עזרה להגן על שונית המחסום הגדולה עם TensorFlow על Kaggle הצטרפו אתגר

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

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

סקירה כללית

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

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

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

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

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

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

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

הגדר את TensorFlow

import tensorflow as tf

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

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

  • סינכרוני לעומת אימונים אסינכרוני: אלו הם שתי דרכים נפוצות של הפצת אימונים עם הקבלת נתונים. באימון סנכרון, כל העובדים מתאמנים על פרוסות שונות של נתוני קלט בסנכרון, וצבירת מעברי צבע בכל שלב. בהדרכה אסינכרונית, כל העובדים מתאמנים באופן עצמאי על נתוני הקלט ומעדכנים משתנים באופן אסינכרוני. בדרך כלל אימון סנכרון נתמך באמצעות הקטנת הכל ואסינכרון באמצעות ארכיטקטורת שרת פרמטרים.
  • פלטפורמת חומרה: אולי כדאי לשנות את קנה המידה האימונים שלך על GPUs מרובים במחשב אחד, או מספר מחשבים ברשת (עם 0 או יותר GPUs כל אחד), או על ענן 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 שלך על יחידות עיבוד מותחות (TPUs) . TPUs הם ASICs המיוחדים של Google שנועדו להאיץ באופן דרמטי את עומסי העבודה של למידת מכונה. הם זמינים על גוגל Colab , את ענן מחקר TPU , ואת קלאוד 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 מבוסס והתומכת הן מעבדות ו- GPUs. CommunicationImplementation.NCCL משתמשת NCCL ומספק ביצועים המדינה- of-art על GPUs אך הוא אינו תומך מעבדים. 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 בכיתה.

ביישום זה, את worker ואת parameter server המשימות לרוץ 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 זמין רק עם הערכה באמצעות 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 גלוי. עדכון למשתנים בעותקים משוכפלים יצטבר לפני יישום המשתנים.

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

בנוסף האסטרטגיות הנ"ל, קיימות שתי אסטרטגיות אחרות אשר עשוי להיות שימושי עבור prototyping באגים בעת שימוש tf.distribute APIs.

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

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

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

default_strategy = tf.distribute.get_strategy()

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

  • זה מאפשר כתיבת קוד ספרייה מודע להפצה ללא תנאי. לדוגמה, ב tf.optimizer זה אתה יכול להשתמש tf.distribute.get_strategy ולהשתמש אסטרטגיה לצמצום הדרגתי-זה תמיד יחזור אובייקט אסטרטגיה שבו אתה יכול להתקשר Strategy.reduce API.
# 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 של מפרט ה- API Keras . tf.keras הוא ה- API ברמה גבוהה למודלים לבנות ולאמן. על ידי שילוב לתוך tf.keras backend, חלקה של זה בשבילך כדי להפיץ את האימון שנכתב במסגרת ההדרכה Keras באמצעות Model.fit .

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

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

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

הנה קטע קוד כדי לעשות זאת עבור מודל פשוט מאוד 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 מספק את ההדרכה קלט eval. אתה יכול גם להשתמש במערכים 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. הדרכה : ברט פיין-טיונינג למשימות רבות מן benchmark הדבק עם Model.fit ו TPUStrategy .
  6. גינת דגם TensorFlow מאגר המכילה אוספים של המדינה- of-the-art דגמים מיושמים באמצעות אסטרטגיות שונות.

השתמש ב-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. אתה גם השתמשת tf.distribute.Strategy.reduce API כדי לצבור את התוצאות שמחזירות 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)

בדוגמא שלעיל, אתה iterated רחב 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 מאגר המכילה אוספים של המדינה- of-the-art דגמים מיושמים באמצעות אסטרטגיות שונות.

נושאים אחרים

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

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

לקבלת הכשרה רב-העובד, כפי שהוזכר קודם לכן, אתה צריך להגדיר את 'TF_CONFIG' משתנה הסביבה עבור כל ריצה בינאריים באשכול שלך. 'TF_CONFIG' משתנה הסביבה הוא מחרוזת JSON המציין מה המשימות מהווים מקבץ, כתובותיהם כל תפקיד של המשימה באשכול. tensorflow/ecosystem ריפה מספק תבנית Kubernetes, אשר מגדירה '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" -worker 1 (העובד השני). תפקידים תקפים באשכול הם "chief" , "worker" , "ps" , ו "evaluator" . לא צריך להיות שום "ps" עבודה למעט בעת שימוש tf.distribute.experimental.ParameterServerStrategy .

מה הלאה?

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