יצירת משימה של למידת מכונה מאוחדת

בדף הזה נסביר איך לעבוד עם ממשקי API של למידה משותפת שמסופקים על ידי התאמה אישית במכשיר כדי לאמן מודל באמצעות תהליך למידה של חישוב ממוצע מאוחד ורעש גאוסיאני קבוע.

לפני שמתחילים

לפני שמתחילים, צריך לבצע את השלבים הבאים במכשיר הבדיקה:

  1. מוודאים שהמודול OnDevicePersonalization מותקן. המודול הפך לזמין כעדכון אוטומטי באפריל 2024.

    # List the modules installed on the device
    adb shell pm list packages --apex-only --show-versioncode
    

    מוודאים שהמודול הבא מופיע עם קוד גרסה 341717000 ואילך:

    package:com.google.android.ondevicepersonalization versionCode:341717000

    אם המודול הזה לא מופיע ברשימה, עוברים אל הגדרות > אבטחה ופרטיות > עדכונים > עדכון מערכת של Google Play כדי לוודא שהמכשיר עדכני. בוחרים באפשרות עדכון לפי הצורך.

  2. הפעלת כל התכונות החדשות שקשורות ללמידה משותפת.

    # Enable On-Device Personalization apk.
    adb shell device_config put on_device_personalization global_kill_switch false
    # Enable On-Device Personalization APIs.
    adb shell device_config put on_device_personalization enable_ondevicepersonalization_apis true
    # Enable On-Device Personalization overriding.
    adb shell device_config put on_device_personalization enable_personalization_status_override true
    adb shell device_config put on_device_personalization personalization_status_override_value true
    # Enable Federated Compute apk.
    adb shell device_config put on_device_personalization federated_compute_kill_switch false
    

יצירת משימה של למידה משותפת

הטופולוגיה של שרת-לקוח של למידת מכונה מאוחדת עם שמונה שלבים מודגשים.
תרשים של הטופולוגיה של שרת הלקוח-למידה מאוחדת עם שמונה שלבים מודגשים.

המספרים בתרשים מוסברים בפירוט בשלבים הבאים.

הגדרת שרת מחשוב מאוחד

למידה משותפת (Federated) היא צמצום המפה שפועלת ב-Federated Compute Server (המפחית) ובקבוצת לקוחות (הממופים). השרת של Federated Compute שומר על המטא-נתונים ועל פרטי המודל של כל משימה של למידה משותפת. ברמה גבוהה:

  • מפתח של למידה משותפת יוצר משימה חדשה ומעלה לשרת גם את המטא-נתונים של הפעלת המשימה וגם את פרטי המודל.
  • כשלקוח Federated Compute יוצר בקשה חדשה להקצאת משימה לשרת, השרת בודק את הכשירות של המשימה ומחזיר את פרטי המשימה שעומדת בדרישות.
  • אחרי שלקוח Federated Compute מסיים את החישובים המקומיים, הוא שולח את תוצאות החישובים האלה לשרת. לאחר מכן השרת מבצע צבירה ורעש על תוצאות החישוב האלה, ומחיל את התוצאה על המודל הסופי.

מידע נוסף על המושגים האלה זמין במאמרים הבאים:

ב-ODP נעשה שימוש בגרסה משופרת של למידה משותפת, שבה רעש מכויל (מרכזי) מוחל על האגרגטיבים לפני ההחלה של המודל. היקף הרעש מבטיח שהצטברות שומרת על הפרטיות הדיפרנציאלית.

שלב 1. יצירת שרת מחשוב מאוחד

פועלים לפי ההוראות בפרויקט של Federated Compute כדי להגדיר שרת Federated Compute משלכם.

שלב 2. הכנת מודל פונקציונלי שמור

מכינים קובץ FunctionalModel שמור. אפשר להשתמש ב-'functional_model_from_keras' כדי להמיר 'Model' ל-'FunctionalModel', ולהשתמש ב-'save_functional_model' כדי לסדר את 'FunctionalModel' הזה כ-'SavedModel'.

functional_model = tff.learning.models.functional_model_from_keras(keras_model=model)
tff.learning.models.save_functional_model(functional_model, saved_model_path)

שלב 3. יצירת הגדרה אישית של שרת מחשוב מאוחד (Federated Compute Server)

צריך להכין fcp_server_config.json שכולל מדיניות, הגדרת למידה משותפת והגדרה של פרטיות דיפרנציאלית. דוגמה:

  # Identifies the set of client devices that will participate.
  population_name: "my_new_population"
  # Options you can choose:
  # * TRAINING_ONLY: Only one training task will be generated under this
  #                  population.
  # * TRAINING_AND_EVAL: One training task and one evaluation task will be
  #                      generated under this population.
  # * EVAL_ONLY: Only one evaluation task will be generated under this
  #              population.
  mode: TRAINING_AND_EVAL
  policies {
    # Policy for sampling on-device examples. It is checked every time a
    # device attempts to start a new training.
    min_separation_policy {
      # The minimum number of rounds before the same client participated.
      minimum_separation: 3
    }
    # Policy for releasing training results to developers. It is checked
    # when uploading a new task to the Federated Compute Server.
    model_release_policy {
      # Server stops training when number of training rounds reaches this
      # number.
      num_max_training_rounds: 1000
    }
  }
  # Federated learning setups. They are applied inside Task Builder.
  federated_learning {
    learning_process {
      # Use FED_AVG to build federated learning process. Options you can
      # choose:
      # * FED_AVG: Federated Averaging algorithm
      #            (https://arxiv.org/abs/2003.00295)
      # * FED_SDG: Federated SGD algorithm
      #            (https://arxiv.org/abs/1602.05629)
      type: FED_AVG
      # Optimizer used at client side training. Options you can choose:
      # * ADAM
      # * SGD
      client_optimizer: SGD
      # Learning rate used at client side training.
      client_learning_rate: 0.01
      # Optimizer used at server side training. Options you can choose:
      # * ADAM
      # * SGD
      server_optimizer: ADAM
      # Learning rate used at server side training.
      sever_learning_rate: 1
      runtime_config {
        # Number of participating devices for each round of training.
        report_goal: 2000
      }
      # List of metrics to be evaluated by the model during training and
      # evaluation. Federated Compute Server provides a list of allowed
      # metrics.
      metrics {
        name: "auc-roc"
      }
      metrics {
        name: "binary_accuracy"
      }
    }
    # Whether or not to generate a corresponding evaluation task under the same
    # population. If this field isn't set, only one training task is
    # generated under this population.
    evaluation {
      # The task id under the same population of the source training task that
      # this evaluation task evaluates.
      source_training_task_id: 1
      # Decides how checkpoints from the training task are chosen for
      # evaluation.
      # * every_k_round: the evaluation task randomly picks one checkpoint
      #                  from the past k rounds of training task checkpoints.
      # * every_k_hour: the evaluation task randomly picks one checkpoint
      #                 from the past k hours of training task checkpoints.
      checkpoint_selector: "every_1_round"
      # The traffic of this evaluation task in this population.
      evaluation_traffic: 0.1
      # Number of participating devices for each round of evaluation.
      report_goal: 200
    }
  }
  # Differential Privacy setups. They are applied inside the Task Builder.
  differential_privacy {
    # The DP aggregation algorithm you want to use. Options you can choose:
    # * FIXED_GAUSSIAN: Federated Learning DP-SGD with fixed clipping norm
    #                   described in "Learning Differentially Private Recurrent
    #                   Language Models" (https://arxiv.org/abs/1710.06963).
    # * ADAPTIVE_GAUSSIAN: Federated Learning DP-SGD with quantile-based clip
    #                      norm estimation described in "Differentially Private
    #                      Learning with Adaptive Clipping"
    #                      (https://arxiv.org/abs/1905.03871).
    # * TREE: DP-FTRL algorithm described in "Practical and Private (Deep)
    #         Learning without Sampling or Shuffling"
    #         (https://arxiv.org/abs/2103.00039).
    # * ADADPTIVE_TREE: DP-FTRL with adaptive clipping norm descirbed in
    #                  "Differentially Private Learning with Adaptive Clipping"
    #                  (https://arxiv.org/abs/1905.03871).
    type: FIXED_GAUSSIAN
    # Noise multiplier for the Gaussian noise.
    noise_multiplier: 0.1
    #   The value of the clipping norm.
    clip_norm: 0.1
  }

