ترجمت واجهة Cloud Translation API‏ هذه الصفحة.
Switch to English

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

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

نظرة عامة

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

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

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

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

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

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

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

# Import TensorFlow
import tensorflow as tf

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

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

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

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

API التدريب استراتيجية TPUS الإستراتيجية MultiWorkerMirroredStrategy إستراتيجية CentralStorage ParameterServerStrategy
واجهة برمجة تطبيقات Keras أيد أيد دعم تجريبي دعم تجريبي الدعم المخطط له 2.3
حلقة تدريب مخصصة أيد أيد دعم تجريبي دعم تجريبي الدعم المخطط له 2.3
مقدر 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 و TensorFlow 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:Using MirroredStrategy with devices ('/device:GPU:0',)
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CommunicationImplementation.AUTO

لدى MultiWorkerMirroredStrategy تطبيقين للاتصالات عبر الأجهزة. CommunicationImplementation.RING يعتمد على RPC ويدعم كلاً من وحدة المعالجة المركزية ووحدة معالجة الرسومات. CommunicationImplementation.NCCL يستخدم NCCL NCCL الخاص بـ Nvidia ويوفر أحدث أداء على وحدة معالجة الرسومات ، ولكنه لا يدعم وحدة المعالجة المركزية. 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:Using MirroredStrategy with devices ('/device:GPU:0',)
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CommunicationImplementation.NCCL

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

ParameterServerStrategy

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

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

في هذا التنفيذ ، تقوم مهام worker parameter server بتشغيل 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)

لاحظ أنك ستحتاج إلى تكوين متغير بيئة TF_CONFIG إذا كنت تستخدم TFConfigClusterResolver . إنه مشابه لـ TF_CONFIG في MultiWorkerMirroredStrategy ولكن لديه محاذير إضافية.

في TF 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() واستخدام هذه الإستراتيجية لتقليل التدرجات - ستعيد دائمًا كائن إستراتيجية يمكننا من خلاله استدعاء تقليل 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 default strategy
  strategy = tf.distribute.get_strategy() 

with strategy.scope():
  # do something interesting
  print(tf.Variable(1.))
<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 مع tf.keras.Model.fit

tf.distribute.Strategy ودمجها tf.keras وهو تنفيذ TensorFlow للل مواصفات API Keras . tf.keras عبارة عن واجهة برمجة تطبيقات عالية المستوى لبناء النماذج وتدريبها. من خلال الدمج في الواجهة الخلفية لـ tf.keras ، جعلنا توزيع تدريبك المكتوب في إطار عمل تدريب model.fit باستخدام model.fit .

إليك ما تحتاج إلى تغييره في التعليمات البرمجية الخاصة بك:

  1. قم بإنشاء مثيل لـ tf.distribute.Strategy .
  2. حرك عملية إنشاء نموذج Keras والمحسن والمقاييس داخل نطاق strategy.scope .

نحن ندعم جميع أنواع نماذج Keras - المتسلسلة والوظيفية والمصنفة.

فيما يلي مقتطف من التعليمات البرمجية للقيام بذلك لنموذج Keras بسيط للغاية بطبقة واحدة كثيفة:

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',).
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: 0.9810
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.4336
10/10 [==============================] - 1s 2ms/step - loss: 0.2299

0.22988776862621307

هناtf.data.Dataset يوفر التدريب ومدخلات التقييم. يمكنك أيضًا استخدام المصفوفات المعقدة:

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
10/10 [==============================] - 1s 2ms/step - loss: 0.1636
Epoch 2/2
10/10 [==============================] - 0s 2ms/step - loss: 0.0723

<tensorflow.python.keras.callbacks.History at 0x7f89057a2470>

