אימונים מבוזרים עם TensorFlow

הצג באתר TensorFlow.org הפעל בגוגל קולאב צפה במקור ב-GitHub הורד מחברת

סקירה כללית

tf.distribute.Strategy הוא TensorFlow API להפצת הכשרה על פני מספר GPUs, מספר מכונות או TPUs. באמצעות ממשק API זה, אתה יכול להפיץ את הדגמים הקיימים ואת קוד ההדרכה שלך עם שינויים מינימליים בקוד.

tf.distribute.Strategy תוכננה מתוך מחשבה על מטרות מפתח אלו:

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

אתה יכול להפיץ אימון באמצעות tf.distribute.Strategy עם API ברמה גבוהה כמו Keras Model.fit , כמו גם לולאות אימון מותאמות אישית (ובאופן כללי, כל חישוב באמצעות TensorFlow).

ב-TensorFlow 2.x, אתה יכול להפעיל את התוכניות שלך בשקיקה, או בגרף באמצעות tf.function . tf.distribute.Strategy מתכוונת לתמוך בשני אופני הביצוע הללו, אך פועלת בצורה הטובה ביותר עם tf.function . מצב להוט מומלץ רק למטרות ניפוי באגים ואינו נתמך עבור tf.distribute.TPUStrategy . למרות שהדרכה היא המוקד של מדריך זה, ממשק API זה יכול לשמש גם להפצת הערכה וחיזוי בפלטפורמות שונות.

אתה יכול להשתמש ב- tf.distribute.Strategy עם מעט מאוד שינויים בקוד שלך, מכיוון שהרכיבים הבסיסיים של TensorFlow שונו כדי להיות מודעים לאסטרטגיה. זה כולל משתנים, שכבות, מודלים, מייעלים, מדדים, סיכומים ונקודות ביקורת.

במדריך זה תלמדו על סוגים שונים של אסטרטגיות וכיצד תוכלו להשתמש בהן במצבים שונים. כדי ללמוד כיצד לבצע ניפוי באגים בביצועים, עיין במדריך הביצועים של Optimize TensorFlow GPU .

הגדר את TensorFlow

import tensorflow as tf

סוגי אסטרטגיות

tf.distribute.Strategy מתכוונת לכסות מספר מקרי שימוש לאורך צירים שונים. חלק מהשילובים הללו נתמכים כעת ואחרים יתווספו בעתיד. חלק מהצירים הללו הם:

  • אימון סינכרוני לעומת אסינכרוני: אלו הן שתי דרכים נפוצות להפצת אימון עם מקביליות נתונים. באימון סנכרון, כל העובדים מתאמנים על פרוסות שונות של נתוני קלט בסנכרון, וצבירת מעברי צבע בכל שלב. בהדרכה אסינכרונית, כל העובדים מתאמנים באופן עצמאי על נתוני הקלט ומעדכנים משתנים באופן אסינכרוני. בדרך כלל אימון סנכרון נתמך באמצעות הקטנת הכל ואסינכרון באמצעות ארכיטקטורת שרת פרמטרים.
  • פלטפורמת חומרה: ייתכן שתרצה להתאים את האימון שלך למספר GPUs במכונה אחת, או למספר מכונות ברשת (עם 0 או יותר GPUs כל אחד), או ב-Cloud TPUs.

על מנת לתמוך במקרים של שימוש אלה, ל-TensorFlow יש MirroredStrategy , TPUStrategy , MultiWorkerMirroredStrategy , ParameterServerStrategy , CentralStorageStrategy , כמו גם אסטרטגיות אחרות זמינות. הסעיף הבא מסביר אילו מהם נתמכים באילו תרחישים ב-TensorFlow. הנה סקירה מהירה:

הדרכה API MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy CentralStorageStrategy ParameterServerStrategy
Keras Model.fit נתמך נתמך נתמך תמיכה נסיונית תמיכה נסיונית
לולאת אימון מותאמת אישית נתמך נתמך נתמך תמיכה נסיונית תמיכה נסיונית
API של Estimator תמיכה מוגבלת אינו נתמך תמיכה מוגבלת תמיכה מוגבלת תמיכה מוגבלת

אסטרטגיית מראה

tf.distribute.MirroredStrategy תומכת באימון מבוזר סינכרוני במספר GPUs במכונה אחת. זה יוצר העתק אחד לכל התקן GPU. כל משתנה במודל משתקף על פני כל ההעתקים. יחד, משתנים אלה יוצרים משתנה מושגי יחיד בשם MirroredVariable . משתנים אלה נשמרים מסונכרנים זה עם זה על ידי החלת עדכונים זהים.

אלגוריתמים יעילים להפחתת הכל משמשים כדי להעביר את העדכונים המשתנים על פני המכשירים. צמצם הכל את הטנזורים המצטברים בכל המכשירים על ידי הוספתם, והופכת אותם לזמינים בכל מכשיר. זהו אלגוריתם מפוזר יעיל מאוד ויכול להפחית את התקורה של הסנכרון באופן משמעותי. ישנם אלגוריתמים והטמעות רבים של צמצום הכל, בהתאם לסוג התקשורת הזמינה בין מכשירים. כברירת מחדל, הוא משתמש בספריית התקשורת הקולקטיבית של NVIDIA ( NCCL ) כיישום להפחתת הכל. אתה יכול לבחור מתוך כמה אפשרויות אחרות או לכתוב משלך.

הנה הדרך הפשוטה ביותר ליצור MirroredStrategy :

mirrored_strategy = tf.distribute.MirroredStrategy()
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

זה ייצור מופע MirroredStrategy , שישתמש בכל ה-GPUs הגלויים ל-TensorFlow, ו-NCCL - כתקשורת חוצת-מכשירים.

אם ברצונך להשתמש רק בחלק מה-GPUs במחשב שלך, תוכל לעשות זאת כך:

mirrored_strategy = tf.distribute.MirroredStrategy(devices=["/gpu:0", "/gpu:1"])
WARNING:tensorflow:Some requested devices in `tf.distribute.Strategy` are not visible to TensorFlow: /job:localhost/replica:0/task:0/device:GPU:1,/job:localhost/replica:0/task:0/device:GPU:0
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0', '/job:localhost/replica:0/task:0/device:GPU:1')

אם ברצונך לעקוף את התקשורת בין מכשירים, תוכל לעשות זאת באמצעות הארגומנט cross_device_ops על ידי אספקת מופע של tf.distribute.CrossDeviceOps . נכון לעכשיו, tf.distribute.HierarchicalCopyAllReduce ו- tf.distribute.ReductionToOneDevice הן שתי אפשרויות מלבד tf.distribute.NcclAllReduce , שהיא ברירת המחדל.

mirrored_strategy = tf.distribute.MirroredStrategy(
    cross_device_ops=tf.distribute.HierarchicalCopyAllReduce())
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

אסטרטגיה של TPUS

tf.distribute.TPUStrategy מאפשרת לך להפעיל את אימון TensorFlow שלך על יחידות עיבוד Tensor (TPUs) . TPUs הם ASICs המיוחדים של Google שנועדו להאיץ באופן דרמטי את עומסי העבודה של למידת מכונה. הם זמינים ב- Google Colab , ב- TPU Research Cloud וב- Cloud TPU .

במונחים של ארכיטקטורת אימון מבוזר, TPUStrategy היא אותה MirroredStrategy - היא מיישמת אימון מבוזר סינכרוני. TPUs מספקים יישום משלהם של פעולות יעילות להפחתת הכל ופעולות קולקטיביות אחרות על פני ליבות TPU מרובות, המשמשות ב- TPUStrategy .

כך תוכל ליצור TPUStrategy :

cluster_resolver = tf.distribute.cluster_resolver.TPUClusterResolver(
    tpu=tpu_address)
tf.config.experimental_connect_to_cluster(cluster_resolver)
tf.tpu.experimental.initialize_tpu_system(cluster_resolver)
tpu_strategy = tf.distribute.TPUStrategy(cluster_resolver)

מופע TPUClusterResolver עוזר לאתר את ה-TPUs. ב-Colab, אתה לא צריך לציין טיעונים כלשהם.

אם אתה רוצה להשתמש בזה עבור TPUs בענן:

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

אסטרטגיית MultiWorkerMirrored

tf.distribute.MultiWorkerMirroredStrategy דומה מאוד ל- MirroredStrategy . הוא מיישם אימון מבוזר סינכרוני על פני מספר עובדים, שלכל אחד מהם יש פוטנציאל למספר GPUs. בדומה ל- tf.distribute.MirroredStrategy , הוא יוצר עותקים של כל המשתנים במודל בכל מכשיר על פני כל העובדים.

הנה הדרך הפשוטה ביותר ליצור MultiWorkerMirroredStrategy :

strategy = tf.distribute.MultiWorkerMirroredStrategy()
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CommunicationImplementation.AUTO

ל- MultiWorkerMirroredStrategy יש שני יישומים לתקשורת חוצת-מכשירים. CommunicationImplementation.RING מבוסס RPC ותומך הן במעבדים והן במעבדי GPU. CommunicationImplementation.NCCL משתמש ב-NCCL ומספק ביצועים חדישים במעבדי GPU אך הוא אינו תומך במעבדים. CollectiveCommunication.AUTO דוחה את הבחירה ל-Tensorflow. אתה יכול לציין אותם בצורה הבאה:

communication_options = tf.distribute.experimental.CommunicationOptions(
    implementation=tf.distribute.experimental.CommunicationImplementation.NCCL)
strategy = tf.distribute.MultiWorkerMirroredStrategy(
    communication_options=communication_options)
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CommunicationImplementation.NCCL

אחד ההבדלים העיקריים להפעלת הכשרה מרובה עובדים, בהשוואה לאימון ריבוי GPU, הוא ההגדרה של ריבוי עובדים. משתנה הסביבה 'TF_CONFIG' הוא הדרך הסטנדרטית ב-TensorFlow לציין את תצורת האשכול לכל עובד שהוא חלק מהאשכול. למידע נוסף בסעיף הגדרת TF_CONFIG במסמך זה.

לפרטים נוספים על MultiWorkerMirroredStrategy , שקול את המדריכים הבאים:

ParameterServerStrategy

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

ב-TensorFlow 2, הכשרת שרת פרמטרים משתמשת בארכיטקטורה מבוססת רכז מרכזי דרך הכיתה tf.distribute.experimental.coordinator.ClusterCoordinator .

ביישום זה, משימות parameter server מריצים worker s שמקשיבים למשימות tf.distribute.Server . הרכז יוצר משאבים, שולח משימות הדרכה, כותב מחסומים ומטפל בכשלים במשימה.

בתכנות הפועל על המתאם, תשתמש באובייקט ParameterServerStrategy כדי להגדיר שלב הדרכה ותשתמש ב- ClusterCoordinator כדי לשלוח שלבי הדרכה לעובדים מרוחקים. הנה הדרך הפשוטה ביותר ליצור אותם:

strategy = tf.distribute.experimental.ParameterServerStrategy(
    tf.distribute.cluster_resolver.TFConfigClusterResolver(),
    variable_partitioner=variable_partitioner)
coordinator = tf.distribute.experimental.coordinator.ClusterCoordinator(
    strategy)

למידע נוסף על ParameterServerStrategy , בדוק את ההדרכה של שרת פרמטרים עם Keras Model.fit ומדריך לולאת אימון מותאם אישית .

ב-TensorFlow 1, ParameterServerStrategy זמין רק עם Estimator דרך סמל tf.compat.v1.distribute.experimental.ParameterServerStrategy .

אסטרטגיית אחסון מרכזית

tf.distribute.experimental.CentralStorageStrategy גם אימון סינכרוני. משתנים אינם משתקפים, במקום זאת הם ממוקמים על ה-CPU והפעולות משוכפלות על פני כל ה-GPUs המקומיים. אם יש רק GPU אחד, כל המשתנים והפעולות יוצבו באותו GPU.

צור מופע של CentralStorageStrategy על ידי:

central_storage_strategy = tf.distribute.experimental.CentralStorageStrategy()
INFO:tensorflow:ParameterServerStrategy (CentralStorageStrategy if you are using a single machine) with compute_devices = ['/job:localhost/replica:0/task:0/device:GPU:0'], variable_device = '/job:localhost/replica:0/task:0/device:GPU:0'

פעולה זו תיצור מופע CentralStorageStrategy שישתמש בכל ה-GPUs וה-CPU הגלויים. עדכון למשתנים בעותקים משוכפלים יצטבר לפני יישום המשתנים.

אסטרטגיות אחרות

בנוסף לאסטרטגיות שלעיל, ישנן שתי אסטרטגיות נוספות שעשויות להיות שימושיות עבור אב טיפוס וניפוי באגים בעת שימוש בממשקי API tf.distribute .

אסטרטגיית ברירת מחדל

אסטרטגיית ברירת המחדל היא אסטרטגיית הפצה שקיימת כאשר אין אסטרטגיית הפצה מפורשת בהיקף. הוא מיישם את ממשק tf.distribute.Strategy אך הוא מעבר ואינו מספק הפצה בפועל. לדוגמה, Strategy.run(fn) פשוט יקרא fn . קוד שנכתב באמצעות אסטרטגיה זו צריך להתנהג בדיוק כמו קוד שנכתב ללא כל אסטרטגיה. אתה יכול לחשוב על זה כאסטרטגיה "ללא הפעלה".

