1. סקירה כללית
בשיעור ה-Lab הזה תלמדו להשתמש ב-Vertex AI כדי להריץ משימה אימון עם עובדים מרובים למודל TensorFlow.
מה תלמדו
תלמדו איך:
- שינוי קוד האפליקציה של האימון לאימון של כמה עובדים
- הגדרה והפעלה של משימת אימון עם עובדים מרובים דרך ממשק המשתמש של Vertex AI
- הגדרה והשקה של משימת אימון מרובה עובדים באמצעות Vertex SDK
העלות הכוללת של הפעלת שיעור ה-Lab הזה ב-Google Cloud היא כ-5$.
2. מבוא ל-Vertex AI
במעבדה הזו נעשה שימוש במוצרי ה-AI החדשים ביותר שזמינים ב-Google Cloud. Vertex AI משלבת את חבילות ה-ML ב-Google Cloud לחוויית פיתוח חלקה. בעבר, ניתן היה לגשת למודלים שעברו אימון באמצעות AutoML ומודלים בהתאמה אישית דרך שירותים נפרדים. המוצר החדש משלב את שניהם ב-API אחד, יחד עם מוצרים חדשים אחרים. אפשר גם להעביר פרויקטים קיימים ל-Vertex AI. יש לך משוב? אפשר להיכנס לדף התמיכה.
Vertex AI כולל הרבה מוצרים שונים לתמיכה בתהליכי עבודה של למידת מכונה מקצה לקצה. בשיעור ה-Lab הזה נתמקד במוצרים הבאים: Training ו-Workbench
3. סקירה כללית של תרחיש לדוגמה
בשיעור ה-Lab הזה נעזרים בלמידת העברה כדי לאמן מודל לסיווג תמונות על סמך מערך הנתונים של קסאווה מ-TensorFlow Datasets. הארכיטקטורה שבה תשתמשו היא מודל ResNet50 מהספרייה tf.keras.applications
, שעבר אימון מראש על מערך הנתונים Imagenet.
למה כדאי להשתמש באימון מבוזבז?
אם יש לכם GPU אחד, TensorFlow ישתמש במאיץ הזה כדי לזרז את אימון המודל בלי שתצטרכו לעשות שום דבר נוסף. עם זאת, אם אתם רוצים לקבל הגדלה של מספר מעבדי GPU במחשב אחד או בכמה מכונות (בכל אחת מהן יש כמה מעבדי GPU), תצטרכו להשתמש ב-tf.distribute
, שהיא הספרייה של TensorFlow להרצת חישוב בכמה מכשירים. מכשיר מתייחס למעבד (CPU) או למאיץ, כמו מעבדי GPU או מעבדי TPU, במכונות מסוימות ש-TensorFlow יכול להריץ בהן פעולות.
הדרך הפשוטה ביותר להתחיל באימון מבוזר היא מכונה אחת עם כמה מכשירי GPU. אסטרטגיית הפצה של TensorFlow מהמודול tf.distribute
תנהל את התיאום של הפצת נתונים ועדכונים הדרגתיים בין כל מעבדי ה-GPU. אם כבר רכשתם מיומנות בהדרכה במארח יחיד ואתם רוצים להרחיב את היקף העבודה עוד יותר, הוספת מכונות מרובות לאשכול יכולה לעזור לכם לשפר את הביצועים עוד יותר. אתם יכולים להשתמש באשכול של מכונות שהן מעבד (CPU) בלבד, או שלכל אחת מהן יש יחידת GPU אחת או יותר. בשיעור ה-Lab הזה תלמדו איך להשתמש ב-MultiWorkerMirroredStrategy
כדי להפיץ אימון של מודל TensorFlow במספר מכונות ב-Vertex AI.
MultiWorkerMirroredStrategy
היא אסטרטגיה של סינכרון מקבילי של נתונים, שאפשר להשתמש בה עם כמה שינויים קטנים בקוד. עותק של המודל נוצר בכל מכשיר באשכול. עדכוני ההדרגתיות הבאים יתבצעו באופן סינכרוני. כלומר, כל מכשיר עבודה מחשב את החזרות הקדימה והלאחור דרך המודל בחלק שונה של נתוני הקלט. לאחר מכן, הנגזרות המחושבות מכל אחד מהפלחים האלה נצברות בכל המכשירים במכונה ובכל המכונות באשכול, ומצטמצמות (בדרך כלל ממוצעות) בתהליך שנקרא all-reduce. לאחר מכן כלי האופטימיזציה מעדכן את הפרמטר עם ההדרגתיות המופחתת האלה, ובכך שומר על סנכרון המכשירים. למידע נוסף על אימון מבוזר באמצעות TensorFlow, כדאי לצפות בסרטון הבא:
4. הגדרת הסביבה
כדי להריץ את ה-Codelab הזה צריך פרויקט ב-Google Cloud Platform שהחיוב מופעל בו. כדי ליצור פרויקט, יש לפעול לפי ההוראות האלה.
שלב 1: מפעילים את Compute Engine API
עוברים אל Compute Engine ובוחרים באפשרות Enable (הפעלה) אם היא עדיין לא מופעלת. תצטרכו את זה כדי ליצור את מכונה של המחברות.
שלב 2: מפעילים את Container Registry API
עוברים אל Container Registry ובוחרים באפשרות Enable (הפעלה) אם היא עדיין לא מסומנת. תשתמשו בו כדי ליצור קונטיינר למשימת האימון בהתאמה אישית.
שלב 3: מפעילים את Vertex AI API
עוברים אל הקטע Vertex AI במסוף Cloud ולוחצים על Enable Vertex AI API.
שלב 4: יצירת מכונה של Vertex AI Workbench
בקטע Vertex AI במסוף Cloud, לוחצים על Workbench:
מפעילים את Notebooks API, אם הוא לא פועל.
לאחר ההפעלה, לוחצים על פנקסי רשימות מנוהלים:
לאחר מכן בוחרים באפשרות מחברות חדשה.
נותנים שם למחברת ולוחצים על הגדרות מתקדמות.
בקטע 'הגדרות מתקדמות', מפעילים את ההגדרה 'כיבוי במצב חוסר פעילות' ומגדירים את מספר הדקות ל-60. המשמעות היא שהמחשב הנייד יכבה באופן אוטומטי כשלא משתמשים בו, כדי שלא תחויבו בעלויות מיותרות.
בקטע אבטחה, בוחרים באפשרות 'הפעלת מסוף' אם היא עדיין לא מופעלת.
אפשר להשאיר את כל שאר ההגדרות המתקדמות כפי שהן.
לאחר מכן, לוחצים על יצירה. תהליך ההקצאה של המכונה יימשך כמה דקות.
אחרי יצירת המכונה, בוחרים באפשרות Open JupyterLab.
בפעם הראשונה שתשתמשו במכונה חדשה, תתבקשו לבצע אימות. כדי לעשות זאת, פועלים לפי השלבים בממשק המשתמש.
5. אריזה בקונטיינר של קוד אפליקציית האימון
כדי לשלוח את משימת האימון הזו ל-Vertex, תצטרכו להעביר את קוד האפליקציה של האימון לקונטיינר Docker ולדחוף את הקונטיינר הזה ל-Google Container Registry. כך תוכלו לאמן מודל שנוצר באמצעות כל מסגרת.
כדי להתחיל, פותחים חלון Terminal במכונה של המחברת בתפריט Launcher:
יוצרים ספרייה חדשה בשם cassava
ומוסיפים אליה cd:
mkdir cassava
cd cassava
שלב 1: יוצרים קובץ Docker
השלב הראשון ביצירת קונטיינרים לקוד הוא יצירת קובץ Docker. בקובץ Dockerfile תכללו את כל הפקודות הנדרשות להרצת קובץ האימג'. הספריות הנדרשות יותקנו ותתבצע הגדרה של נקודת הכניסה לקוד האימון.
יוצרים קובץ Dockerfile ריק ב-Terminal:
touch Dockerfile
פותחים את Dockerfile ומעתיקים אליו את הטקסט הבא:
FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-7
WORKDIR /
# Copies the trainer code to the docker image.
COPY trainer /trainer
# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.task"]
קובץ ה-Dockerfile הזה משתמש בקובץ אימג' של Docker ב-Deep Learning Container TensorFlow Enterprise 2.7 GPU. הקונטיינרים של Deep Learning ב-Google Cloud מגיעים עם הרבה frameworks נפוצים של מדעי נתונים ולמידת מכונה שהותקנו מראש. אחרי הורדת התמונה, קובץ ה-Dockerfile הזה מגדיר את נקודת הכניסה לקוד האימון. עדיין לא יצרתם את הקבצים האלה – בשלב הבא תוסיפו את הקוד לאימון ולכוונון המודל.
שלב 2: יצירת קטגוריה של Cloud Storage
במשימת האימון הזו תייצאו את מודל TensorFlow המאומן לקטגוריה של Cloud Storage. ב-Terminal, מריצים את הפקודה הבאה כדי להגדיר משתנה סביבה לפרויקט. חשוב להחליף את your-cloud-project
במזהה הפרויקט:
PROJECT_ID='your-cloud-project'
לאחר מכן, מריצים את הפקודה הבאה ב-Terminal כדי ליצור קטגוריה חדשה בפרויקט.
BUCKET="gs://${PROJECT_ID}-bucket"
gsutil mb -l us-central1 $BUCKET
שלב 3: מוסיפים קוד לאימון המודלים
בטרמינל, מריצים את הפקודה הבאה כדי ליצור ספרייה לקוד האימון וקובץ Python שאליו מוסיפים את הקוד:
mkdir trainer
touch trainer/task.py
עכשיו אמורים להופיע בספרייה cassava/
:
+ Dockerfile
+ trainer/
+ task.py
אחר כך פותחים את הקובץ task.py
שיצרתם ומעתיקים את הקוד שבהמשך. צריך להחליף את {your-gcs-bucket}
בשם של הקטגוריה ב-Cloud Storage שיצרתם.
import tensorflow as tf
import tensorflow_datasets as tfds
import os
PER_REPLICA_BATCH_SIZE = 64
EPOCHS = 2
# TODO: replace {your-gcs-bucket} with the name of the Storage bucket you created earlier
BUCKET = 'gs://{your-gcs-bucket}/mwms'
def preprocess_data(image, label):
'''Resizes and scales images.'''
image = tf.image.resize(image, (300,300))
return tf.cast(image, tf.float32) / 255., label
def create_dataset(batch_size):
'''Loads Cassava dataset and preprocesses data.'''
data, info = tfds.load(name='cassava', as_supervised=True, with_info=True)
number_of_classes = info.features['label'].num_classes
train_data = data['train'].map(preprocess_data,
num_parallel_calls=tf.data.experimental.AUTOTUNE)
train_data = train_data.shuffle(1000)
train_data = train_data.batch(batch_size)
train_data = train_data.prefetch(tf.data.experimental.AUTOTUNE)
# Set AutoShardPolicy
options = tf.data.Options()
options.experimental_distribute.auto_shard_policy = tf.data.experimental.AutoShardPolicy.DATA
train_data = train_data.with_options(options)
return train_data, number_of_classes
def create_model(number_of_classes):
'''Creates and compiles pretrained ResNet50 model.'''
base_model = tf.keras.applications.ResNet50(weights='imagenet', include_top=False)
x = base_model.output
x = tf.keras.layers.GlobalAveragePooling2D()(x)
x = tf.keras.layers.Dense(1016, activation='relu')(x)
predictions = tf.keras.layers.Dense(number_of_classes, activation='softmax')(x)
model = tf.keras.Model(inputs=base_model.input, outputs=predictions)
model.compile(
loss='sparse_categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(0.0001),
metrics=['accuracy'])
return model
def _is_chief(task_type, task_id):
'''Helper function. Determines if machine is chief.'''
return task_type == 'chief'
def _get_temp_dir(dirpath, task_id):
'''Helper function. Gets temporary directory for saving model.'''
base_dirpath = 'workertemp_' + str(task_id)
temp_dir = os.path.join(dirpath, base_dirpath)
tf.io.gfile.makedirs(temp_dir)
return temp_dir
def write_filepath(filepath, task_type, task_id):
'''Helper function. Gets filepath to save model.'''
dirpath = os.path.dirname(filepath)
base = os.path.basename(filepath)
if not _is_chief(task_type, task_id):
dirpath = _get_temp_dir(dirpath, task_id)
return os.path.join(dirpath, base)
def main():
# Create strategy
strategy = tf.distribute.MultiWorkerMirroredStrategy()
# Get data
global_batch_size = PER_REPLICA_BATCH_SIZE * strategy.num_replicas_in_sync
train_data, number_of_classes = create_dataset(global_batch_size)
# Wrap variable creation within strategy scope
with strategy.scope():
model = create_model(number_of_classes)
model.fit(train_data, epochs=EPOCHS)
# Determine type and task of the machine from
# the strategy cluster resolver
task_type, task_id = (strategy.cluster_resolver.task_type,
strategy.cluster_resolver.task_id)
# Based on the type and task, write to the desired model path
write_model_path = write_filepath(BUCKET, task_type, task_id)
model.save(write_model_path)
if __name__ == "__main__":
main()
לפני שמפתחים את הקונטיינר, נבחן לעומק את הקוד, שמשתמש ב-MultiWorkerMirroredStrategy
מ-API של tf.distribute.Strategy
.
הקוד כולל מספר רכיבים שנדרשים כדי לעבוד עם MultiWorkerMirroredStrategy
.
- צריך לפצל את הנתונים – כלומר, לכל עובד מוקצית קבוצת משנה של כל מערך הנתונים. לכן, בכל שלב כל עובד יעבד קבוצה גלובלית של רכיבי מערך נתונים שלא חופפים זה לזה. חלוקת המשנה מתבצעת באופן אוטומטי באמצעות
tf.data.experimental.AutoShardPolicy
, שאפשר להגדיר כ-FILE
או כ-DATA
. בדוגמה הזו, הפונקציהcreate_dataset()
מגדירה אתAutoShardPolicy
כ-DATA
כי מערך הנתונים של הקסאווה לא מוריד כמספר קבצים. עם זאת, אם לא תגדירו את המדיניות ל-DATA
, תופעל מדיניות ברירת המחדלAUTO
והתוצאה הסופית תהיה זהה. מידע נוסף על חלוקת מערכי נתונים באמצעותMultiWorkerMirroredStrategy
- בפונקציה
main()
, נוצר האובייקטMultiWorkerMirroredStrategy
. בשלב הבא, צריך לתחום את יצירת משתני המודל בהיקף של האסטרטגיה. השלב הזה חיוני כדי להורות ל-TensorFlow אילו משתנים צריך לשקף בין הרפליקות. - גודל האצווה יגדל לפי הערך של
num_replicas_in_sync
. כך אפשר להבטיח שכל רפליקה תעבד אותו מספר של דוגמאות בכל שלב. שינוי הגודל של האצווה היא שיטה מומלצת כשמשתמשים בשיטות של עיבוד נתונים סינכרוני במקביל ב-TensorFlow. - שמירת המודל מורכבת יותר במקרה של כמה עובדים, כי היעד צריך להיות שונה לכל אחד מהעובדים. העובד הראשי ישמור את המודל בספריית המודל הרצויה, והעובדים האחרים ישמרו את המודל בספריות זמניות. חשוב שהספריות הזמניות האלה יהיו ייחודיות כדי למנוע מכמה עובדים לכתוב באותו מיקום. חיסכון יכול לכלול פעולות קולקטיביות, כלומר כל העובדים צריכים להציל ולא רק את המנהל. הפונקציות
_is_chief()
,_get_temp_dir()
,write_filepath()
והפונקציותmain()
כוללות קוד סטנדרטי שעוזר לשמור את המודל.
שימו לב: אם השתמשתם ב-MultiWorkerMirroredStrategy
בסביבה אחרת, יכול להיות שהגדרתם את משתנה הסביבה TF_CONFIG
. מערכת Vertex AI מגדירה את TF_CONFIG
באופן אוטומטי, כך שאין צורך להגדיר את המשתנה הזה בכל מכונה באשכול.
שלב 4: יצירת הקונטיינר
ב-Terminal, מריצים את הפקודה הבאה כדי להגדיר משתנה סביבה לפרויקט. חשוב להחליף את your-cloud-project
במזהה הפרויקט:
PROJECT_ID='your-cloud-project'
מגדירים משתנה עם ה-URI של קובץ האימג' בקונטיינר ב-Google Container Registry:
IMAGE_URI="gcr.io/$PROJECT_ID/multiworker:cassava"
הגדרת Docker
gcloud auth configure-docker
לאחר מכן, כדי ליצור את הקונטיינר, מריצים את הפקודה הבאה מהשורש של ספריית cassava
:
docker build ./ -t $IMAGE_URI
לבסוף, מעבירים אותו ל-Google Container Registry:
docker push $IMAGE_URI
הקונטיינר הועבר ל-Container Registry. עכשיו אתם מוכנים להתחיל את משימת האימון.
6. הרצת משימת אימון מרובת עובדים ב-Vertex AI
בסדנת העבודה הזו נעשה שימוש באימון בהתאמה אישית באמצעות קונטיינר בהתאמה אישית ב-Google Container Registry, אבל אפשר גם להריץ משימת אימון באמצעות הקונטיינרים שנוצרו מראש.
כדי להתחיל, עוברים לקטע Training בקטע Vertex במסוף Cloud:
שלב 1: הגדרה של משימת האימון
לוחצים על יצירה כדי להזין את הפרמטרים למשימת האימון.
- בקטע מערך נתונים, בוחרים באפשרות ללא מערך נתונים מנוהל.
- לאחר מכן בוחרים באפשרות אימון מותאם אישית (מתקדם) כשיטת האימון ולוחצים על המשך.
- מזינים
multiworker-cassava
(או כל שם אחר שרוצים לתת למודל) בשדה שם המודל. - לוחצים על המשך.
בשלב 'הגדרות מאגר התגים', בוחרים באפשרות מאגר תגים בהתאמה אישית:
בתיבה הראשונה (תמונה של קונטיינר), מזינים את הערך של המשתנה IMAGE_URI
מהקטע הקודם. הערך צריך להיות: gcr.io/your-cloud-project/multiworker:cassava
, עם מזהה הפרויקט שלכם. משאירים את שאר השדות ריקים ולוחצים על המשך.
כדי לדלג על השלב של הפרמטרים הסופר-היפרטרמיים, לוחצים שוב על Continue.
שלב 2: הגדרת אשכול המחשוב
מערכת Vertex AI מספקת 4 מאגרי עובדים כדי לכסות את הסוגים השונים של משימות המכונה.
Worker pool 0 מגדיר את המארח הראשי, המארח הראשי, מתזמן או 'מאסטר'. ב-MultiWorkerMirroredStrategy
, כל המכונות מוגדרות כמכונות עבודה, שהן המכונות הפיזיות שבהן מתבצע החישוב המשוכפל. בנוסף לכך שכל מכונה היא worker, צריך להיות עובד אחד שמבצע עבודה נוספת כמו שמירת נקודות ביקורת וכתיבת קובצי סיכום ב-TensorBoard. המכונה הזו נקראת 'הראשית'. תמיד יש רק עובד ראשי אחד, כך שמספר העובדים במאגר העובדים 0 יהיה תמיד 1.
בקטע Compute andpricing, משאירים את האזור שנבחר כפי שהוא ומגדירים את Worker pool 0 באופן הבא:
במאגר העובדים 1 מגדירים את העובדים של האשכולות.
מגדירים את מאגר העובדים 1 באופן הבא:
האשכול מוגדר עכשיו עם שתי מכונות עם מעבדים בלבד. כשמפעילים את קוד האפליקציה של האימון, MultiWorkerMirroredStrategy
יפיץ את האימון בין שתי המכונות.
ב-MultiWorkerMirroredStrategy
יש רק את סוגי המשימות chief ו-worker, לכן אין צורך להגדיר את מאגרי העובדים הנוספים. עם זאת, אם משתמשים ב-ParameterServerStrategy
של TensorFlow, צריך להגדיר את שרתי הפרמטרים במאגר העובדים 2. אם רוצים להוסיף למקבץ מכונה להערכה, צריך להגדיר את המכונה הזו במאגר העובדים 3.
לוחצים על Start training (התחלת האימון) כדי להתחיל את עבודת הכוונון של ההיפר-פרמטרים. בקטע Training במסוף, בכרטיסייה TRAINING PIPELINES, תוכלו לראות את המשימה החדשה שהפעלתם:
🎉 כל הכבוד! 🎉
למדתם איך להשתמש ב-Vertex AI כדי:
- השקת משימת אימון מרובת עובדים לאימון קוד שסופק בקונטיינר מותאם אישית. השתמשתם במודל TensorFlow בדוגמה הזו, אבל אפשר לאמן מודל שנוצר עם כל מסגרת באמצעות קונטיינרים מובנים או מותאמים אישית.
מידע נוסף על החלקים השונים של Vertex זמין במסמכי העזרה.
7. [אופציונלי] שימוש ב-Vertex SDK
בקטע הקודם הוסבר איך להפעיל את משימת האימון דרך ממשק המשתמש. בקטע הזה תוצג דרך חלופית לשלוח את משימת האימון באמצעות Vertex Python API.
חוזרים למכונה של ה-notebook ויוצרים מסמך notebook של TensorFlow 2 דרך מרכז האפליקציות:
מייבאים את Vertex AI SDK.
from google.cloud import aiplatform
כדי להפעיל את משימת האימון של ריבוי עובדים, קודם צריך להגדיר את המפרט של מאגר העובדים. חשוב לשים לב שהשימוש במעבדי GPU במפרט הוא אופציונלי לחלוטין, ואפשר להסיר את accelerator_type
ואת accelerator_count
אם רוצים אשכול של מעבד (CPU) בלבד כפי שמוצג בקטע הקודם.
# The spec of the worker pools including machine type and Docker image
# Be sure to replace {YOUR-PROJECT-ID} with your project ID.
worker_pool_specs=[
{
"replica_count": 1,
"machine_spec": {
"machine_type": "n1-standard-8", "accelerator_type": "NVIDIA_TESLA_V100", "accelerator_count": 1
},
"container_spec": {"image_uri": "gcr.io/{YOUR-PROJECT-ID}/multiworker:cassava"}
},
{
"replica_count": 1,
"machine_spec": {
"machine_type": "n1-standard-8", "accelerator_type": "NVIDIA_TESLA_V100", "accelerator_count": 1
},
"container_spec": {"image_uri": "gcr.io/{YOUR-PROJECT-ID}/multiworker:cassava"}
}
]
בשלב הבא, יוצרים ומריצים CustomJob
. צריך להחליף את {YOUR_BUCKET}
בקטגוריה בפרויקט לצורך שלב ההרצה המקדימות. אפשר להשתמש באותה קטגוריה שיצרתם קודם.
# Replace YOUR_BUCKET
my_multiworker_job = aiplatform.CustomJob(display_name='multiworker-cassava-sdk',
worker_pool_specs=worker_pool_specs,
staging_bucket='gs://{YOUR_BUCKET}')
my_multiworker_job.run()
בקטע Training במסוף, בכרטיסייה CUSTOM JOBS, תוכלו לראות את משימה האימון:
8. הסרת המשאבים
מכיוון שהגדרתנו ל-notebook זמן תפוגה של 60 דקות חוסר פעילות, אין צורך לדאוג לגבי כיבוי המכונה. כדי לכבות את המכונה באופן ידני, לוחצים על הלחצן Stop בקטע Vertex AI Workbench במסוף. כדי למחוק את המחברות כולה, לוחצים על הלחצן 'מחיקה'.
כדי למחוק את הקטגוריה של האחסון, עוברים לתפריט הניווט במסוף Cloud, לוחצים על Storage, בוחרים את הקטגוריה ולוחצים על Delete: