در سمپوزیوم زنان در ML در 7 دسامبر شرکت کنید هم اکنون ثبت نام کنید

آموزش توزیع شده با TensorFlow

با مجموعه‌ها، منظم بمانید ذخیره و دسته‌بندی محتوا براساس اولویت‌های شما.

مشاهده در TensorFlow.org در Google Colab اجرا شود مشاهده منبع در GitHub دانلود دفترچه یادداشت

بررسی اجمالی

tf.distribute.Strategy یک API TensorFlow برای توزیع آموزش در چندین GPU، چندین ماشین یا TPU است. با استفاده از این 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 برای آگاهی از استراتژی تغییر کرده اند. این شامل متغیرها، لایه‌ها، مدل‌ها، بهینه‌سازها، معیارها، خلاصه‌ها و نقاط بازرسی است.

در این راهنما با انواع استراتژی ها و نحوه استفاده از آنها در موقعیت های مختلف آشنا خواهید شد. برای یادگیری نحوه اشکال زدایی مشکلات عملکرد، راهنمای عملکرد GPU Optimize TensorFlow را بررسی کنید.

TensorFlow را تنظیم کنید

import tensorflow as tf

انواع استراتژی ها

tf.distribute.Strategy در نظر دارد تعدادی از موارد استفاده را در محورهای مختلف پوشش دهد. برخی از این ترکیب ها در حال حاضر پشتیبانی می شوند و برخی دیگر در آینده اضافه خواهند شد. برخی از این محورها عبارتند از:

  • آموزش همزمان در مقابل آموزش ناهمزمان: این دو روش رایج برای توزیع آموزش با موازی سازی داده ها هستند. در آموزش همگام‌سازی، همه کارگران بر روی بخش‌های مختلف داده ورودی به صورت همگام‌سازی شده و شیب‌ها را در هر مرحله جمع‌آوری می‌کنند. در آموزش ناهمگام، همه کارگران به طور مستقل روی داده های ورودی آموزش می بینند و متغیرها را به طور ناهمزمان به روز می کنند. معمولاً آموزش همگام‌سازی از طریق معماری سرور پارامتری از طریق all-reduce و async پشتیبانی می‌شود.
  • پلتفرم سخت افزاری: ممکن است بخواهید آموزش خود را بر روی چندین GPU در یک ماشین، یا چندین ماشین در یک شبکه (هر کدام 0 یا چند GPU) یا در Cloud TPU مقیاس کنید.

به منظور پشتیبانی از این موارد استفاده، TensorFlow دارای MirroredStrategy ، TPUStrategy ، MultiWorkerMirroredStrategy ، ParameterServerStrategy ، CentralStorageStrategy و همچنین سایر استراتژی‌های موجود است. بخش بعدی توضیح می‌دهد که کدام یک از اینها در کدام سناریوها در TensorFlow پشتیبانی می‌شوند. در اینجا یک مرور سریع وجود دارد:

API آموزشی MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy CentralStorageStrategy ParameterServerStrategy
Keras Model.fit پشتیبانی پشتیبانی پشتیبانی پشتیبانی تجربی پشتیبانی تجربی
حلقه آموزشی سفارشی پشتیبانی پشتیبانی پشتیبانی پشتیبانی تجربی پشتیبانی تجربی
تخمینگر API پشتیبانی محدود پشتیبانی نشده پشتیبانی محدود پشتیبانی محدود پشتیبانی محدود

Mirrored Strategy

tf.distribute.MirroredStrategy از آموزش های همزمان توزیع شده در چندین GPU در یک دستگاه پشتیبانی می کند. در هر دستگاه GPU یک ماکت ایجاد می کند. هر متغیر در مدل در تمام کپی ها منعکس می شود. این متغیرها با هم یک متغیر مفهومی واحد به نام MirroredVariable را تشکیل می دهند. این متغیرها با اعمال به روز رسانی های یکسان با یکدیگر هماهنگ می شوند.

الگوریتم های کارآمد همه کاهش برای ارتباط به روز رسانی متغیر در سراسر دستگاه استفاده می شود. کاهش همه جانبه تانسورها را در همه دستگاه‌ها با جمع کردن آنها جمع می‌کند و آنها را در هر دستگاه در دسترس قرار می‌دهد. این یک الگوریتم ذوب شده است که بسیار کارآمد است و می تواند هزینه های همگام سازی را به میزان قابل توجهی کاهش دهد. بسته به نوع ارتباط موجود بین دستگاه‌ها، الگوریتم‌ها و پیاده‌سازی‌های تمام کاهشی زیادی وجود دارد. به طور پیش فرض، از NVIDIA Collective Communication Library ( NCCL ) به عنوان پیاده سازی همه جانبه استفاده می کند. می‌توانید از میان چند گزینه دیگر انتخاب کنید یا خودتان بنویسید.

در اینجا ساده ترین راه ایجاد MirroredStrategy است:

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

این یک نمونه MirroredStrategy ایجاد می کند که از تمام GPUهایی که برای TensorFlow و NCCL قابل مشاهده هستند به عنوان ارتباط بین دستگاهی استفاده می کند.

اگر می خواهید فقط از برخی از GPU های دستگاه خود استفاده کنید، می توانید این کار را به صورت زیر انجام دهید:

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',)

TPUStrategy

tf.distribute.TPUStrategy به شما امکان می دهد آموزش TensorFlow خود را روی واحدهای پردازش تانسور (TPU) اجرا کنید. TPU ها ASIC های تخصصی گوگل هستند که برای تسریع چشمگیر بارهای کاری یادگیری ماشین طراحی شده اند. آنها در Google Colab ، TPU Research Cloud و Cloud TPU در دسترس هستند.

از نظر معماری آموزشی توزیع شده، TPUStrategy همان MirroredStrategy است — آموزش توزیع همزمان را پیاده سازی می کند. TPU ها اجرای خود را از همه کاهش کارآمد و سایر عملیات جمعی در چندین هسته 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 را به طور صریح در شروع برنامه مقداردهی کنید. قبل از استفاده از TPUها برای محاسبات، این مورد ضروری است. راه‌اندازی سیستم 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 است و از CPU و GPU پشتیبانی می کند. CommunicationImplementation.NCCL از NCCL استفاده می کند و عملکرد پیشرفته ای را در GPU ها ارائه می دهد اما از CPU پشتیبانی نمی کند. 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 را اجرا می 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 در دسترس است.

CentralStorageStrategy

tf.distribute.experimental.CentralStorageStrategy آموزش همزمان را نیز انجام می دهد. متغیرها آینه نمی شوند، در عوض روی CPU قرار می گیرند و عملیات در تمام GPU های محلی تکرار می شود. اگر تنها یک 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 ایجاد می کند که از تمام GPU ها و CPU قابل مشاهده استفاده می کند. به‌روزرسانی متغیرهای موجود در رونوشت‌ها قبل از اعمال به متغیرها جمع‌آوری می‌شود.

استراتژی های دیگر

علاوه بر استراتژی های فوق، دو استراتژی دیگر وجود دارد که ممکن است برای نمونه سازی و اشکال زدایی در هنگام استفاده از tf.distribute API مفید باشد.

استراتژی پیش فرض

استراتژی پیش فرض یک استراتژی توزیع است که زمانی وجود دارد که هیچ استراتژی توزیع صریحی در محدوده نباشد. این رابط 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 استفاده کنید و از آن استراتژی برای کاهش گرادیان‌ها استفاده کنید — همیشه یک شی استراتژی را برمی‌گرداند که در آن می‌توانید 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 . اگر کدی می خواهید که طوری رفتار کند که گویی استراتژی وجود ندارد، از استراتژی پیش فرض استفاده کنید.

تا به حال در مورد استراتژی های مختلف و اینکه چگونه می توانید آنها را نمونه برداری کنید، یاد گرفته اید. چند بخش بعدی روش های مختلفی را نشان می دهد که می توانید از آنها برای توزیع آموزش خود استفاده کنید.

با Keras Model.fit از tf.distribute.Strategy استفاده کنید

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 استفاده می‌کند، بنابراین می‌توانید آن را روی دستگاهی با چندین GPU اجرا کنید. strategy.scope() به Keras نشان می دهد که از کدام استراتژی برای توزیع آموزش استفاده کند. ایجاد مدل‌ها/بهینه‌سازها/متریک‌ها در این محدوده به شما امکان می‌دهد به جای متغیرهای معمولی، متغیرهای توزیع‌شده ایجاد کنید. هنگامی که این تنظیم شد، می توانید مدل خود را مانند حالت عادی مطابقت دهید. MirroredStrategy از تکرار آموزش مدل بر روی GPU های موجود، تجمیع گرادیان ها و موارد دیگر مراقبت می کند.

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 پردازنده گرافیکی استفاده می کنید، هر دسته با اندازه 10 بین 2 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 حاوی مجموعه‌ای از مدل‌های پیشرفته است که با استفاده از استراتژی‌های مختلف پیاده‌سازی شده‌اند.

از tf.distribute.Strategy با حلقه های آموزشی سفارشی استفاده کنید

همانطور که در بالا نشان داده شد، استفاده از tf.distribute.Strategy با Keras Model.fit نیاز به تغییر تنها چند خط از کد شما دارد. با کمی تلاش بیشتر، می توانید از tf.distribute.Strategy با حلقه های آموزشی سفارشی نیز استفاده کنید.

اگر به انعطاف‌پذیری و کنترل بیشتری بر روی حلقه‌های آموزشی خود نسبت به برآوردگر یا 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 در اختیار شما قرار داده شده است. می توانید از این 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 حاوی مجموعه‌ای از مدل‌های پیشرفته است که با استفاده از استراتژی‌های مختلف پیاده‌سازی شده‌اند.

موضوعات دیگر

این بخش برخی از موضوعات مرتبط با موارد استفاده چندگانه را پوشش می دهد.

تنظیم متغیر محیطی 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 ارائه دهید.