אסטרטגיית ברירת המחדל היא יחידה - ואי אפשר ליצור מופעים נוספים שלה. ניתן להשיג אותו באמצעות tf.distribute.get_strategy מחוץ להיקף של אסטרטגיה מפורשת (אותו API שניתן להשתמש בו כדי לקבל את האסטרטגיה הנוכחית בתוך היקף של אסטרטגיה מפורשת).

default_strategy = tf.distribute.get_strategy()

אסטרטגיה זו משרתת שתי מטרות עיקריות:

  • זה מאפשר כתיבת קוד ספרייה מודע להפצה ללא תנאי. לדוגמה, ב- tf.optimizer s אתה יכול להשתמש ב- tf.distribute.get_strategy ולהשתמש באסטרטגיה זו להפחתת הדרגות - היא תמיד תחזיר אובייקט אסטרטגיה עליו תוכל לקרוא ל-API Strategy.reduce .
# In optimizer or other library code
# Get currently active strategy
strategy = tf.distribute.get_strategy()
strategy.reduce("SUM", 1., axis=None)  # reduce some values
1.0
  • בדומה לקוד ספרייה, ניתן להשתמש בו כדי לכתוב תוכניות של משתמשי קצה שיעבדו עם ובלי אסטרטגיית הפצה, ללא צורך בהיגיון מותנה. להלן קטע קוד לדוגמה הממחיש זאת:
if tf.config.list_physical_devices('GPU'):
  strategy = tf.distribute.MirroredStrategy()
else:  # Use the Default Strategy
  strategy = tf.distribute.get_strategy()

with strategy.scope():
  # Do something interesting
  print(tf.Variable(1.))
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
MirroredVariable:{
  0: <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=1.0>
}

OneDevice Strategy

tf.distribute.OneDeviceStrategy היא אסטרטגיה להצבת כל המשתנים והחישובים במכשיר שצוין יחיד.

strategy = tf.distribute.OneDeviceStrategy(device="/gpu:0")

אסטרטגיה זו נבדלת מאסטרטגיית ברירת המחדל במספר דרכים. באסטרטגיית ברירת המחדל, לוגיקת המיקום המשתנה נשארת ללא שינוי בהשוואה להפעלת TensorFlow ללא כל אסטרטגיית הפצה. אבל בעת שימוש ב- OneDeviceStrategy , כל המשתנים שנוצרו בהיקפו ממוקמים במפורש על המכשיר שצוין. יתר על כן, כל פונקציה שנקראת דרך OneDeviceStrategy.run גם במכשיר שצוין.

קלט שמופץ באמצעות אסטרטגיה זו יאוחזר מראש למכשיר שצוין. באסטרטגיית ברירת המחדל, אין הפצת קלט.

בדומה לאסטרטגיית ברירת המחדל, ניתן להשתמש באסטרטגיה זו גם כדי לבדוק את הקוד שלך לפני המעבר לאסטרטגיות אחרות המופצות למעשה למספר מכשירים/מכונות. זה יפעיל את מנגנון אסטרטגיית ההפצה קצת יותר מאסטרטגיית ברירת המחדל, אך לא במידה המלאה של שימוש, למשל, MirroredStrategy או TPUStrategy . אם אתה רוצה קוד שמתנהג כאילו אין אסטרטגיה, השתמש באסטרטגיית ברירת המחדל.

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

השתמש ב-tf.distribute.Strategy עם Keras Model.fit

tf.distribute.Strategy משולבת ב- tf.keras , שהיא היישום של TensorFlow של מפרט Keras API . tf.keras הוא API ברמה גבוהה לבנייה והדרכה של דגמים. על ידי שילוב ב-backend של tf.keras , זה חלק עבורך להפיץ את ההדרכה שלך שנכתבה במסגרת ההדרכה של Keras באמצעות Model.fit .

הנה מה שאתה צריך לשנות בקוד שלך:

  1. צור מופע של tf.distribute.Strategy המתאימה.
  2. העבר את יצירת המודל, כלי האופטימיזציה והמדדים של Keras בתוך strategy.scope .

אסטרטגיות הפצה של TensorFlow תומכות בכל סוגי המודלים של Keras - רצף , פונקציונלי ותת-סיווג.

