التدريب الموزع مع TensorFlow

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تحميل دفتر

ملخص

tf.distribute.Strategy هي واجهة برمجة تطبيقات TensorFlow لتوزيع التدريب عبر وحدات معالجة رسومات متعددة أو أجهزة متعددة أو وحدات TPU. باستخدام واجهة برمجة التطبيقات هذه ، يمكنك توزيع النماذج الحالية ورمز التدريب الخاص بك مع الحد الأدنى من التغييرات في التعليمات البرمجية.

tf.distribute.Strategy تم تصميم الإستراتيجية مع وضع هذه الأهداف الرئيسية في الاعتبار:

  • سهل الاستخدام ودعم شرائح مستخدم متعددة ، بما في ذلك الباحثين ومهندسي التعلم الآلي ، إلخ.
  • قدم أداءً جيدًا خارج الصندوق.
  • سهولة التبديل بين الاستراتيجيات.

يمكنك توزيع التدريب باستخدام tf.distribute.Strategy مع واجهة برمجة تطبيقات عالية المستوى مثل Keras Model.fit ، بالإضافة إلى حلقات تدريب مخصصة (وبشكل عام ، أي حساب باستخدام TensorFlow).

في TensorFlow 2.x ، يمكنك تنفيذ برامجك بلهفة ، أو في رسم بياني باستخدام tf.function . tf.distribute.Strategy يعتزم دعم وضعي التنفيذ هذين ، ولكنه يعمل بشكل أفضل مع tf.function . يوصى باستخدام الوضع الحثيث فقط لأغراض التصحيح وهو غير مدعوم لـ tf.distribute.TPUStrategy . على الرغم من أن التدريب هو محور هذا الدليل ، إلا أنه يمكن أيضًا استخدام واجهة برمجة التطبيقات هذه لتوزيع التقييم والتنبؤ على منصات مختلفة.

يمكنك استخدام tf.distribute.Strategy مع تغييرات قليلة جدًا في التعليمات البرمجية الخاصة بك ، لأن المكونات الأساسية لـ TensorFlow تم تغييرها لتصبح مدركة للاستراتيجية. يتضمن ذلك المتغيرات والطبقات والنماذج والمحسِّنون والمقاييس والملخصات ونقاط التحقق.

في هذا الدليل ، ستتعرف على أنواع مختلفة من الاستراتيجيات وكيف يمكنك استخدامها في مواقف مختلفة. لمعرفة كيفية تصحيح أخطاء الأداء ، راجع دليل أداء Optimize TensorFlow GPU .

قم بإعداد TensorFlow

import tensorflow as tf

أنواع الاستراتيجيات

tf.distribute.Strategy تهدف الإستراتيجية إلى تغطية عدد من حالات الاستخدام على طول محاور مختلفة. بعض هذه المجموعات مدعومة حاليًا وستتم إضافة البعض الآخر في المستقبل. بعض هذه المحاور هي:

  • التدريب المتزامن مقابل التدريب غير المتزامن: هاتان طريقتان شائعتان لتوزيع التدريب بتوازي البيانات. في التدريب المتزامن ، يتدرب جميع العمال على شرائح مختلفة من بيانات الإدخال المتزامنة ، ويجمعون التدرجات في كل خطوة. في التدريب غير المتزامن ، يتم تدريب جميع العمال بشكل مستقل على بيانات الإدخال وتحديث المتغيرات بشكل غير متزامن. عادةً ما يتم دعم تدريب المزامنة عبر تقليل الكل وغير المتزامن من خلال بنية خادم المعلمات.
  • النظام الأساسي للأجهزة: قد ترغب في توسيع نطاق تدريبك على وحدات معالجة رسومات متعددة على جهاز واحد ، أو أجهزة متعددة في شبكة (مع 0 أو أكثر من وحدات معالجة الرسومات لكل منها) ، أو على Cloud TPUs.

من أجل دعم حالات الاستخدام هذه ، تمتلك TensorFlow MirroredStrategy و TPUStrategy و MultiWorkerMirroredStrategy و ParameterServerStrategy و CentralStorageStrategy بالإضافة إلى الاستراتيجيات الأخرى المتاحة. يوضح القسم التالي أيًا منها مدعوم في أي سيناريوهات في TensorFlow. فيما يلي نظرة عامة سريعة:

تدريب API MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy CentralStorageStrategy ParameterServerStrategy
Keras Model.fit أيد أيد أيد دعم تجريبي دعم تجريبي
حلقة تدريب مخصصة أيد أيد أيد دعم تجريبي دعم تجريبي
مقدر API دعم محدود غير مدعوم دعم محدود دعم محدود دعم محدود

استراتيجية

