Training Optimization2018متوسط10 دقيقة قراءة
التدريب بالدقة المختلطة
Mixed Precision Training
Micikevicius, P. · Narang, S. · Alben, J. · Diamos, G. · Elsen, E. · Garcia, D. · Ginsburg, B. · Houston, M. · Kuchaiev, O. · Venkatesh, G. · Wu, H. — ICLR
المشكلة
الشبكات العصبية العميقة تكبر بلا توقف — طبقات أكثر، ومعاملات أكثر، وبيانات أضخم. هذه الشبكات بصيغة الأعداد العائمة 32 بت (FP32) يستهلك موارد هائلة: كل وزن وتنشيط وتدرُّج يشغل 4 بايت من ذاكرة GPU، والحسابات بهذه الدقة أبطأ مما نحتاج. المعالجات الرسومية قادرة على تنفيذ حسابات (FP16) أسرع بـ 2 إلى 8 مرات، لكنّ المشكلة أن FP16 يغطّي نطاقاً ديناميكياً أضيق بكثير: أي قيمة تقلّ عن 2⁻²⁴ تُعامَل كصفر، والتحديثات الدقيقة على التدرُّجات تختفي. لو حوّلت كل شيء إلى FP16 مباشرةً، سينهار تدريب النموذج.
الإسهام
ثلاث تقنيات تسمح بالتدريب بصيغة FP16 دون التضحية بالدقة. الأولى: الاحتفاظ بنسخة رئيسية من الأوزان بدقة FP32 الكاملة، واستخراج نسخة FP16 منها في كل خطوة تدريب — وبذلك تتراكم التحديثات الصغيرة بأمان في الدقة الكاملة. الثانية: ضرب قيمة الخسارة بثابت كبير قبل الانتشار الخلفي لدفع التدرُّجات الصغيرة إلى النطاق الذي يستطيع FP16 تمثيله، ثم إلغاء هذا التحجيم قبل تحديث الأوزان. الثالثة: تجميع النواتج الجزئية لعمليات في مُجمِّع FP32 قبل كتابتها — وهو ما تفعله تلقائياً. المحصلة: انخفاض الذاكرة إلى النصف تقريباً وتسريع التدريب 2–3 مرات دون تغيير أي معامل.
الأثر
أصبح الممارسة المعيارية لتدريب النماذج الكبيرة. تبنّته جميع الأطر الرئيسية — PyTorch AMP وTensorFlow mixed precision وDeepSpeed. بدون هذه التقنية، كان تدريب نماذج بمليارات المعاملات كـ GPT-3 سيتطلّب ضعف الذاكرة والوقت تقريباً، وكانت ثورة التوسّع ستكلّف أضعافاً مضاعفة. هذه الورقة هي التي فتحت الباب أمام Megatron-LM وZeRO وكامل منظومة النماذج الضخمة التي نعرفها اليوم.
تخيّل فريقاً هندسياً يبني ناطحة سحاب. كبيرة المهندسين تحتفظ بمخطط رئيسي عالي الدقة (أوزان FP32 الرئيسية). كل صباح تسلّم طاقم البناء نسخة مبسّطة من هذا المخطط (نسخة FP16) — تكفي لقصّ الحديد وصبّ الخرسانة طوال اليوم. في نهاية اليوم يُبلّغها الفريق بالتعديلات الصغيرة التي استجدّت، فتنقلها بدقة إلى مخططها الأصلي الذي تسمح شبكته الدقيقة بوضع كل تفصيلة في موضعها الصحيح.
بدون هذا المخطط الأصلي، ستتراكم أخطاء التقريب يوماً بعد يوم — ملّيمترات تتحوّل إلى أمتار والمبنى كلّه ينحرف. أما بوجوده، فالطاقم يعمل بضعف السرعة وبنصف الورق، والبرج النهائي لا يمكن تمييزه عن برجٍ بُني بالكامل بمخططات عالية الدقة.
المشكلة: دقة FP32 ممتازة لكن ثمنها باهظ
في التدريب المعياري تُخزَّن كل والتنشيطات و بصيغة أعداد عائمة 32 بت، أي 4 بايت لكل رقم. نموذج بمئة مليون معامل يحتاج 400 ميغابايت لأوزانه فقط — ثم تأتي التنشيطات المحفوظة لمرحلة فتُضاعِف هذه التكلفة بحسب وعدد طبقات الشبكة.
المعالجات الرسومية الحديثة توفّر مساراً أسرع بكثير: حسابات نصف الدقة (FP16) تعمل أسرع بـ 2 إلى 8 مرات وتستهلك نصف الذاكرة. المشكلة أن FP16 لا يحمل سوى 10 بتات للجزء الكسري (مقابل 23 في FP32) و أضيق بكثير — أي قيمة أقل من نحو 6×10⁻⁸ تنهار إلى صفر. التحويل الأعمى إلى FP16 يُسبّب مشكلتين أساسيتين:
- تلاشي التحديثات: حين نضرب تدرُّج وزنٍ ما في صغير، تقع النتيجة غالباً تحت أصغر قيمة يستطيع FP16 تمثيلها فتُقرَّب إلى صفر. نحو 5% من قيم التدرُّجات في النماذج النموذجية تقع في هذه المنطقة الخطرة.
- ابتلاع الجمع: حتى لو كان التدرُّج قابلاً للتمثيل، فإن جمعه مع وزن أكبر منه بـ 2048 مرة يُزيحه خارج الجزء الكسري ويُهمله تماماً — كأنك تُضيف سنتيمتراً واحداً إلى كيلومتر على مسطرة لا تقرأ إلا بالأمتار.
الوصفة: ثلاث تقنيات بلا أي خسارة في الدقة
تطرح الورقة ثلاث تقنيات تعمل معاً كشبكة أمان متعددة الطبقات: كل تقنية تلتقط الأخطاء التي تفلت من التقنيتين الأخريين، والمحصلة أنك تُجري معظم الحسابات بصيغة FP16 وتحصل على مكافئة لصيغة FP32.
تحجيم الخسارة: لماذا تتلاشى التدرُّجات في FP16
لُبّ المشكلة هو الفجوة بين المنطقة التي تعيش فيها قيم التدرُّجات وبين ما يستطيع FP16 تمثيله فعلاً. الورقة تعرض مدرّجاً تكرارياً لتدرُّجات التنشيط من كاشف كائنات SSD مُدرَّب بصيغة FP32: 67% من قيم التدرُّجات كانت أصفاراً تامة، والكثير من القيم المتبقية حملت أسساً في النطاق [−32, −20] — أي أقلّ بكثير من أصغر أسّ مُسوّى في FP16 وهو −14.
بدون تحجيم الخسارة، تُقرَّب هذه التدرُّجات الصغيرة المهمة إلى صفر ويفقد النموذج استقراره. لكن بعامل تحجيم بسيط مقداره 8 (يُزيح الأسس ثلاث خطوات للأعلى)، تنزلق التدرُّجات إلى المنطقة المثالية في FP16 ويُطابق التدريب نتائج FP32 تماماً.
كيف نختار عامل التحجيم؟ أبسط طريقة استخدام ثابت واحد — وجدت الورقة أن قيماً بين 8 و32,000 تعمل مع معظم الشبكات. الطريقة الأمتن هي : ابدأ بعامل كبير، وإن ظهر طفحان (قيمة لانهائية أو NaN) في التدرُّجات، تخطَّ تلك الخطوة وانصِّف العامل. إذا مرّت عدة خطوات متتالية بنجاح، ضاعفه مرة أخرى. بهذه الآلية يتكيّف العامل تلقائياً مع توزيع التدرُّجات دون أي ضبط يدوي.
توفير الذاكرة — من أين يأتي المكسب؟
سؤال يتكرّر كثيراً: إذا احتفظت بنسخة أوزان رئيسية FP32 وأضفت إليها نسخة FP16، ألن تستهلك ذاكرة أكثر؟ بالنسبة للأوزان وحدها، نعم — زيادة بنحو 50%. لكن الأوزان ليست سوى شريحة صغيرة من إجمالي ذاكرة التدريب. التكلفة الحقيقية تكمن في التنشيطات: مخرجات كل طبقة يجب حفظها لمرحلة الانتشار العكسي، ومع أحجام الدُّفعات الكبيرة تُقزِّم التنشيطاتُ الأوزانَ تماماً. بما أن التنشيطات وتدرُّجاتها أصبحت مخزّنة بصيغة FP16 — أي بايتان بدلاً من أربعة — ينخفض الاستهلاك الكلي بنحو 40–50%.
النتيجة العملية: إما أن تدرّب النموذج نفسه بوقت أقل، أو أن تُكبّر حجم الدُّفعة في الذاكرة المتاحة — وكلا الخيارين يُقصّر زمن التدريب الفعلي.
أيّ العمليات تبقى بصيغة FP32؟
ليست كل العمليات تتحمّل العمل بصيغة FP16 وحدها. تُصنّف الورقة حسابات الشبكة العصبية في ثلاث فئات وتُحدّد الدقة المناسبة لكل منها:
- الضرب النقطي (الالتفاف، وضرب المصفوفات في الطبقات كاملة الاتصال والتكرارية): الضرب يتم بصيغة FP16 والتجميع بصيغة FP32. نوى المصفوفات في معالجات Volta تفعل ذلك تلقائياً دون أي تكلفة في السرعة.
- العمليات التجميعية الكبيرة (إحصائيات تسوية الدُّفعات، ومجاميع softmax): تُحسب بصيغة FP32. هذه الطبقات مقيّدة أصلاً بسعة نقل الذاكرة لا بسرعة الحساب، فالدقة الحسابية لا تؤثر في سرعتها، ولا تزال تقرأ وتكتب مصفوفات FP16.
- العمليات النقطية (ReLU، والضرب عنصراً بعنصر، وإضافة الانحياز): كلتا الصيغتين تؤدّيان الغرض. هذه العمليات محدودة بالذاكرة، فصيغة FP16 تُنصّف تكلفة النطاق الترددي دون أي خطر على الدقة.
الدقة المختلطة في الشيفرة البرمجية
أطر العمل الحديثة حوّلت التدريب بالدقة المختلطة إلى إضافة من ثلاثة أسطر فقط. وحدة torch.cuda.amp في PyTorch توفّر أداتين أساسيتين: autocast الذي يختار تلقائياً بين FP16 وFP32 لكل عملية، وGradScaler الذي يتولّى تحجيم الخسارة الديناميكي. إليك النمط الأساسي:
مبسَّط لإظهار الفكرة — ليس التنفيذ الحقيقي.
import torch
from torch.cuda.amp import autocast, GradScaler
model = MyModel().cuda()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
scaler = GradScaler() # يتولّى تحجيم الخسارة الديناميكي
for inputs, targets in dataloader:
optimizer.zero_grad()
with autocast(): # تمريرة أمامية FP16، مع FP32 حيث يلزم
outputs = model(inputs)
loss = criterion(outputs, targets)
scaler.scale(loss).backward() # انتشار خلفي مُحجَّم بـ FP16
scaler.step(optimizer) # إلغاء التحجيم وتحديث أوزان FP32
scaler.update() # ضبط عامل التحجيم للخطوة التاليةالنتائج — لا خسارة في الدقة مهما اختلفت المهمة
اختبرت الورقة التدريب بالدقة المختلطة على ستة مجالات تطبيقية مختلفة. في كل حالة، طابقت الدقة المختلطة أداء FP32 أو تفوّقت عليه بهامش بسيط، وبنفس المعاملات تماماً:
- تصنيف الصور: AlexNet وVGG وGoogLeNet وInception v2/v3 وResNet-50 — جميعها حققت مكافئة لـ FP32 على مجموعة ILSVRC، دون الحاجة إلى تحجيم الخسارة.
- كشف الكائنات: Faster R-CNN وMultibox SSD. نموذج SSD انهار بدون تحجيم، لكنه طابق FP32 بعامل تحجيم بسيط مقداره 8.
- التعرّف على الكلام: نماذج DeepSpeech 2 بأحجام 115–215 مليون معامل. الدقة المختلطة حققت معدلات خطأ أفضل بنسبة 5–10%، ما يوحي بأن FP16 يعمل كمُنظِّم ضمني يحدّ من .
- الترجمة الآلية: نماذج LSTM بمعمارية – بثلاث وخمس طبقات. احتاجت تحجيم الخسارة لمطابقة FP32.
- نمذجة اللغة: bigLSTM بطبقات من 8192 وحدة على مجموعة بيانات المليار كلمة. انهار بدون تحجيم، لكن عاملاً بقيمة 128 أعاد الدقة كاملة.
- توليد الصور: DCGAN لتوليد وجوه بدقة 128×128. طابق جودة FP32 بلا تحجيم.
لماذا غيَّرت هذه التقنية كل شيء
بعد هذه الورقة تحوّل التدريب بالدقة المختلطة إلى مكوّن لا غنى عنه في أي خط تدريب. دمجه PyTorch في torch.cuda.amp، وأضافه TensorFlow عبر tf.keras.mixed_precision، ووفّرت مكتبة Apex من NVIDIA دعماً جاهزاً للمُتبنّين الأوائل. أنظمة مثل Megatron-LM وZeRO بُنيت من الأساس على طبقة الدقة المختلطة.
الأثر يتجاوز FP16: نمط مع التحجيم نفسه ينطبق على وFP8 وصيغ الدقة المنخفضة الأخرى التي تُشغّل أكبر النماذج اليوم. في كل مرة تسمع عن نموذج دُرِّب على آلاف المعالجات الرسومية، اعلم أن الدقة المختلطة تعمل تحت الغطاء.
2015
Gupta et al. — الفاصلة الثابتة 16 بت
أثبتوا إمكانية التدريب بفاصلة ثابتة 16 بت على مجموعات بيانات صغيرة (MNIST وCIFAR-10)، لكن الأسلوب لم يصمد عند الانتقال إلى شبكات CNN أو RNN كبيرة.
2018
التدريب بالدقة المختلطة (هذه الورقة)
أوزان رئيسية + تحجيم الخسارة + تجميع FP32. أول طريقة تُحقّق دقة مكافئة لـ FP32 عبر شبكات CNN وRNN وGAN وعدة مجالات دون أي تعديل في المعاملات.
2019
NVIDIA Apex وPyTorch AMP
الدمج على مستوى أطر العمل حوّل الدقة المختلطة إلى تعديل برمجي من ثلاثة أسطر، فأصبحت الممارسة المعيارية في التدريب.
2020
Megatron-LM وZeRO
أنظمة تدريب النماذج الضخمة اعتمدت الدقة المختلطة كطبقة أساسية، ما أتاح تدريب نماذج بمليارات المعاملات على عناقيد من المعالجات الرسومية.
2022
التدريب بصيغة FP8
النمط نفسه — أوزان رئيسية + تحجيم — امتدّ إلى أعداد عائمة 8 بت على معالجات NVIDIA Hopper، مُضاعفاً الإنتاجية مرة أخرى.
المرجعMicikevicius, Narang, Alben, Diamos, Elsen, Garcia, Ginsburg, Houston, Kuchaiev, Venkatesh, Wu. Mixed Precision Training. ICLR, 2018.
مصطلحات هذه الورقة
- التدريب بالدقة المختلطةMixed Precision Training
- الدقة العائمة بنظام 16 بتFP16
- تحجيم الخسارةLoss Scaling
- الأوزان الرئيسيةMaster Weights
- الطفح السفلي للتدرّجاتGradient Underflow
- نوى Tensor CoresTensor Cores
- نصف الدقةHalf-Precision
- النطاق الديناميكيDynamic Range