להלן קטע קוד לעשות זאת עבור דגם Keras פשוט מאוד עם שכבה אחת Dense :

mirrored_strategy = tf.distribute.MirroredStrategy()

with mirrored_strategy.scope():
  model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])

model.compile(loss='mse', optimizer='sgd')
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

דוגמה זו משתמשת ב- MirroredStrategy , כך שתוכל להפעיל זאת על מחשב עם מספר GPUs. strategy.scope() מציין ל-Keras באיזו אסטרטגיה להשתמש כדי להפיץ את ההדרכה. יצירת מודלים/אופטימיזציה/מדדים בהיקף זה מאפשרת ליצור משתנים מבוזרים במקום משתנים רגילים. לאחר הגדרה זו, אתה יכול להתאים את הדגם שלך כמו שאתה עושה בדרך כלל. MirroredStrategy דואגת לשכפל את ההכשרה של המודל על ה-GPUs הזמינים, צבירת שיפועים ועוד.

dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(10)
model.fit(dataset, epochs=2)
model.evaluate(dataset)
Epoch 1/2
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
2021-10-26 01:27:56.527729: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Found an unshardable source dataset: name: "TensorDataset/_2"
op: "TensorDataset"
input: "Placeholder/_0"
input: "Placeholder/_1"
attr {
  key: "Toutput_types"
  value {
    list {
      type: DT_FLOAT
      type: DT_FLOAT
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 1
        }
      }
      shape {
        dim {
          size: 1
        }
      }
    }
  }
}
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
10/10 [==============================] - 3s 2ms/step - loss: 2.2552
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
Epoch 2/2
10/10 [==============================] - 0s 2ms/step - loss: 0.9968
2021-10-26 01:27:59.372113: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Found an unshardable source dataset: name: "TensorDataset/_2"
op: "TensorDataset"
input: "Placeholder/_0"
input: "Placeholder/_1"
attr {
  key: "Toutput_types"
  value {
    list {
      type: DT_FLOAT
      type: DT_FLOAT
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 1
        }
      }
      shape {
        dim {
          size: 1
        }
      }
    }
  }
}
10/10 [==============================] - 1s 2ms/step - loss: 0.6190
0.6190494298934937

כאן tf.data.Dataset מספק את ההדרכה והקלט. אתה יכול גם להשתמש במערכים NumPy:

import numpy as np

inputs, targets = np.ones((100, 1)), np.ones((100, 1))
model.fit(inputs, targets, epochs=2, batch_size=10)
Epoch 1/2
2021-10-26 01:28:00.609977: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Did not find a shardable source, walked to a node which is not a dataset: name: "FlatMapDataset/_9"
op: "FlatMapDataset"
input: "PrefetchDataset/_8"
attr {
  key: "Targuments"
  value {
    list {
    }
  }
}
attr {
  key: "f"
  value {
    func {
      name: "__inference_Dataset_flat_map_slice_batch_indices_997"
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 10
        }
      }
    }
  }
}
attr {
  key: "output_types"
  value {
    list {
      type: DT_INT64
    }
  }
}
. Consider either turning off auto-sharding or switching the auto_shard_policy to DATA to shard this dataset. You can do this by creating a new `tf.data.Options()` object then setting `options.experimental_distribute.auto_shard_policy = AutoShardPolicy.DATA` before applying the options object to the dataset via `dataset.with_options(options)`.
10/10 [==============================] - 1s 2ms/step - loss: 0.4406
Epoch 2/2
10/10 [==============================] - 0s 2ms/step - loss: 0.1947
<keras.callbacks.History at 0x7fb81813d2d0>

בשני המקרים - עם Dataset או NumPy - כל אצווה של הקלט הנתון מחולקת באופן שווה בין העותקים המרובים. לדוגמה, אם אתה משתמש ב- MirroredStrategy עם 2 GPUs, כל אצווה בגודל 10 תחולק בין 2 GPUs, כאשר כל אחד יקבל 5 דוגמאות קלט בכל שלב. לאחר מכן כל תקופה תתאמן מהר יותר ככל שתוסיף עוד GPUs. בדרך כלל, תרצה להגדיל את גודל האצווה שלך ככל שתוסיף עוד מאיצים, כדי לעשות שימוש יעיל בכוח המחשוב הנוסף. תצטרך גם לכוון מחדש את קצב הלמידה שלך, בהתאם לדגם. אתה יכול להשתמש ב- strategy.num_replicas_in_sync כדי לקבל את מספר ההעתקים.

# Compute a global batch size using a number of replicas.
BATCH_SIZE_PER_REPLICA = 5
global_batch_size = (BATCH_SIZE_PER_REPLICA *
                     mirrored_strategy.num_replicas_in_sync)
dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100)
dataset = dataset.batch(global_batch_size)

LEARNING_RATES_BY_BATCH_SIZE = {5: 0.1, 10: 0.15}
learning_rate = LEARNING_RATES_BY_BATCH_SIZE[global_batch_size]

מה נתמך עכשיו?

הדרכה API MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy ParameterServerStrategy CentralStorageStrategy
Keras Model.fit נתמך נתמך נתמך תמיכה נסיונית תמיכה נסיונית

דוגמאות והדרכות

להלן רשימה של מדריכים ודוגמאות הממחישות את האינטגרציה שלעיל מקצה לקצה עם Keras Model.fit :

  1. הדרכה : אימון עם Model.fit ו- MirroredStrategy .
  2. הדרכה : אימון עם Model.fit ו- MultiWorkerMirroredStrategy .
  3. מדריך : מכיל דוגמה לשימוש ב- Model.fit וב- TPUStrategy .
  4. הדרכה : אימון שרת פרמטרים עם Model.fit ו- ParameterServerStrategy .
  5. מדריך : כוונון עדין של BERT למשימות רבות ממבחן ה-GLUE עם Model.fit ו- TPUStrategy .
  6. מאגר TensorFlow Model Garden המכיל אוספים של מודלים חדישים המיושמים באמצעות אסטרטגיות שונות.

השתמש ב-tf.distribute.Strategy עם לולאות אימון מותאמות אישית

כפי שהוכח לעיל, שימוש ב- tf.distribute.Strategy עם Keras Model.fit מצריך שינוי רק כמה שורות מהקוד שלך. עם קצת יותר מאמץ, אתה יכול גם להשתמש ב- tf.distribute.Strategy עם לולאות אימון מותאמות אישית .

אם אתה צריך יותר גמישות ושליטה על לולאות האימון שלך ממה שאפשר עם Estimator או Keras, אתה יכול לכתוב לולאות אימון מותאמות אישית. לדוגמה, בעת שימוש ב-GAN, ייתכן שתרצה לבצע מספר שונה של צעדי מחולל או מפלה בכל סיבוב. באופן דומה, המסגרות ברמה הגבוהה אינן מתאימות במיוחד לאימון למידת חיזוק.

שיעורי tf.distribute.Strategy מספקים מערכת ליבה של שיטות לתמיכה בלולאות אימון מותאמות אישית. השימוש באלה עשוי לדרוש מבנה מחדש קל של הקוד בתחילה, אך ברגע שזה נעשה, אתה אמור להיות מסוגל לעבור בין GPUs, TPUs ומכונות מרובות פשוט על ידי שינוי מופע האסטרטגיה.

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

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

with mirrored_strategy.scope():
  model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])
  optimizer = tf.keras.optimizers.SGD()

לאחר מכן, צור את מערך הנתונים של הקלט וקרא ל- tf.distribute.Strategy.experimental_distribute_dataset כדי להפיץ את מערך הנתונים על סמך האסטרטגיה.

dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(
    global_batch_size)
dist_dataset = mirrored_strategy.experimental_distribute_dataset(dataset)
2021-10-26 01:28:01.831942: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Found an unshardable source dataset: name: "TensorDataset/_2"
op: "TensorDataset"
input: "Placeholder/_0"
input: "Placeholder/_1"
attr {
  key: "Toutput_types"
  value {
    list {
      type: DT_FLOAT
      type: DT_FLOAT
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 1
        }
      }
      shape {
        dim {
          size: 1
        }
      }
    }
  }
}

לאחר מכן, הגדירו שלב אחד באימון. השתמש tf.GradientTape כדי לחשב מעברי צבע ואופטימיזציה כדי להחיל את ההדרגות כדי לעדכן את המשתנים של המודל שלך. כדי להפיץ את שלב ההדרכה הזה, הכניסו אותו לפונקציה train_step והעבירו אותו ל- tf.distribute.Strategy.run יחד עם כניסות הנתונים שקיבלתם מ- dist_dataset שנוצרו קודם לכן:

loss_object = tf.keras.losses.BinaryCrossentropy(
  from_logits=True,
  reduction=tf.keras.losses.Reduction.NONE)

def compute_loss(labels, predictions):
  per_example_loss = loss_object(labels, predictions)
  return tf.nn.compute_average_loss(per_example_loss, global_batch_size=global_batch_size)