يدعم tf.distribute.MirroredStrategy التدريب الموزع المتزامن على وحدات معالجة الرسومات المتعددة على جهاز واحد. يقوم بإنشاء نسخة متماثلة واحدة لكل جهاز 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 ، والذي سيستخدم جميع وحدات معالجة الرسومات المرئية لـ TensorFlow و NCCL - كاتصال عبر الأجهزة.

إذا كنت ترغب في استخدام بعض وحدات معالجة الرسومات فقط على جهازك ، فيمكنك القيام بذلك على النحو التالي:

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 (TPU) . 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 في تحديد موقع TPU. في Colab ، لا تحتاج إلى تحديد أي حجج لها.

إذا كنت تريد استخدام هذا لـ Cloud TPU:

  • يجب تحديد اسم مورد TPU الخاص بك في وسيطة tpu .
  • يجب تهيئة نظام TPU بشكل صريح في بداية البرنامج. هذا مطلوب قبل استخدام TPUs للحساب. يؤدي بدء تشغيل نظام TPU أيضًا إلى مسح ذاكرة TPU ، لذلك من المهم إكمال هذه الخطوة أولاً لتجنب فقدان الحالة.

MultiWorkerMirroredStrategy

tf.distribute.MultiWorkerMirroredStrategy مشابه جدًا لـ MirroredStrategy . ينفذ تدريبًا موزعًا متزامنًا عبر عدة عمال ، لكل منهم وحدات معالجة رسومات متعددة محتملة. على غرار 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 ويدعم كلاً من وحدات المعالجة المركزية ووحدات معالجة الرسومات. CommunicationImplementation.NCCL : يستخدم NCCL NCCL ويوفر أداءً متطورًا على وحدات معالجة الرسومات ولكنه لا يدعم وحدات المعالجة المركزية (CPU). CollectiveCommunication.AUTO Communication.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

أحد الاختلافات الرئيسية للحصول على تدريب متعدد العمال ، مقارنةً بالتدريب على وحدات معالجة الرسومات المتعددة ، هو الإعداد متعدد العمال. متغير البيئة 'TF_CONFIG' هو الطريقة القياسية في TensorFlow لتحديد تكوين الكتلة لكل عامل يمثل جزءًا من الكتلة. تعرف على المزيد في قسم إعداد TF_CONFIG من هذا المستند.

لمزيد من التفاصيل حول MultiWorkerMirroredStrategy ، ضع في اعتبارك البرامج التعليمية التالية:

ParameterServerStrategy

يعد تدريب خادم المعلمات طريقة موازية للبيانات الشائعة لتوسيع نطاق تدريب النموذج على أجهزة متعددة. تتكون مجموعة تدريب خادم المعلمات من العمال وخوادم المعلمات. يتم إنشاء المتغيرات على خوادم المعلمات ويتم قراءتها وتحديثها من قبل العاملين في كل خطوة. تحقق من البرنامج التعليمي للتدريب على خادم Parameter للحصول على التفاصيل.

في TensorFlow 2 ، يستخدم تدريب خادم المعلمات بنية قائمة على المنسق المركزي عبر فئة tf.distribute.experimental.coordinator.ClusterCoordinator .

في هذا التطبيق ، تقوم مهام parameter server worker والمعلمة بتشغيل tf.distribute.Server s التي تستمع للمهام من المنسق. ينشئ المنسق الموارد ويرسل مهام التدريب ويكتب نقاط التفتيش ويتعامل مع فشل المهام.

في البرمجة التي يتم تشغيلها على المنسق ، ستستخدم كائن ParameterServerStrategy لتحديد خطوة تدريب واستخدام ClusterCoordinator لإرسال خطوات التدريب إلى العاملين عن بُعد. إليك أبسط طريقة لإنشائها:

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

لمعرفة المزيد حول ParameterServerStrategy ، تحقق من تدريب خادم Parameter مع Keras Model.fit وبرنامج تعليمي مخصص لحلقة التدريب .

في TensorFlow 1 ، يتوفر ParameterServerStrategy فقط مع مقدر عبر tf.compat.v1.distribute.experimental.ParameterServerStrategy رمز.

إستراتيجية CentralStorage

تقوم tf.distribute.experimental.CentralStorageStrategy بتدريب متزامن أيضًا. لا يتم عكس المتغيرات ، بدلاً من ذلك يتم وضعها على وحدة المعالجة المركزية ويتم تكرار العمليات عبر جميع وحدات معالجة الرسومات المحلية. إذا كان هناك 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 والذي سيستخدم جميع وحدات معالجة الرسومات ووحدة المعالجة المركزية المرئية. سيتم تجميع تحديث المتغيرات في النسخ المتماثلة قبل تطبيقها على المتغيرات.

استراتيجيات أخرى

بالإضافة إلى الاستراتيجيات المذكورة أعلاه ، هناك استراتيجيتان أخريان قد تكونان مفيدتين في وضع النماذج الأولية وتصحيح الأخطاء عند استخدام tf.distribute APIs.

الإستراتيجية الافتراضية

الإستراتيجية الافتراضية هي إستراتيجية توزيع تكون موجودة عندما لا توجد إستراتيجية توزيع واضحة في النطاق. يقوم بتنفيذ واجهة tf.distribute.Strategy ولكنه تمريري ولا يوفر توزيعًا فعليًا. على سبيل المثال ، ستقوم Strategy.run(fn) باستدعاء fn . يجب أن يتصرف الكود المكتوب باستخدام هذه الإستراتيجية تمامًا مثل الكود المكتوب بدون أي استراتيجية. يمكنك التفكير في الأمر على أنه إستراتيجية "عدم التشغيل".

الإستراتيجية الافتراضية هي إستراتيجية مفردة - ولا يمكن للمرء إنشاء المزيد منها. يمكن الحصول عليها باستخدام tf.distribute.get_strategy خارج نطاق أي استراتيجية صريحة (نفس واجهة برمجة التطبيقات التي يمكن استخدامها للحصول على الإستراتيجية الحالية داخل نطاق إستراتيجية صريحة).

default_strategy = tf.distribute.get_strategy()

تخدم هذه الاستراتيجية غرضين رئيسيين:

  • يسمح لكتابة كود مكتبة مدرك للتوزيع دون قيد أو شرط. على سبيل المثال ، في tf.optimizer s يمكنك استخدام 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>
}

OneDeviceStrategy

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 عبارة عن واجهة برمجة تطبيقات عالية المستوى لبناء النماذج وتدريبها. من خلال الدمج في الواجهة الخلفية لـ 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 ، لذا يمكنك تشغيل هذا على جهاز به عدة وحدات معالجة رسومات. يشير Strategy.scope strategy.scope() إلى Keras إلى الاستراتيجية التي يجب استخدامها لتوزيع التدريب. يتيح لك إنشاء النماذج / المُحسِّنون / المقاييس داخل هذا النطاق إنشاء متغيرات موزعة بدلاً من المتغيرات العادية. بمجرد إعداد هذا ، يمكنك ملاءمة النموذج الخاص بك كما تفعل عادةً. تهتم MirroredStrategy بتكرار تدريب النموذج على وحدات معالجة الرسومات المتاحة وتجميع التدرجات والمزيد.

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 مع وحدتي GPU ، فسيتم تقسيم كل دفعة بحجم 10 بين وحدتي GPU ، مع تلقي كل منها 5 أمثلة على الإدخال في كل خطوة. ستتدرب كل فترة بعد ذلك بشكل أسرع كلما أضفت المزيد من وحدات معالجة الرسومات. عادة ، قد ترغب في زيادة حجم الدفعة الخاصة بك مع إضافة المزيد من المسرعات ، وذلك للاستفادة الفعالة من قوة الحوسبة الإضافية. ستحتاج أيضًا إلى إعادة ضبط معدل التعلم الخاص بك ، اعتمادًا على النموذج. يمكنك استخدام 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 مجموعة أساسية من الأساليب لدعم حلقات التدريب المخصصة. قد يتطلب استخدام هذه إعادة هيكلة بسيطة للرمز في البداية ، ولكن بمجرد الانتهاء من ذلك ، يجب أن تكون قادرًا على التبديل بين وحدات معالجة الرسومات (GPU) و (TPU) والأجهزة المتعددة ببساطة عن طريق تغيير مثيل الإستراتيجية.

يوجد أدناه مقتطف موجز يوضح حالة الاستخدام هذه لمثال تدريب بسيط باستخدام نموذج 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)

في المثال أعلاه ، قمت dist_dataset عبر مجموعة البيانات لتوفير مدخلات للتدريب الخاص بك. يتم تزويدك أيضًا بمجموعة tf.distribute.Strategy.make_experimental_numpy_dataset لدعم مدخلات NumPy. يمكنك استخدام واجهة برمجة التطبيقات هذه لإنشاء مجموعة بيانات قبل استدعاء 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 نموذج 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" - العامل 1 (العامل الثاني). الأدوار الصالحة في الكتلة هي "chief" و "worker" و "ps" و "evaluator" . يجب ألا تكون هناك وظيفة "ps" إلا عند استخدام tf.distribute.experimental.ParameterServerStrategy .

ماذا بعد؟

tf.distribute.Strategy . الإستراتيجية قيد التطوير. جربه وقدم ملاحظاتك باستخدام مشكلات GitHub .