في كلتا الحالتين (مجموعة البيانات أو numpy) ، يتم تقسيم كل دفعة من الإدخال المحدد بالتساوي بين النسخ المتماثلة المتعددة. على سبيل المثال ، إذا كنت تستخدم MirroredStrategy مع MirroredStrategy GPU ، فسيتم تقسيم كل دفعة بحجم 10 بين وحدتي GPU ، مع تلقي كل منها 5 أمثلة على الإدخال في كل خطوة. ستتدرب كل فترة بعد ذلك بشكل أسرع كلما أضفت المزيد من وحدات معالجة الرسومات. عادة ، قد ترغب في زيادة حجم الدفعة الخاصة بك مع إضافة المزيد من المسرعات للاستفادة الفعالة من قوة الحوسبة الإضافية. ستحتاج أيضًا إلى إعادة ضبط معدل التعلم الخاص بك ، اعتمادًا على النموذج. يمكنك استخدام strategy.num_replicas_in_sync للحصول على عدد النسخ المتماثلة.

# Compute global batch size using 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 التدريب استراتيجية TPUS الإستراتيجية MultiWorkerMirroredStrategy ParameterServerStrategy إستراتيجية CentralStorage
واجهات برمجة تطبيقات Keras أيد أيد دعم تجريبي دعم تجريبي دعم تجريبي

أمثلة وبرامج تعليمية

فيما يلي قائمة بالبرامج التعليمية والأمثلة التي توضح التكامل أعلاه مع Keras:

  1. البرنامج التعليمي لتدريب MNIST مع MirroredStrategy .
  2. برنامج تعليمي لتدريب MNIST باستخدام MultiWorkerMirroredStrategy .
  3. دليل لتدريب MNIST باستخدام TPUStrategy .
  4. برنامج تعليمي لتدريب خادم المعلمات في TensorFlow 2 مع ParameterServerStrategy .
  5. مستودع 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)

ثم حدد خطوة واحدة من التدريب. استخدمtf.GradientTape لحساب التدرجاتtf.GradientTape لتطبيق تلك التدرجات لتحديث متغيرات نموذجنا. لتوزيع خطوة التدريب هذه ، ضعها في دالة train_step وقم tf.distrbute.Strategy.run إلى tf.distrbute.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 لخطوة التدريب ، يمكننا التكرار عبر dist_dataset وتشغيل التدريب في حلقة:

for dist_inputs in dist_dataset:
  print(distributed_train_step(dist_inputs))
tf.Tensor(0.88850546, shape=(), dtype=float32)
tf.Tensor(0.8815902, shape=(), dtype=float32)
tf.Tensor(0.87474185, shape=(), dtype=float32)
tf.Tensor(0.8679599, shape=(), dtype=float32)
tf.Tensor(0.86124384, shape=(), dtype=float32)
tf.Tensor(0.8545932, shape=(), dtype=float32)
tf.Tensor(0.8480073, shape=(), dtype=float32)
tf.Tensor(0.8414857, shape=(), dtype=float32)
tf.Tensor(0.8350279, shape=(), dtype=float32)
tf.Tensor(0.8286335, shape=(), dtype=float32)
tf.Tensor(0.8223018, shape=(), dtype=float32)
tf.Tensor(0.81603223, shape=(), dtype=float32)
tf.Tensor(0.8098244, shape=(), dtype=float32)
tf.Tensor(0.8036777, shape=(), dtype=float32)
tf.Tensor(0.7975916, shape=(), dtype=float32)
tf.Tensor(0.79156566, shape=(), dtype=float32)
tf.Tensor(0.78559923, shape=(), dtype=float32)
tf.Tensor(0.77969193, shape=(), dtype=float32)
tf.Tensor(0.773843, shape=(), dtype=float32)
tf.Tensor(0.7680521, shape=(), dtype=float32)

في المثال أعلاه ، قمت dist_dataset عبر dist_dataset لتقديم مدخلات إلى dist_dataset . نوفر أيضًا tf.distribute.Strategy.make_experimental_numpy_dataset لدعم المدخلات غير الدقيقة. يمكنك استخدام واجهة برمجة التطبيقات هذه لإنشاء مجموعة بيانات قبل استدعاء tf.distribute.Strategy.experimental_distribute_dataset .

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

iterator = iter(dist_dataset)
for _ in range(10):
  print(distributed_train_step(next(iterator)))