def train_step(inputs):
  features, labels = inputs

  with tf.GradientTape() as tape:
    predictions = model(features, training=True)
    loss = compute_loss(labels, predictions)

  gradients = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  return loss

@tf.function
def distributed_train_step(dist_inputs):
  per_replica_losses = mirrored_strategy.run(train_step, args=(dist_inputs,))
  return mirrored_strategy.reduce(tf.distribute.ReduceOp.SUM, per_replica_losses,
                         axis=None)

יש לציין עוד כמה דברים בקוד למעלה:

  1. השתמשת tf.nn.compute_average_loss כדי לחשב את ההפסד. tf.nn.compute_average_loss מסכם את ההפסד לכל דוגמה ומחלק את הסכום ב- global_batch_size . זה חשוב כי מאוחר יותר לאחר חישוב ההדרגות על כל העתק, הם מצטברים על פני ההעתקים על ידי סיכומם .
  2. השתמשת גם בממשק API של tf.distribute.Strategy.reduce כדי לצבור את התוצאות המוחזרות על ידי tf.distribute.Strategy.run . tf.distribute.Strategy.run מחזיר תוצאות מכל העתק מקומי באסטרטגיה, וישנן מספר דרכים לצרוך תוצאה זו. אתה יכול reduce אותם כדי לקבל ערך מצטבר. אתה יכול גם לעשות tf.distribute.Strategy.experimental_local_results כדי לקבל את רשימת הערכים הכלולה בתוצאה, אחד לכל עותק מקומי.
  3. כאשר אתה קורא apply_gradients במסגרת אסטרטגיית הפצה, ההתנהגות שלו משתנה. באופן ספציפי, לפני החלת שיפועים על כל מופע מקביל במהלך אימון סינכרוני, הוא מבצע סיכום-על-הכל-רפליקות של השיפועים.

לבסוף, לאחר שהגדרת את שלב האימון, אתה יכול לחזור על dist_dataset ולהפעיל את האימון בלולאה:

for dist_inputs in dist_dataset:
  print(distributed_train_step(dist_inputs))
tf.Tensor(0.18686396, shape=(), dtype=float32)
tf.Tensor(0.18628375, shape=(), dtype=float32)
tf.Tensor(0.18570684, shape=(), dtype=float32)
tf.Tensor(0.18513316, shape=(), dtype=float32)
tf.Tensor(0.1845627, shape=(), dtype=float32)
tf.Tensor(0.18399543, shape=(), dtype=float32)
tf.Tensor(0.18343134, shape=(), dtype=float32)
tf.Tensor(0.18287037, shape=(), dtype=float32)
tf.Tensor(0.18231256, shape=(), dtype=float32)
tf.Tensor(0.18175781, shape=(), dtype=float32)
tf.Tensor(0.18120615, shape=(), dtype=float32)
tf.Tensor(0.18065754, shape=(), dtype=float32)
tf.Tensor(0.18011193, shape=(), dtype=float32)
tf.Tensor(0.17956935, shape=(), dtype=float32)
tf.Tensor(0.17902976, shape=(), dtype=float32)
tf.Tensor(0.17849308, shape=(), dtype=float32)
tf.Tensor(0.17795937, shape=(), dtype=float32)
tf.Tensor(0.17742859, shape=(), dtype=float32)
tf.Tensor(0.17690066, shape=(), dtype=float32)
tf.Tensor(0.17637561, shape=(), dtype=float32)

בדוגמה למעלה, עברת על ה- dist_dataset כדי לספק קלט לאימון שלך. אתה גם מסופק עם ערכת הנתונים tf.distribute.Strategy.make_experimental_numpy_dataset כדי לתמוך בכניסות NumPy. אתה יכול להשתמש ב-API זה כדי ליצור מערך נתונים לפני קריאה tf.distribute.Strategy.experimental_distribute_dataset .

דרך נוספת לבצע איטרציה על הנתונים שלך היא להשתמש באופן מפורש באיטרטורים. ייתכן שתרצה לעשות זאת כאשר ברצונך לרוץ עבור מספר נתון של שלבים, לעומת איטרציה על כל מערך הנתונים. האיטרציה שלעיל תשתנה כעת כדי ליצור תחילה איטרטור ולאחר next להתקשר אליו במפורש כדי לקבל את נתוני הקלט.

iterator = iter(dist_dataset)
for _ in range(10):
  print(distributed_train_step(next(iterator)))