שלב 4. שולחים את קובץ ה-zip של ההגדרות לשרת Federated Compute.

שולחים את קובץ ה-ZIP ו-fcp_server_config.json לשרת המחושב המאוחד.

task_builder_client --task_builder_server='http://{federated_compute_server_endpoint}' --saved_model='saved_model' --task_config='fcp_server_config.json'

נקודת הקצה של שרת המחשוב המאוחד היא השרת שהגדרתם בשלב 1.

ספריית האופרטורים המובנית של LiteRT תומכת רק במספר מוגבל של אופרטורים של TensorFlow (Select TensorFlow operators). קבוצת האופרטורים הנתמכת עשויה להשתנות בגרסאות שונות של המודול OnDevicePersonalization. כדי להבטיח תאימות, תהליך אימות האופרטור מתבצע בתוך הכלי ליצירת משימות במהלך יצירת המשימה.

  • הגרסה המינימלית הנתמכת של מודול OnDevicePersonalization תיכלל במטא-נתונים של המשימה. המידע הזה יופיע בהודעת המידע של הכלי ליצירת משימות.

    I1023 22:16:53.058027 139653371516736 task_builder_client.py:109] Success! Tasks are built, and artifacts are uploaded to the cloud.
    I1023 22:16:53.058399 139653371516736 task_builder_client.py:112] applied_algorithms {
      learning_algo: FED_AVG
      client_optimizer: SGD
      server_optimizer: SGD
      dp_aggregator: FIXED_GAUSSIAN
    }
    metric_results {
      accepted_metrics: "binary_accuracy, binary_crossentropy, recall, precision, auc-roc, auc-pr"
    }
    dp_hyperparameters {
      dp_delta: 0.000001
      dp_epsilon: 6.4
      noise_multiplier: 1.0
      dp_clip_norm: 1.0
      num_training_rounds: 10000
    }
    
    I1023 22:16:53.058594 139653371516736 task_builder_client.py:113] training_task {
      min_client_version: "341912000"
    }
    eval_task {
      min_client_version: "341812000"
    }
    

    שרת המחשוב המאוחד יקצה את המשימה הזו לכל המכשירים עם מודול OnDevicePersonalization בגרסה 341812000 ואילך.

  • אם המודל כולל פעולות שלא נתמכות במודולים של OnDevicePersonalization, תיווצר הודעת שגיאה במהלך יצירת המשימה.

    common.TaskBuilderException: Cannot build the ClientOnlyPlan: Please contact Google to register these ops: {'L2Loss': 'L2LossOp<CPUDevice, float>'}
    . Stop building remaining artifacts.
    
  • אתם יכולים למצוא רשימה מפורטת של אפשרויות גמישות נתמכות ב-GitHub.

יצירת חבילת APK של Android Federated Compute

כדי ליצור קובץ APK של Android Federated Compute, צריך לציין את נקודת הקצה (endpoint) של כתובת ה-URL של שרת Federated Compute ב-AndroidManifest.xml, שאליה מתחבר לקוח Federated Compute.

שלב 5. ציון נקודת הקצה של כתובת ה-URL של שרת המחשוב המאוחד

מציינים את נקודת הקצה של כתובת ה-URL של שרת המחשוב המאוחד (שהגדרתם בשלב 1) ב-AndroidManifest.xml, שאליה מתחבר לקוח המחשוב המאוחד.

<!-- Contents of AndroidManifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.odpsample" >
    <application android:label="OdpSample">
        <!-- XML resource that contains other ODP settings. -->
        <property android:name="android.ondevicepersonalization.ON_DEVICE_PERSONALIZATION_CONFIG"
                  android:resource="@xml/OdpSettings"></property>
        <!-- The service that ODP will bind to. -->
        <service android:name="com.example.odpsample.SampleService"
                android:exported="true" android:isolatedProcess="true" />
    </application>
</manifest>

קובץ המשאב של ה-XML שצוין בתג <property> צריך גם להצהיר על סיווג השירות בתג <service>, ולציין את נקודת הקצה של כתובת ה-URL של שרת המחשוב המאוחד שאליה יתחבר לקוח המחשוב המאוחד:

<!-- Contents of res/xml/OdpSettings.xml -->
<on-device-personalization>
   <!-- Name of the service subclass -->
   <service name="com.example.odpsample.SampleService">
     <!-- If you want to use federated compute feature to train a model,
          specify this tag. -->
     <federated-compute-settings url="https://fcpserver.com/" />
   </service>
</on-device-personalization>

שלב 6. הטמעה של IsolatedWorker#onTrainingExample API

מטמיעים את ה-API הציבורי של התאמה אישית במכשיר IsolatedWorker#onTrainingExample כדי ליצור נתוני אימון.

לקוד שפועל ב-IsolatedProcess אין גישה ישירה לרשת, לדיסקים המקומיים או לשירותים אחרים שפועלים במכשיר. עם זאת, ממשקי ה-API הבאים זמינים:

  • 'getRemoteData' – נתוני מפתח/ערך שלא ניתן לשנות, שהורדתם מקצוות עורפיים מרוחקים שמנוהלים על ידי מפתחים, אם רלוונטי.
  • 'getLocalData' – נתוני מפתח/ערך שניתנים לשינוי ושהמפתחים שומרים באופן מקומי, אם רלוונטי.
  • 'UserData' – נתוני משתמשים שסופקו על ידי הפלטפורמה.
  • 'getLogReader' – מחזירה DAO בטבלאות Preference ו-Events.

דוגמה:

@Override public void onTrainingExample(
            @NonNull TrainingExampleInput input,
            @NonNull Consumer<TrainingExampleOutput> consumer) {
    // Check if the incoming training task is the task we want.
    if (input.getPopulationName() == "my_new_population") {
        TrainingExampleOutput result = new TrainingExampleOutput.Builder():
        RequestLogRecord record = this.getLogReader().getRequestLogRecord(1);
        int count = 1;
        // Iterate logging event table.
        for (ContentValues contentValues: record.rows()) {
            Features features = Features.newBuilder()
                // Retrieve carrier from user info.
                .putFeature("carrier", buildFeature(mUserData.getCarrier()))
                // Retrieve features from logging info.
                .putFeature("int_feature_1",
                    buildFeature(contentValues.get("int_feature_1")
            result.addTrainingExample(
                    Example.newBuilder()
                        .setFeatures(features).build().toByteArray())
                .addResumptionToken(
                    String.format("token%d", count).getBytes()))
                .build();
            count++;
        }
        consumer.accept(result.build());
    }
}

שלב 7. קביעת משימה חוזרת של אימון.

התכונה 'התאמה אישית במכשיר' מספקת FederatedComputeScheduler למפתחים שאפשר לתזמן או לבטל משימות מחשוב מאוחדות. יש אפשרויות שונות להפעיל אותו דרך IsolatedWorker, לפי תזמון או בסיום הורדה אסינכררונית. בהמשך מופיעות דוגמאות לשני המקרים.

  • אפשרות מבוססת-תזמון. התקשרות אל FederatedComputeScheduler#schedule בIsolatedWorker#onExecute.

    @Override public void onExecute(
                @NonNull ExecuteInput input,
                @NonNull Consumer<ExecuteOutput> consumer
        ) {
        if (input != null && input.getAppParams() != null
            && input.getAppParams().getString("schedule_training") != null) {
            if (input.getAppParams().getString("schedule_training").isEmpty()) {
                consumer.accept(null);
                return;
            }
            TrainingInterval interval = new TrainingInterval.Builder()
                .setMinimumInterval(Duration.ofSeconds(10))
                .setSchedulingMode(2)
                .build();
            FederatedComputeScheduler.Params params = new FederatedComputeScheduler
                .Params(interval);
            FederatedComputeInput fcInput = new FederatedComputeInput.Builder()
                .setPopulationName(
                    input.getAppParams().getString("schedule_training")).build();
            mFCScheduler.schedule(params, fcInput);
    
            ExecuteOutput result = new ExecuteOutput.Builder().build();
            consumer.accept(result);
        }
    }
    
  • הורדת האפשרות המלאה. קוראים לפונקציה FederatedComputeScheduler#schedule ב-IsolatedWorker#onDownloadCompleted אם התזמון של משימת אימון תלוי בנתונים או בתהליכים אסינכרוניים.

אימות

בשלבים הבאים מוסבר איך לוודא שמשימה של למידה משותפת פועלת כמו שצריך.

שלב 8. מוודאים שהמשימה של הלמידה המשותפת פועלת כמו שצריך.

בכל סיבוב של צבירת נתונים בצד השרת נוצרים צ'קפוינט חדש של מודל וקובץ מדדים חדש.

המדדים נמצאים בקובץ בפורמט JSON של צמדי מפתח-ערך. הקובץ נוצר על ידי הרשימה של Metrics שהגדרתם בשלב 3. דוגמה לקובץ JSON מייצג של מדדים:

{"server/client_work/train/binary_accuracy":0.5384615659713745, "server/client_work/train/binary_crossentropy":0.694046676158905, "server/client_work/train/recall":0.20000000298023224, "server/client_work/train/precision":0.3333333432674408, "server/client_work/train/auc-roc":0.3500000238418579, "server/client_work/train/auc-pr":0.44386863708496094, "server/finalizer/update_non_finite":0.0}

תוכלו להשתמש בסקריפט שדומה לסקריפט הבא כדי לקבל מדדי מודל ולעקוב אחר ביצועי האימון:

import collections
import json
import matplotlib.pyplot as plt
from google.cloud import storage

# The population_name you set in fcp_server_config.json in Step 3.
POPULATION_NAME = 'my_new_population'
# The Google Cloud storage you set in Step 1.
GCS_BUCKET_NAME = 'fcp-gcs'
NUM_TRAINING_ROUND = 1000

storage_client = storage.Client()
bucket = storage_client.bucket(GCS_BUCKET_NAME)

metrics = collections.defaultdict(list)
for i in range(NUM_TRAINING_ROUND):
    blob = bucket.blob('{}/{}/1/{}/s/0/metrics'.format(GCS_BUCKET_NAME, POPULATION_NAME, i+1))
    with blob.open("r") as f:
                     metric = json.loads(f.read())
                    for metric_name in metric.keys():
                             metrics[metric_name].append(metric[metric_name])

for metric_name in metrics:
         print(metric_name)
         plt.plot(metrics[metric_name])
         plt.show()
תרשים לדוגמה של המדד auc-roc כשהוא מוצג בתרשים.

שימו לב שבתרשים לדוגמה שלמעלה:

  • ציר ה-X הוא מספר האימון העגול.
  • ציר ה-y הוא הערך של auc-roc בכל סיבוב.

אימון של מודל לסיווג תמונות בהתאמה אישית במכשיר

במדריך הזה נשתמש במערך הנתונים EMNIST כדי להדגים איך להריץ משימת למידה משותפת ב-ODP.

שלב 1. יוצרים tff.learning.models.FunctionalModel

def get_image_classification_input_spec():
  return (
      tf.TensorSpec([None, 28, 28, 1], tf.float32),
      tf.TensorSpec([None, 1], tf.int64),
  )

def create_and_save_image_classification_functional_model(
    model_path: str,
) -> None:
  keras_model =  emnist_models.create_original_fedavg_cnn_model(
      only_digits=True
  )
  functional_model = tff.learning.models.functional_model_from_keras(
      keras_model=keras_model,
      input_spec=get_image_classification_input_spec(),
      loss_fn=tf.keras.losses.SparseCategoricalCrossentropy(),
  )
  tff.learning.models.save_functional_model(functional_model, model_path)
  • פרטי מודל emnist keras מופיעים בקובץ emnist_models.
  • עדיין אין ב-TfLite תמיכה טובה ב-tf.sparse.SparseTensor או ב-tf.RaggedTensor. כשאתם יוצרים את המודל, נסו להשתמש ב-tf.Tensor כמה שיותר.
  • הכלי ליצירת משימות ODP יחליף את כל המדדים במהלך פיתוח תהליך הלמידה, אין צורך לציין מדדים. נתעמק בנושא הזה בשלב 2. יוצרים את ההגדרות של ה-task builder.
  • יש תמיכה בשני סוגים של קלט למודלים:

    • סוג 1. Tuple(features_tensor, label_tensor).

      • כשיוצרים את המודל, ה-input_spec נראה כך:
      def get_input_spec():
        return (
            tf.TensorSpec([None, 28, 28, 1], tf.float32),
            tf.TensorSpec([None, 1], tf.int64),
        )
      
      • משלבים את הקוד הקודם עם ההטמעה הבאה של ממשק ה-API הציבורי של ODP‏ IsolatedWorker#onTrainingExamples כדי ליצור נתוני אימון במכשיר:
      return tf.train.Example(
          features=tf.train.Features(
              feature={
                  'x': tf.train.Feature(
                      float_list=tf.train.FloatList(value=[1.0] * 784)
                  ),
                  'y': tf.train.Feature(
                      int64_list=tf.train.Int64List(
                          value=[1]
                      )
                  ),
              }
          )
      ).SerializeToString()
      
    • סוג 2. Tuple(Dict[feature_name, feature_tensor], label_tensor)

      • כשיוצרים את המודל, ה-input_spec נראה כך:
      def get_input_spec() -> (
          Tuple[collections.OrderedDict[str, tf.TensorSpec], tf.TensorSpec]
      ):
        return (
            collections.OrderedDict(
                [('feature-1', tf.TensorSpec([None, 1], tf.float32)),
                ('feature-2', tf.TensorSpec([None, 1], tf.float32))]
            ),
            tf.TensorSpec([None, 1], tf.int64),
        )
      
      • כדי ליצור נתוני אימון, משלבים את הקוד הקודם עם ההטמעה הבאה של ממשק ה-API הציבורי של ODP‏ IsolatedWorker#onTrainingExamples:
      return tf.train.Example(
          features=tf.train.Features(
              feature={
                  'feature-1': tf.train.Feature(
                      float_list=tf.train.FloatList(value=[1.0])
                  ),
                  'feature-2': tf.train.Feature(
                      float_list=tf.train.FloatList(value=[2.0])
                  ),
                  'my_label': tf.train.Feature(
                      int64_list=tf.train.Int64List(
                          value=[1]
                      )
                  ),
              }
          )
      ).SerializeToString()
      
      • חשוב לא לשכוח לרשום את label_name בהגדרות של ה-task builder.
      mode: TRAINING_AND_EVAL  # Task execution mode
      population_name: "my_example_model"
      label_name: "my_label"
      
  • במהלך הפיתוח של תהליך הלמידה, ODP מטפל ב-DP באופן אוטומטי. לכן אין צורך להוסיף רעש כשיוצרים את המודל הפונקציונלי.

  • הפלט של המודל הפונקציונלי השמור הזה אמור להיראות כמו הדוגמה במאגר שלנו ב-GitHub.

שלב 2. יצירת התצורה של ה-task builder

דוגמאות להגדרות של ה-Task Builder זמינות במאגר שלנו ב-GitHub.

  • מדדי אימון והערכה

    מאחר שמדדים עלולים לגרום לדליפת נתוני משתמשים, ב-Task Builder תהיה רשימה של מדדים שתהליך הלמידה יכול ליצור ולשחרר. הרשימה המלאה מופיעה במאגר שלנו ב-GitHub.

    לפניכם רשימת מדדים לדוגמה כשיוצרים הגדרה חדשה של הכלי ליצירת משימות:

    federated_learning {
      learning_process {
        metrics {
          name: "binary_accuracy"
        }
        metrics {
          name: "binary_crossentropy"
        }
        metrics {
          name: "recall"
        }
        metrics {
          name: "precision"
        }
        metrics {
          name: "auc-roc"
        }
        metrics {
          name: "auc-pr"
        }
      }
    }
    

אם המדדים שמעניינים אתכם לא מופיעים ברשימה הנוכחית, אתם יכולים ליצור איתנו קשר.

  • הגדרות DP

    יש כמה הגדרות שקשורות ל-DP שצריך לציין:

    policies {
      min_separation_policy {
        minimum_separation: 1
      }
      model_release_policy {
        num_max_training_rounds: 1000
        dp_target_epsilon: 10
        dp_delta: 0.000001
      }
    }
    differential_privacy {
      type: FIXED_GAUSSIAN
      clip_norm: 0.1
      noise_multiplier: 0.1
    }
    

שלב 3. העלאת התצורה של ה-Task Builder והמודל השמור לאחסון בענן של כל מפתח

חשוב לעדכן את השדות artifact_building כשמעלים את ההגדרות של הכלי ליצירת משימות.

שלב 4. (אופציונלי) בדיקת פיתוח ארטיפקטים בלי ליצור משימה חדשה

cd ${odp_fcp_github_repo}/python
bazel run //python/taskbuilder:task_builder_client -- --saved_model=${path_of_cloud_storage}/mnist_model/ --task_config=${path_of_cloud_storage}/mnist_cnn_task_config_build_artifact_only.pbtxt --build_artifact_only=true --task_builder_server=${task_builder_server_endpoint}

המודל לדוגמה מאומת גם באמצעות בדיקת הפעולות הגמישה וגם באמצעות בדיקת ה-dp. אפשר להוסיף את skip_flex_ops_check ואת skip_dp_check כדי לעקוף את המודל במהלך האימות (אי אפשר לפרוס את המודל הזה לגרסה הנוכחית של לקוח ODP כי חסרות כמה פעולות גמישות).

cd ${odp_fcp_github_repo}/python
bazel run //python/taskbuilder:task_builder_client -- --saved_model=${path_of_cloud_storage}/mnist_model/ --task_config=${path_of_cloud_storage}/mnist_cnn_task_config_build_artifact_only.pbtxt --build_artifact_only=true --task_builder_server=${task_builder_server_endpoint} --skip_flex_ops_check=True --skip_dp_check=True
  • flex_ops_check: ספריית האופרטורים המובנית של TensorFlow Lite תומכת רק במספר מוגבל של אופרטורים של TensorFlow (תאימות של TensorFlow Lite לאופרטורים של TensorFlow). צריך להתקין את כל הפעולות הלא תואמות של tensorflow באמצעות נציג עם הרשאה גמישה (Android.bp). אם מודל מכיל פעולות שלא נתמכות, אפשר ליצור איתנו קשר כדי לרשום אותן:

    Cannot build the ClientOnlyPlan: Please contact Google to register these ops: {...}
    
  • הדרך הטובה ביותר לנפות באגים ב-Task Builder היא להפעיל אותו באופן מקומי:

    # Starts a server at localhost:5000
    bazel run //python/taskbuilder:task_builder
    # Links to a server at localhost:5000 by removing task_builder_server flag
    bazel run //python/taskbuilder:task_builder_client -- --saved_model=${path_of_cloud_storage}/mnist_model/ --task_config=${path_of_cloud_storage}/mnist_cnn_task_config_build_artifact_only.pbtxt --build_artifact_only=true --skip_flex_ops_check=True --skip_dp_check=True
    

אפשר למצוא את הארטיפקטים שנוצרו באחסון בענן שצוין בהגדרה. הוא אמור להיראות כמו הדוגמה במאגר שלנו ב-GitHub.

שלב 5. בונים ארטיפקטים ויוצרים זוג חדש של משימות אימון והערכה בשרת ה-FCP.

מסירים את הדגל build_artifact_only והארטיפקטים שנוצרו יועלמו לשרת FCP. צריך לבדוק אם צמד משימות של אימון והערכה נוצרו בהצלחה

cd ${odp_fcp_github_repo}/python
bazel run //python/taskbuilder:task_builder_client -- --saved_model=${path_of_cloud_storage}/mnist_model/ --task_config=${path_of_cloud_storage}/mnist_cnn_task_config.pbtxt --task_builder_server=${task_builder_server_endpoint}

שלב 6. הכנת הצד הלקוח ל-FCP

שלב 7. מעקב

תרשים של מטלות לדקה.
תרשים של זמן העיבוד של המחזור.
תרשים של איטרציות לאורך זמן.
  • מדדי מודל
תרשים שבו מוצגת השוואה בין מדדים מהפעלות שונות.

ניתן להשוות מדדים מהפעלות שונות בתרשים אחד. לדוגמה:

  • הקו הסגול מופיע עם הערך noise_multiplier 0.1
  • השורה הוורודה היא עם noise_multipiler 0.3