tf.Tensor(0.7623187, shape=(), dtype=float32)
tf.Tensor(0.7566423, shape=(), dtype=float32)
tf.Tensor(0.7510221, shape=(), dtype=float32)
tf.Tensor(0.7454578, shape=(), dtype=float32)
tf.Tensor(0.739949, shape=(), dtype=float32)
tf.Tensor(0.7344949, shape=(), dtype=float32)
tf.Tensor(0.72909516, shape=(), dtype=float32)
tf.Tensor(0.7237492, shape=(), dtype=float32)
tf.Tensor(0.7184567, shape=(), dtype=float32)
tf.Tensor(0.7132167, shape=(), dtype=float32)

يغطي هذا أبسط حالة لاستخدام tf.distribute.Strategy API لتوزيع حلقات تدريب مخصصة.

ما الذي يتم دعمه الآن؟

API التدريب استراتيجية TPUS الإستراتيجية MultiWorkerMirroredStrategy ParameterServerStrategy إستراتيجية CentralStorage
حلقة تدريب مخصصة أيد أيد دعم تجريبي دعم تجريبي دعم تجريبي

أمثلة وبرامج تعليمية

فيما يلي بعض الأمثلة لاستخدام استراتيجية التوزيع مع حلقات تدريب مخصصة:

  1. البرنامج التعليمي لتدريب MNIST باستخدام MirroredStrategy .
  2. دليل لتدريب MNIST باستخدام TPUStrategy .
  3. مستودع TensorFlow Model Garden الذي يحتوي على مجموعات من أحدث النماذج المنفذة باستخدام استراتيجيات مختلفة.

موضوعات أخرى

يغطي هذا القسم بعض الموضوعات ذات الصلة بحالات الاستخدام المتعددة.

إعداد متغير بيئة TF_CONFIG

للتدريب متعدد العمال ، كما ذكرنا سابقًا ، تحتاج إلى تعيين متغير بيئة TF_CONFIG لكل ثنائي يعمل في المجموعة الخاصة بك. متغير البيئة TF_CONFIG هو سلسلة JSON التي تحدد المهام التي تشكل الكتلة وعناوينها ودور كل مهمة في المجموعة. يوفر tensorflow / repo للنظام الإيكولوجي نموذجًا Kubernetes يحدد فيه TF_CONFIG لمهام التدريب الخاصة بك.

هناك نوعان من مكونات TF_CONFIG: الكتلة والمهمة. توفر الكتلة معلومات حول مجموعة التدريب ، وهي عبارة عن إملاء يتكون من أنواع مختلفة من الوظائف مثل العامل. في التدريب متعدد العمال ، عادة ما يكون هناك عامل واحد يتحمل مسؤولية أكبر قليلاً مثل حفظ نقطة التفتيش وكتابة ملف ملخص لـ TensorBoard بالإضافة إلى ما يفعله العامل العادي. يُشار إلى هذا العامل باسم "العامل الرئيسي" ، ومن المعتاد أن يتم تعيين العامل ذي المؤشر 0 باعتباره العامل الرئيسي (في الواقع ، هذه هي الطريقة التي يتم بها تنفيذ استراتيجية التوزيع). المهمة من ناحية أخرى توفر معلومات عن المهمة الحالية. مجموعة المكونات الأولى هي نفسها لجميع العمال ، ومهمة المكون الثاني مختلفة لكل عامل وتحدد نوع وفهرس ذلك العامل.

أحد الأمثلة على 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 هذا وجود ثلاثة عمال TF_CONFIG ps في المجموعة مع مضيفيهم TF_CONFIG . جزء "المهمة" يحدد دور المهمة الحالية في الكتلة ، العامل 1 (العامل الثاني). الأدوار الصالحة في الكتلة هي "رئيس" و "عامل" و "ps" و "مقيِّم". يجب ألا تكون هناك وظيفة "ps" إلا عند استخدام tf.distribute.experimental.ParameterServerStrategy .

ماذا بعد؟

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