tf.Tensor(0.17585339, shape=(), dtype=float32)
tf.Tensor(0.17533402, shape=(), dtype=float32)
tf.Tensor(0.17481743, shape=(), dtype=float32)
tf.Tensor(0.17430364, shape=(), dtype=float32)
tf.Tensor(0.17379259, shape=(), dtype=float32)
tf.Tensor(0.17328428, shape=(), dtype=float32)
tf.Tensor(0.17277871, shape=(), dtype=float32)
tf.Tensor(0.17227581, shape=(), dtype=float32)
tf.Tensor(0.17177561, shape=(), dtype=float32)
tf.Tensor(0.17127804, shape=(), dtype=float32)

זה מכסה את המקרה הפשוט ביותר של שימוש ב- tf.distribute.Strategy API כדי להפיץ לולאות אימון מותאמות אישית.

מה נתמך עכשיו?

הדרכה API MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy ParameterServerStrategy CentralStorageStrategy
לולאת אימון מותאמת אישית נתמך נתמך נתמך תמיכה נסיונית תמיכה נסיונית

דוגמאות והדרכות

הנה כמה דוגמאות לשימוש באסטרטגיות הפצה עם לולאות אימון מותאמות אישית:

  1. הדרכה : אימון עם לולאת אימון מותאמת אישית ו- MirroredStrategy .
  2. הדרכה : אימון עם לולאת אימון מותאמת אישית ו- MultiWorkerMirroredStrategy .
  3. מדריך : מכיל דוגמה ללולאת אימון מותאמת אישית עם TPUStrategy .
  4. מדריך : אימון שרת פרמטרים עם לולאת אימון מותאמת אישית ו- ParameterServerStrategy .
  5. מאגר TensorFlow Model Garden המכיל אוספים של מודלים חדישים המיושמים באמצעות אסטרטגיות שונות.

נושאים אחרים

חלק זה מכסה כמה נושאים שרלוונטיים למקרי שימוש מרובים.

הגדרת משתנה הסביבה TF_CONFIG

להכשרה מרובה עובדים, כפי שהוזכר קודם לכן, עליך להגדיר את משתנה הסביבה 'TF_CONFIG' עבור כל בינארי הפועל באשכול שלך. משתנה הסביבה 'TF_CONFIG' הוא מחרוזת JSON המציינת אילו משימות מהוות אשכול, הכתובות שלהן ותפקידה של כל משימה באשכול. ה- tensorflow/ecosystem מספקת תבנית 'TF_CONFIG' עבור משימות האימון שלך.

ישנם שני מרכיבים של 'TF_CONFIG' : אשכול ומשימה.

  • אשכול מספק מידע על אשכול ההכשרה, שהוא הכתבה המורכבת מסוגים שונים של עבודות כגון עובדים. בהכשרה מרובת עובדים, יש בדרך כלל עובד אחד שלוקח על עצמו קצת יותר אחריות כמו שמירת מחסום וכתיבת קובץ סיכום עבור TensorBoard בנוסף למה שעובד רגיל עושה. עובד כזה מכונה העובד ה"ראשי", ומקובל כי העובד בעל מדד 0 מתמנה לעובד הראשי (למעשה כך tf.distribute.Strategy ).
  • משימה לעומת זאת מספקת מידע על המשימה הנוכחית. אשכול הרכיבים הראשון זהה עבור כל העובדים, ומשימת הרכיב השני שונה בכל עובד ומציינת את הסוג והאינדקס של אותו עובד.

דוגמה אחת של 'TF_CONFIG' היא:

os.environ["TF_CONFIG"] = json.dumps({
    "cluster": {
        "worker": ["host1:port", "host2:port", "host3:port"],
        "ps": ["host4:port", "host5:port"]
    },
   "task": {"type": "worker", "index": 1}
})

'TF_CONFIG' זה מציין שיש שלושה עובדים ושתי משימות "ps" ב"אשכול "cluster" יחד עם המארחים והיציאות שלהם. חלק ה"משימה "task" מציין את התפקיד של המשימה הנוכחית ב"אשכול "cluster" - עובד 1 (העובד השני). תפקידים תקפים באשכול הם "chief" , "worker" , "ps" "evaluator" . לא אמורה להיות עבודת "ps" אלא בעת שימוש ב- tf.distribute.experimental.ParameterServerStrategy .

מה הלאה?

tf.distribute.Strategy נמצאת בפיתוח פעיל. נסה את זה וספק את המשוב שלך באמצעות בעיות GitHub .