روز جامعه ML 9 نوامبر است! برای به روز رسانی از TensorFlow، JAX به ما بپیوندید، و بیشتر بیشتر بدانید

عملکرد TensorFlow GPU را با TensorFlow Profiler بهینه کنید

بررسی اجمالی

این راهنما به شما نشان می دهد که چگونه از TensorFlow Profiler با TensorBoard استفاده کنید تا اطلاعات بیشتری در مورد GPU های خود کسب کرده و حداکثر کارایی را داشته باشید ، و در صورت عدم استفاده از یک یا چند GPU خود اشکال زدایی کنید.

اگر در Profiler تازه وارد هستید:

بخاطر داشته باشید که محاسبه بارگیری در GPU ممکن است همیشه مفید نباشد ، به خصوص برای مدل های کوچک. به دلیل:

  • انتقال داده بین میزبان (CPU) و دستگاه (GPU) ؛ و
  • به دلیل تأخیر در هنگام راه اندازی هسته GPU توسط میزبان.

گردش کار بهینه سازی عملکرد

این راهنما به طور خلاصه نحوه اشکال زدایی از مشکلات عملکرد را با استفاده از یک GPU واحد ، سپس انتقال به یک میزبان با چندین GPU بیان می کند.

توصیه می شود مشکلات عملکرد را به ترتیب زیر رفع اشکال کنید:

  1. عملکرد را در یک GPU بهینه و اشکال زدایی کنید:
    1. بررسی کنید که خط لوله ورودی گلوگاه است.
    2. عملکرد یک پردازنده گرافیکی را اشکال زدایی کنید.
    3. فعال کردن دقت مخلوط (با fp16 (float16)) و به صورت اختیاری فعال XLA .
  2. عملکرد را در میزبان چند GPU بهینه و اشکال زدایی کنید.

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

به عنوان یک پایه برای گرفتن کد سازگار در GPU ها، این راهنما فرض شما در حال حاضر با استفاده از tf.function . Keras Model.compile و Model.fit از API استفاده tf.function به طور خودکار در زیر کاپوت. هنگام نوشتن یک حلقه آموزش سفارشی با tf.GradientTape ، به مراجعه عملکرد بهتر با tf.function در مورد نحوه فعال tf.function است.

در بخشهای بعدی روشهای پیشنهادی برای هر یک از سناریوهای بالا برای کمک به شناسایی و رفع گلوگاه های عملکرد مورد بحث قرار می گیرد.

1. بهینه سازی عملکرد در یک GPU

در یک حالت ایده آل ، برنامه شما باید از پردازنده گرافیکی بالا ، حداقل CPU (میزبان) به GPU (دستگاه) ارتباط داشته باشد و از خط لوله ورودی سربار نداشته باشد.

اولین گام در تجزیه و تحلیل عملکرد ، دریافت نمایه برای مدلی است که با یک GPU کار می کند.

TensorBoard است نیمرخ صفحه مرور کلی -که نشان می دهد یک دیدگاه سطح بالای چگونه مدل خود را در طول نمایه یک انجام اجرا توانید یک ایده از چه دور برنامه خود را از سناریو ایده آل فراهم می کند.

TensorFlow Profiler Overview Page

اعداد کلیدی برای توجه به صفحه مروری عبارتند از:

  1. چه مدت از زمان اجرای واقعی دستگاه است
  2. درصد عملکردهای نصب شده در دستگاه در مقابل میزبان
  3. چه تعداد دانه استفاده fp16

دستیابی به عملکرد مطلوب به معنای حداکثر رساندن این اعداد در هر سه حالت است. برای به دست آوردن درک عمیق از برنامه خود، شما نیاز به با نیمرخ TensorBoard آشنا بیننده اثری . بخشهای زیر برخی از الگوهای معمول مشاهده کننده ردیابی را نشان می دهد که باید هنگام تشخیص گلوگاه های عملکرد به دنبال آنها باشید.

در زیر تصویری از نمای ردیابی مدل در حال اجرا بر روی یک GPU است. از دامنه TensorFlow نام و TensorFlow عملیات بخش، شما می توانید قسمت های مختلف مدل مانند پاس رو به جلو، تابع از دست دادن، پاس رو به عقب / محاسبه شیب، و به روز رسانی وزن بهینه ساز شناسایی،. شما همچنین می توانید عملیات در حال اجرا بر روی GPU کنار هر جریان، که اشاره به CUDA جریان دارند. هر جریان برای کارهای خاص استفاده می شود. در این ردیابی، جریان # 118 استفاده می شود برای راه اندازی دانه محاسبه و دستگاه به دستگاه کپی. جریان # 119 برای میزبان-به-دستگاه کپی استفاده می شود و جریان # 120 برای دستگاه کپی میزبان.

ردیابی زیر ویژگی های مشترک یک مدل عملکردی را نشان می دهد.

image

به عنوان مثال، جدول زمانی GPU محاسبه (جریان # 118) به نظر می رسد "شلوغ" با تعداد کمی از شکاف. نسخههای حداقل از میزبان به دستگاه (جریان # 119) و از دستگاه به میزبان (جریان # 120)، و همچنین شکاف حداقل بین مراحل وجود ندارد. هنگامی که Profiler را برای برنامه خود اجرا می کنید ، ممکن است نتوانید این مشخصات ایده آل را در نمای ردیابی خود شناسایی کنید. بقیه این راهنما سناریوهای رایج و نحوه اصلاح آنها را پوشش می دهد.

1. خط لوله ورودی را اشکال زدایی کنید

اولین قدم در اشکال زدایی عملکرد GPU این است که تعیین کنید آیا برنامه شما ورودی است. ساده ترین راه برای کشف این است که استفاده از نیمرخ را تجزیه و تحلیل ورودی خط لوله ، در TensorBoard، فراهم می کند که یک نمای کلی از زمان صرف شده در خط لوله ورودی.

image

اگر خط لوله ورودی شما به طور قابل توجهی به زمان پله کمک کند ، می توانید اقدامات بالقوه زیر را انجام دهید:

  • شما می توانید با استفاده از tf.data خاص راهنمای به یاد بگیرند که چگونه برای اشکالزدایی خط لوله ورودی خود را.
  • روش سریع دیگر برای بررسی تنگنا بودن خط لوله ورودی ، استفاده از داده های ورودی به صورت تصادفی تولید شده است که نیازی به پردازش قبلی ندارد. در اینجا یک مثال است از استفاده از این تکنیک برای یک مدل RESNET. اگر خط لوله ورودی بهینه باشد ، باید عملکرد مشابهی را با داده های واقعی و با داده های تصادفی / مصنوعی تولید شده تجربه کنید. تنها هزینه سربار در مورد داده های مصنوعی به دلیل کپی داده های ورودی خواهد بود که مجدداً می تواند از پیش تنظیم و بهینه شود.

علاوه بر این، به مراجعه بهترین شیوه برای بهینه سازی خط لوله داده های ورودی .

2. عملکرد یک GPU را اشکال زدایی کنید

عوامل مختلفی وجود دارد که می تواند در استفاده کم از GPU موثر باشد. در زیر برخی از حالات معمولا مشاهده زمانی که به دنبال می بیننده اثری و راه حل های بالقوه است.

1. فاصله های بین مراحل را تجزیه و تحلیل کنید

یک مشاهده معمول وقتی برنامه شما به طور مطلوب اجرا نمی شود ، فاصله بین مراحل آموزش است. در تصویر نمای ردیابی در زیر ، فاصله زیادی بین مراحل 8 و 9 وجود دارد ، به این معنی که GPU در آن مدت بیکار است.

image

اگر بیننده ردیابی شما فاصله زیادی را بین مراحل نشان می دهد ، این می تواند نشان دهنده محدود بودن ورودی برنامه شما باشد. در این صورت اگر قبلاً این کار را نکرده اید ، باید به بخش قبلی در مورد اشکال زدایی خط لوله ورودی خود مراجعه کنید.

با این حال ، حتی با وجود یک خط لوله ورودی بهینه ، به دلیل اختلاف موضوع CPU ، باز هم می توانید بین پایان یک مرحله و شروع مرحله دیگر فاصله داشته باشید. tf.data استفاده می کند از موضوعات پس زمینه به parallelize پردازش خط لوله. این رشته ها ممکن است در فعالیت میزبان GPU که در ابتدای هر مرحله اتفاق می افتد ، مانند کپی کردن داده ها یا برنامه ریزی عملیات GPU ، تداخل ایجاد کنند.

اگر شما متوجه شکاف بزرگ در سمت میزبان، که برنامه این عملیات بر روی GPU، شما می توانید متغیر محیطی مجموعه TF_GPU_THREAD_MODE=gpu_private . این تضمین می کند که دانه GPU از موضوعات اختصاصی خود را راه اندازی، و پشت سر صف نیست tf.data کار.

شکاف بین مراحل همچنین می توانید با محاسبات متریک، تماس Keras یا عملیات در خارج از ایجاد شود tf.function که اجرا بر روی میزبان. این عملکردها به خوبی عملکردهای موجود در نمودار TensorFlow عملکرد خوبی ندارند. بعلاوه ، برخی از این عملکردها روی CPU کار می کنند و سنسورها را از GPU به عقب و جلو کپی می کنند.

اگر بعد از بهینه سازی خط لوله ورودی خود ، هنوز فاصله ای بین مراحل در نمایشگر ردیابی مشاهده کردید ، باید کد مدل را بین مراحل بررسی کنید و بررسی کنید که آیا غیرفعال کردن برگشت / اندازه گیری عملکرد را بهبود می بخشد. برخی از جزئیات این عملیات نیز در ردیاب ردیابی (هم دستگاه و هم سمت میزبان) وجود دارد. توصیه در این سناریو این است که هزینه بالای این عملیات را با اجرای آنها بعد از یک تعداد مرحله مشخص به جای هر مرحله ، از بین ببرید. هنگام استفاده از compile روش در tf.keras API، تنظیم experimental_steps_per_execution پرچم این به طور خودکار انجام می دهد. حلقه for آموزش سفارشی، استفاده از tf.while_loop .

2. استفاده بیشتر از دستگاه را بدست آورید

1. هسته های GPU کوچک و تأخیر در راه اندازی هسته میزبان

میزبان هسته هایی را برای کار با GPU تأیید می کند ، اما قبل از اجرای هسته در GPU ، یک تأخیر (حدود 20-40 میکروثانیه) وجود دارد. در یک حالت ایده آل ، میزبان به اندازه کافی هسته را بر روی GPU ایجاد می کند به طوری که GPU بیشتر وقت خود را صرف اجرای برنامه می کند ، نه اینکه برای میزبان هسته بیشتر از میزبان منتظر بماند.

نیمرخ را صفحه مرور کلی در TensorBoard نشان می دهد که چقدر زمان از GPU به دلیل انتظار بر روی میزبان به دانه راه اندازی بیکار بود. در تصویر زیر ، پردازنده گرافیکی تقریباً 10٪ از زمان انتظار برای راه اندازی هسته ها بیکار است.

image

بیننده اثری برای این نشان می دهد همان برنامه شکاف کوچک بین دانه که در آن میزبان دانه راه اندازی مشغول بر روی GPU است.

image

با راه اندازی بسیاری از عملیات کوچک در GPU (برای مثال مانند افزودن اسکالر) ، میزبان ممکن است با GPU همگام نشود. TensorFlow آمار ابزار در TensorBoard برای همان مشخصات نشان می دهد 126،224 عملیات مول گرفتن 2.77 ثانیه صورت گرفت. بنابراین ، هر هسته در حدود 21.9 میکرو ثانیه است که بسیار کوچک است (تقریباً همزمان با تأخیر راه اندازی) و به طور بالقوه می تواند منجر به تاخیرهای راه اندازی هسته میزبان شود.

image

اگر خود را ردیابی بیننده نشان می دهد بسیاری از شکاف کوچک بین عملیات بر روی GPU مانند تصویر بالا، شما می توانید:

  • حسگرهای کوچک را بهم متصل کنید و از اپلیکیشن های برداری شده استفاده کنید یا از اندازه دسته ای بزرگتری استفاده کنید تا هر هسته راه اندازی شده کار بیشتری انجام دهد ، که GPU را برای مدت طولانی تری مشغول خواهد کرد.
  • اطمینان حاصل کنید که شما با استفاده از tf.function برای ایجاد نمودار TensorFlow، به طوری که شما عملیات در یک حالت مشتاق خالص حال اجرا نیست. اگر شما با استفاده Model.fit (به عنوان یک حلقه آموزش سفارشی با مخالفت tf.GradientTape ، پس از آن) tf.keras.Model.compile به طور خودکار این کار را برای شما.
  • فیوز مغز با استفاده از XLA با tf.function(jit_compile=True) و یا خودکار خوشه. برای اطلاعات بیشتر، به فعال کردن دقت مخلوط و XLA بخش زیر به نحوه فعال کردن XLA به عملکرد بالاتر است. این ویژگی می تواند منجر به استفاده زیاد از دستگاه شود.
2. قرار دادن TensorFlow

نیمرخ صفحه مرور کلی نشان می دهد شما می دهد درصد از عملیات بر روی میزبان قرار داده شده در مقابل دستگاه (شما همچنین می توانید از قرار دادن عملیات خاص با نگاه کردن به منظور بررسی بیننده اثری مانند در تصویر زیر، شما می خواهید درصد از عملیات بر روی میزبان در مقایسه با دستگاه بسیار کوچک باشد.

image

در حالت ایده آل ، اکثر عملیات محاسباتی محاسبه شده باید روی پردازنده گرافیکی انجام شود.

برای پیدا کردن که دستگاه های عملیات و تانسورها در مدل های خود را به، مجموعه ای اختصاص داده tf.debugging.set_log_device_placement(True) به عنوان بیانیه اول برنامه خود را.

توجه داشته باشید که در برخی موارد، حتی اگر شما یک op به در یک دستگاه خاص، اجرای آن ممکن است به این بیماری نادیده گرفتن قرار داده شده است مشخص (به عنوان مثال: tf.unique ). حتی برای آموزش GPU تک، تعیین یک استراتژی توزیع، مانند tf.distribute.OneDeviceStrategy ، می توانید قرار دادن قطعی تر از عملیات بر روی دستگاه شما منجر به.

یک دلیل برای قرار دادن اکثر گزینه ها روی GPU جلوگیری از کپی بیش از حد حافظه بین میزبان و دستگاه است (انتظار می رود نسخه های حافظه برای داده های ورودی / خروجی مدل بین میزبان و دستگاه وجود داشته باشد). یک نمونه از کپی کردن بیش از حد در نظر ردیابی زیر در GPU نشان جریان # 167 # 168 و # 169.

image

این کپی ها اگر مانع از اجرای هسته های GPU شوند ، گاهی اوقات می توانند به عملکرد صدمه بزنند. حافظه کپی عملیات در اثری بیننده کسب اطلاعات بیشتر در مورد عملیات که منبع این تانسورها کپی، اما ممکن است همیشه آسان باشد به ارتباط با یک memCopy با عملیات. در این موارد ، بهتر است که به اپراتورهای اطراف نگاهی بیندازید تا بررسی کنید که آیا نسخه حافظه در هر مرحله در همان مکان اتفاق می افتد.

3. هسته های کارآمدتر در GPU ها

هنگامی که استفاده از GPU برنامه شما قابل قبول شد ، مرحله بعدی بررسی افزایش کارایی هسته های GPU با استفاده از هسته های Tensor یا ترکیب عملکردها است.

1. از هسته های تانسور استفاده کنید

مدرن NVIDIA® GPU ها تخصصی تانسور هسته که به طور قابل توجهی می تواند به بهبود عملکرد دانه واجد شرایط.

شما می توانید TensorBoard استفاده آمار هسته GPU به تجسم که دانه GPU به تانسور هسته واجد شرایط، و که دانه با استفاده از تانسور هسته. فعال کردن fp16 (نگاه کنید به فعال کردن بخش های مختلف دقت در زیر) یک راه برای عمومی ماتریس ضرب برنامه شما است (GEMM) دانه (OPS matmul) استفاده از تانسور هسته. دانه GPU استفاده از هسته تانسور موثر وقتی دقت FP16 است و ابعاد ورودی / خروجی تانسور توسط 8 یا 16 (برای بخش پذیر هستند int8 ).

برای دیگر توصیه های دقیق در مورد چگونگی ساخت مغز کارآمد برای GPU ها، اشاره به NVIDIA® یادگیری عمیق عملکرد راهنمای.

2. فیوزهای عملیاتی

استفاده از tf.function(jit_compile=True) به فیوز عملیات کوچکتر به شکل دانه بزرگتر منجر به عملکرد سود قابل توجهی. برای کسب اطلاعات بیشتر، به مراجعه XLA راهنمای.

3. دقت مخلوط و XLA را فعال کنید

بعد از دنبال کردن مراحل بالا ، فعال کردن دقت مختلط و XLA دو مرحله اختیاری است که می توانید برای بهبود عملکرد بیشتر انجام دهید. روش پیشنهادی این است که آنها را یک به یک فعال کنید و تأیید کنید که مزایای عملکرد مطابق انتظار است.

1. دقت مخلوط را فعال کنید

TensorFlow دقت مخلوط راهنمای نشان می دهد که چگونه به فعال fp16 دقت در GPU ها. فعال کردن AMP در NVIDIA® GPU ها به استفاده از تانسور هسته و تحقق تا 3X تند کلی زمانی که به استفاده از فقط در مقایسه fp32 (float32) با دقت در ولتا و معماری GPU های جدیدتر.

اطمینان حاصل کنید که ابعاد ماتریس / تنسور الزامات مربوط به فراخوانی هسته هایی را که از هسته های تنسور استفاده می کنند ، برآورده می کند. هنگامی که دقت fp16 است و ابعاد ورودی / خروجی بر 8 یا 16 قابل تقسیم هستند (برای int8) هسته های GPU از هسته های Tensor به طور کارآمد استفاده می کنند.

توجه داشته باشید که با استفاده از cuDNN v7.6.3 به بعد ، ابعاد پیچیدگی به طور خودکار در صورت لزوم برای استفاده از هسته های Tensor پر می شود.

دنبال بهترین شیوهها در زیر به حداکثر رساندن مزایای عملکرد fp16 دقت.

1. از هسته های بهینه fp16 استفاده کنید

با fp16 را فعال کنید، ضرب ماتریس برنامه خود را (GEMM) دانه، باید مربوط به استفاده از fp16 نسخه ای که با بهره گیری از هسته تانسور. با این حال، در برخی موارد، این اتفاق نمی افتد و شما افزایش سرعت انتظار می رود از فعال را تجربه نمی fp16 ، به عنوان برنامه خود را به جای می افتد به اجرای ناکارآمد.

image

هسته GPU صفحه آمار نشان می دهد که عملیات تانسور هسته واجد شرایط و دانه هستند در واقع با استفاده از کارآمد تانسور هسته. راهنمای NVIDIA® بر عملکرد یادگیری عمیق شامل پیشنهادات بیشتر در مورد چگونگی به اهرم تانسور هسته. علاوه بر این، مزایای استفاده از fp16 نیز در دانه که قبلا حافظه محدود شد نشان می دهد، به عنوان در حال حاضر عملیات خواهد شد نیمی از زمان می برد.

2. پوسته پوسته شدن در برابر مقیاس از دست دادن استاتیک

پوسته پوسته شدن دست دادن در هنگام استفاده از لازم است fp16 برای جلوگیری از سرریز به دلیل دقت پایین. دو نوع از دست دادن پوسته پوسته شدن، دینامیک و استاتیک، که هر دو با جزئیات بیشتر در توضیح وجود دارد راهنمای دقیق مخلوط . شما می توانید با استفاده از mixed_float16 سیاست به طور خودکار پوسته پوسته شدن دست دادن در بهینه ساز Keras را فعال کنید.

هنگام تلاش برای بهینه سازی عملکرد ، یادآوری این نکته ضروری است که مقیاس دهی از دست دادن پویا می تواند گزینه های شرطی اضافی را که روی میزبان اجرا می شوند ، معرفی کند و منجر به ایجاد شکافهایی شود که بین مراحل در نمایشگر ردیابی قابل مشاهده خواهد بود. از طرف دیگر ، مقیاس سازی از دست دادن استاتیک چنین هزینه های اضافه ای ندارد و می تواند از نظر عملکرد با گیرنده گزینه بهتری باشد که باید مقدار صحیح مقیاس کاهش استاتیک را تعیین کنید.

2. XLA را با tf.function (jit_compile = True) یا خوشه بندی خودکار فعال کنید

به عنوان آخرین مرحله برای دستیابی به بهترین عملکرد با یک پردازنده گرافیکی واحد ، می توانید XLA را امتحان کنید ، که عملکردها را ذوب می کند و منجر به استفاده بهتر از دستگاه و اثر حافظه کمتری می شود. برای جزئیات در مورد نحوه فعال XLA در برنامه خود را با tf.function(jit_compile=True) و یا خودکار خوشه بندی، به مراجعه XLA راهنمای.

شما می توانید سطح JIT جهانی به مجموعه ای -1 (خاموش)، 1 و یا 2 . سطح بالاتر تهاجمی تر است و ممکن است موازی کاری را کاهش داده و از حافظه بیشتری استفاده کند. مقدار آن را 1 اگر شما محدودیت حافظه است. توجه داشته باشید که XLA برای مدلهایی که دارای اشکال تانسور ورودی متغیر هستند عملکرد خوبی ندارد زیرا کامپایلر XLA مجبور است هر زمان که با اشکال جدیدی روبرو شد ، هسته را کامپایل کند.

2. عملکرد را روی میزبان چند GPU بهینه کنید

tf.distribute.MirroredStrategy API را می توان به آموزش مدل مقیاس از یک GPU به GPU های متعدد بر روی یک میزبان استفاده می شود. (برای کسب اطلاعات بیشتر در مورد نحوه انجام آموزش توزیع شده با TensorFlow، به مراجعه آموزش توزیع شده با TensorFlow ، استفاده از یک GPU و استفاده از TPU ها راهنماهای و آموزش توزیع شده با Keras آموزش.)

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

هنگامی که از آموزش با یک GPU واحد به چندین GPU در یک میزبان می روید ، در حالت ایده آل ، باید مقیاس بندی عملکرد را فقط با هزینه اضافی ارتباط گرادیان و افزایش استفاده از رشته میزبان تجربه کنید. به عنوان مثال ، اگر از 1 GPU به 2 GPU بروید ، سرعت دقیق 2 برابر نخواهید داشت.

نمای ردیابی زیر نمونه ای از هزینه اضافی ارتباطات هنگام آموزش روی چندین GPU را نشان می دهد. مقداری سربار وجود دارد که می تواند شیب ها را بهم پیوند دهد ، آنها را از طریق کپی ها متصل کرده و قبل از انجام به روزرسانی وزن ، آنها را تقسیم کند.

image

چک لیست زیر به شما کمک می کند تا هنگام بهینه سازی عملکرد در سناریوی چند GPU عملکرد بهتری داشته باشید:

  1. سعی کنید اندازه دسته را به حداکثر برسانید ، که منجر به استفاده بالاتر از دستگاه و کاهش هزینه های ارتباطات در چندین پردازنده گرافیکی می شود. با استفاده از ابزار profiler حافظه یک حس که چگونه نزدیک برنامه خود را به استفاده از حافظه اوج کمک می کند. توجه داشته باشید که اگرچه اندازه دسته بالاتر می تواند روی همگرایی تأثیر بگذارد ، اما این معمولاً با مزایای عملکرد غلبه دارد.
  2. هنگام انتقال از یک GPU به چندین GPU ، همان میزبان اکنون باید داده های ورودی بیشتری را پردازش کند. بنابراین ، بعد از (1) ، توصیه می شود عملکرد خط لوله ورودی را دوباره بررسی کنید و مطمئن شوید که گلوگاه نیست.
  3. جدول زمانی GPU را در نمای ردیابی برنامه خود برای هرگونه تماس غیرضروری AllReduce بررسی کنید ، زیرا این امر باعث همگام سازی تمام دستگاه ها می شود. به نظر ردیابی بالا نشان داده شده، AllReduce از طریق انجام NCCL هسته، و تنها یک پاسخ NCCL در هر GPU برای شیب در هر مرحله وجود دارد.
  4. بررسی عملیات غیرضروری کپی D2H ، H2D و D2D که می تواند به حداقل برسد.
  5. زمان مرحله را بررسی کنید تا مطمئن شوید هر نسخه همان کار را انجام می دهد. به عنوان مثال، می توان آن را اتفاق می افتد که یک GPU (معمولا، GPU0 ) oversubscribed است چون میزبان به اشتباه به پایان می رسد تا قرار دادن کار بیشتر بر روی آن.
  6. در آخر ، مرحله آموزش را در تمام پردازنده های گرافیکی موجود در نمای ردیابی خود بررسی کنید و از نظر عملکردهایی که به طور متوالی اجرا می شوند ، بررسی کنید. این معمولاً زمانی اتفاق می افتد که برنامه شما شامل وابستگی های کنترلی از یک GPU به GPU دیگر باشد. در گذشته رفع اشکال در عملکرد در این شرایط به صورت موردی حل شده است. اگر شما مشاهده این رفتار را در برنامه خود، پرونده یک مسئله گیتهاب با تصاویری از نظر ردیابی خود را.

1. شیب AllReduce را بهینه کنید

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

پس از محاسبه جلو و عقب از مدل ، شیب های محاسبه شده بر روی هر دستگاه باید جمع شده و کاهش یابد. این گرادیان AllReduce پس از محاسبه گرادیان در هر دستگاه اتفاق می افتد، و قبل از بهینه ساز به روز رسانی وزن مدل.

هر GPU اول الحاق شیب در سراسر لایه مدل، آنها ارتباط برقرار در سراسر GPU ها با استفاده از tf.distribute.CrossDeviceOps ( tf.distribute.NcclAllReduce به طور پیش فرض است)، و پس از آن شیب پس از کاهش در هر لایه را برمی گرداند.

بهینه ساز از این شیب های کاهش یافته برای به روزرسانی وزن مدل شما استفاده می کند. در حالت ایده آل ، این فرایند باید همزمان در همه پردازنده های گرافیکی اتفاق بیفتد تا از هزینه های اضافی جلوگیری کند.

زمان اجرای AllReduce باید تقریباً یکسان باشد:

(number of parameters * 4bytes)/ (communication bandwidth)

این محاسبه به عنوان یک بررسی سریع مفید است تا بفهمید عملکردی که هنگام اجرای یک کار آموزشی توزیع شده دارید همانطور که انتظار می رود ، است یا اینکه شما باید اشکال زدایی عملکرد بیشتری انجام دهید. شما می توانید تعداد پارامترها در مدل خود را از گرفتن Model.summary .

توجه داشته باشید که هر یک از پارامتر مدل 4 بایتی است از TensorFlow با استفاده از fp32 (float32) برای برقراری ارتباط شیب. حتی زمانی که شما fp16 را فعال کنید، NCCL AllReduce با بهره گیری fp32 پارامترها.

برای به دست آوردن مزایای مقیاس گذاری ، زمان کار باید در مقایسه با هزینه های اضافی بسیار بالاتر باشد. یکی از راه های دستیابی به این هدف استفاده از اندازه دسته بالاتر است زیرا اندازه دسته بر زمان گام تأثیر می گذارد ، اما بر سربار ارتباطی تأثیر نمی گذارد.

2. بحث رشته میزبان GPU

هنگام اجرای چندین GPU ، وظیفه CPU این است که با راه اندازی موثر هسته های GPU در دستگاه ها ، تمام دستگاه ها را مشغول کند.

با این حال ، هنگامی که بسیاری از عملیات مستقل وجود دارد که CPU می تواند بر روی یک GPU برنامه ریزی کند ، CPU می تواند تصمیم بگیرد که از بسیاری از رشته های میزبان خود استفاده کند تا یک GPU را مشغول نگه دارد ، و سپس هسته ها را بر روی یک GPU دیگر به ترتیب غیر قطعی راه اندازی کند . این می تواند باعث ایجاد انحراف یا پوسته پوسته شدن منفی شود ، که می تواند بر عملکرد تأثیر منفی بگذارد.

بیننده اثری زیر نشان می دهد سربار زمانی که CPU تلوتلو راه اندازی هسته GPU ناکارآمد، به عنوان GPU1 غیر فعال است و پس از آن شروع می شود در حال اجرا عملیات پس از GPU2 آغاز شده است.

image

دیدگاه اثری را نشان می دهد میزبان که میزبان در حال راه اندازی دانه در GPU2 قبل از راه اندازی آنها را در GPU1 (توجه داشته باشید که زیر tf_Compute* ارگانوفسفره ها نشان دهنده موضوعات CPU نمی شود).

image

اگر در نمای ردیابی برنامه خود این نوع حیرت انگیز هسته GPU را تجربه کرده اید ، اقدام پیشنهادی این است:

  • تنظیم متغیر محیطی TensorFlow TF_GPU_THREAD_MODE به gpu_private . این متغیر محیط به میزبان می گوید که رشته ها را برای GPU خصوصی نگه دارد.
  • به طور پیش فرض، TF_GPU_THREAD_MODE=gpu_private مجموعه تعدادی از موضوعات به 2 است که در اکثر موارد کافی. با این حال، آن عدد می تواند با تنظیم متغیر محیطی TensorFlow تغییر TF_GPU_THREAD_COUNT به شماره مورد نظر از موضوعات.