أساسيات تعلم الآلة2017متوسط12 دقيقة قراءة

النزول التدريجي العشوائي بدفعات كبيرة ودقيقة: تدريب ImageNet في ساعة واحدة

Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour

Goyal, P. · Dollár, P. · Girshick, R. · Noordhuis, P. · Wesolowski, L. · Kyrola, A. · Tulloch, A. · Jia, Y. · He, K. — arXiv

المشكلة

كلما زادت البيانات وكبرت الشبكة تحسّنت النتائج، لكن وقت يطول معها. الحل الطبيعي هو : وزِّع كل دفعة على عدة وحدات معالجة رسومية لتعمل بالتوازي. المشكلة أن هذا يفرض تكبير الدفعة، وتكبيرها بلا ضوابط يُسبّب تشتُّت التدريب أو تراجع الدقة. في 2017 كان تدريب ResNet-50 على ImageNet يحتاج 29 ساعة على 8 وحدات معالجة رسومية، ولم يُثبت أحد أن التوسّع لمئات الوحدات ممكن دون التضحية بالدقة.

الإسهام

تقنيتان بسيطتان لكن أثرهما كبير، تسمحان بتكبير الدفعة إلى 8192 صورة دون خسارة في الدقة: (1) قاعدة القياس الخطي — إذا كبّرت الدفعة k مرة، كبِّر معدّل التعلّم k مرة، و(2) التدريجي — ابدأ بمعدّل تعلّم منخفض ثم ارفعه خطياً خلال أول 5 حقب. مع الحرص على إبقاء إحصاءات تسوية الدفعات محلية (32 عيّنة لكل عامل)، نجح تدريب ResNet-50 على 256 وحدة معالجة رسومية في ساعة واحدة فقط، بدقة top-1 مطابقة لخط الأساس الذي كان يحتاج 29 ساعة.

الأثر

هذه الورقة أسّست الوصفة التي يتبعها الجميع اليوم في التدريب الموزَّع بدفعات كبيرة. القياس الخطي لمعدّل التعلّم والإحماء التدريجي صارا خطوتين أساسيتين في كل تدريب واسع النطاق تقريباً — من BERT إلى GPT إلى محوِّلات الرؤية. أثبتت الورقة أن إضافة وحدات معالجة تُقلّص زمن التدريب خطياً دون المساس بجودة النموذج، وهذا ما فتح الباب لتدريب النماذج على مليارات الأمثلة. لاحقاً بنت مُحسِّنات LAMB وLARS على هذه الأفكار ودفعت حجم الدفعات لأرقام أكبر بكثير.

تخيّل فريقاً من الرسّامين يشتغلون على جدارية ضخمة. رسّام واحد يتقدّم ببطء لكن بثبات. أضِف 32 رسّاماً يعمل كلٌّ منهم على جزء، ثم ادمج أعمالهم في نهاية كل جولة — ستُنجَز اللوحة أسرع. لكن لو وضعت 256 رسّاماً دون خطة تنسيق، سيرسم كلٌّ منهم فوق حواف الآخر وتتحوّل الجدارية إلى فوضى.

ما تقدّمه هذه الورقة هو بروتوكول التنسيق: إذا ضاعفت عدد الرسّامين 32 مرة، ضاعِف أيضاً طول ضربة الفرشاة 32 مرة كي يبقى الأثر الكلّي لكل جولة كما هو. وفي الجولات الأولى — حين لا يزال الجميع يتعرّفون على مواقعهم — استخدم ضربات أقصر وأرفق قبل أن تنتقل إلى السرعة الكاملة.

المشكلة: الدُّفعات الأكبر تُعطِّل التدريب

تدريب شبكة عميقة يعني تكرار المرور على البيانات وتحديث الأوزان بعد كل . مع 8 وحدات معالجة رسومية و32 صورة لكل وحدة، تكون الدفعة 256 صورة ويحتاج تدريب ResNet-50 على ImageNet نحو 29 ساعة.

الفكرة المغرية واضحة: استخدم 256 وحدة (أكثر بـ 32 مرة)، وزِّع الدفعة بالتساوي، وأنهِ التدريب في ساعة واحدة تقريباً. كل وحدة تحسب على صورها الـ 32، ثم تتشارك جميع الوحدات تدرُّجاتها وتأخذ خطوة تحديث واحدة. هذا هو مبدأ المتزامن.

لكن لإبقاء كل وحدة مشغولة فعلاً، يجب أن يصل الكلّي إلى 8192 صورة. والمشكلة أن التدريب بدفعة بهذا الحجم دون ضوابط يُشتِّت دالة الخسارة أو يُسقط الدقة النهائية بنسبة 1–2%. في 2017 لم يكن واضحاً: هل هذه مشكلة تعميم جوهرية لا مفرّ منها، أم عقبة تحسينية يمكن تجاوزها؟

افتح في المختبر
شاهد كيف تُوزَّع الصور على وحدات المعالجة: كل وحدة تحسب تدرُّجاتها محلياً ثم تُجمَع النتائج عبر عملية allreduce.
تستيقظ التجربة عند وصولك…

الفكرة الأولى: قاعدة القياس الخطّي

الفكرة الأساسية أبسط مما تتوقع. تخيّل أنك في الوضع العادي تأخذ k خطوات صغيرة بمعدّل تعلّم η\eta، كل خطوة على دفعة مختلفة من nn صورة. الآن تريد أن تستبدلها بـخطوة واحدة كبيرة على knkn صورة مجتمعة. لكي تُعطي الخطوة الكبيرة نفس الأثر تقريباً، عليك ضبط على η^=kη\hat{\eta} = k\eta.

والسبب منطقي: بعد k خطوة صغيرة، يكون تحديث الأوزان الكلّي هو تراكم متوسطات التدرُّج من كل الخطوات. الخطوة الكبيرة تأخذ المتوسط على kn عيّنة دفعة واحدة. ما دامت التدرُّجات لا تتغيّر كثيراً بين خطوة وأخرى — أي l(x,wt)l(x,wt+j)\nabla l(x, w_t) \approx \nabla l(x, w_{t+j}) لقيم jj صغيرة — فإن ضرب معدّل التعلّم في kk يكفي لجعل الخطوة الكبيرة تُكافئ الخطوات الصغيرة المتراكمة.

هذا هو ما يُعرف بـقاعدة القياس الخطّي: كبِّر حجم الدُّفعة kk مرة، وكبِّر معدّل التعلّم kk مرة معه.

η^=kη\hat{\eta} = k \cdot \eta
قاعدة القياس الخطّي — أبسط وصفة للتدريب بدفعات كبيرةحين يكبر حجم الدفعة بمعامل k (مثلاً من 256 إلى 8192 فيكون k=32)، اضرب معدّل التعلّم الأساسي η في المعامل k نفسه.

تخيّلها كالمشي مقابل القفز: 32 خطوة قصيرة توصلك مسافة معيّنة. لو أردتَ الوصول لنفس النقطة بقفزة واحدة، يجب أن تكون أطول بـ 32 مرة. معدّل التعلُّم هو بالضبط طول هذه القفزة في عملية التحسين.

افتح في المختبر
اسحب شريط حجم الدفعة لترى كيف يتغيّر معدّل التعلّم خطياً، وقارن منحنيات التدريب الناتجة مع خط أساس الدفعة 256.
تستيقظ التجربة عند وصولك…

الفكرة الثانية: الإحماء التدريجي

قاعدة القياس الخطّي تفترض أن التدرُّجات لا تتغيّر كثيراً بين خطوة وأخرى. في بداية التدريب، هذا الافتراض لا يصمد إطلاقاً — الأوزان تتغيّر بعنف، والتدرُّج عند الخطوة tt يختلف جذرياً عنه عند t+1t+1.

لو بدأت مباشرة بـمعدّل تعلُّم η^=3.2\hat{\eta} = 3.2 (أي 32 ضعف المعدّل الأساسي)، التدريب ينهار من التكرار الأول. الحل؟ ابدأ بهدوء ثم ارفع تدريجياً.

الورقة جرّبت طريقتين:

  • الإحماء الثابت: استخدم η=0.1\eta = 0.1 لخمس حقب ثم اقفز فجأة إلى η^=3.2\hat{\eta} = 3.2. والنتيجة؟ الأداء ساء أكثر — القفزة المفاجئة رفعت خطأ التدريب بحدّة ولم يتعافَ النموذج منها أبداً.
  • الإحماء التدريجي: ابدأ من η=0.1\eta = 0.1 ثم ارفعه خطياً نحو η^=3.2\hat{\eta} = 3.2 على مدار 5 حقب. هذا نجح تماماً — منحنى التدريب طابق منحنى الدفعة الصغيرة بدقة عالية.
افتح في المختبر
قارن ثلاث استراتيجيات إحماء: بدون إحماء، وإحماء ثابت، وإحماء تدريجي. لاحظ تأثير كلٍّ منها على منحنى خطأ التدريب مقارنة بخط أساس الدفعة الصغيرة.
تستيقظ التجربة عند وصولك…

تسوية الدفعات: ارتباط خفيّ بحجم الدفعة

هناك نقطة دقيقة لكنها حاسمة. تحسب المتوسط والتباين عبر عيّنات الدفعة. معنى ذلك أن خسارة كل عيّنة مرتبطة ببقية العيّنات في دفعتها — وبالتالي دالة الخسارة نفسها تتغيّر حين يتغيّر حجم الدُّفعة.

الحل أنيق: أبقِ إحصاءات التسوية لكل وحدة معالجة ثابتة عند n=32n = 32 عيّنة، مهما كان العدد الكلي للوحدات. حتى لو كانت الدفعة الكلية 8192 صورة موزّعة على 256 وحدة، كل وحدة تحسب إحصاءات التسوية على صورها الـ 32 فقط. بهذا تبقى دالة الخسارة واحدة لا تتغيّر، وتتجنب تكلفة تبادل الإحصاءات بين الوحدات.

الورقة أظهرت أن حساب الإحصاءات على كامل الـ 8192 عيّنة يُغيّر دالة الخسارة فعلياً ويُضعف الدقة. الخلاصة: حجم دفعة التسوية معامل فائق يخصّ التسوية وحدها، لا التدريب الموزَّع.

افتح في المختبر
بدِّل بين التسوية المحلية (32 عيّنة لكل وحدة) والتسوية الشاملة (8192 عيّنة) وشاهد أثر ذلك على الإحصاءات ودالة الخسارة.
تستيقظ التجربة عند وصولك…

عثرات عملية: تفاصيل تُفسد التدريب

الورقة رصدت عدة أخطاء تنفيذية يسهل الوقوع فيها في التدريب الموزَّع:

لا يُعامَل كمعدّل التعلّم. دالة الخسارة تتضمن حدّ تنظيم λ2w2\frac{\lambda}{2}\|w\|^2. قسمة خسارة الإنتروبيا التقاطعية على حجم الدفعة الكلي لا يُغني عن ضبط معدّل التعلّم، لأن حدّ اضمحلال الأوزان يحتاج معالجة مستقلة. الخطأ هنا خبيث: النموذج يتدرّب ويبدو طبيعياً، لكن دقته أقل مما ينبغي ويصعب اكتشاف السبب.

تصحيح . هناك صيغتان شائعتان لـ بزخم. في الأولى، متجه التحديث uu مستقل عن η\eta. في الثانية، v=ηuv = \eta u، فيصبح مخزن الزَّخم مربوطاً بـمعدّل التعلُّم. حين يتغيّر η\eta أثناء الإحماء، تحتاج الصيغة الثانية معامل تصحيح ηt+1ηt\frac{\eta_{t+1}}{\eta_t} يُطبَّق على المخزن. بدون هذا التصحيح، الانتقال من الإحماء إلى المعدّل الكامل يُزعزع استقرار التدريب.

تسوية التدرُّجات. كل عامل يُسوّي تدرُّجاته بحجم دفعته المحلية nn، لكن عملية تَجمع التدرُّجات ولا تُتوسِّطها. لذلك يجب القسمة على حجم الدفعة الكلّي knkn وليس nn وحده. تجاهل هذه النقطة يعني أنك تستخدم معدّل تعلّم فعلياً مختلفاً عمّا تظنّه.

الوصفة في شيفرة برمجية

النزول التدريجي بدفعات كبيرة مع القياس الخطّي والإحماء التدريجيpython

مبسَّط لإظهار الفكرة — ليس التنفيذ الحقيقي.

import numpy as np

def get_lr(epoch, iteration, iters_per_epoch,
           base_lr=0.1, base_batch=256, actual_batch=8192,
           warmup_epochs=5):
    """جدول معدّل التعلّم: قياس خطّي + إحماء تدريجي."""
    k = actual_batch / base_batch          # معامل القياس (مثلاً 32)
    target_lr = base_lr * k                # قاعدة القياس الخطّي

    # إحماء تدريجي: ارفع خطياً من base_lr إلى target_lr
    warmup_iters = warmup_epochs * iters_per_epoch
    current_iter = epoch * iters_per_epoch + iteration
    if current_iter < warmup_iters:
        # استيفاء خطي من base_lr إلى target_lr
        alpha = current_iter / warmup_iters
        return base_lr + alpha * (target_lr - base_lr)

    # بعد الإحماء: تقليص معدّل التعلّم عند الحقب 30 و60 و80
    if epoch < 30:
        return target_lr
    elif epoch < 60:
        return target_lr * 0.1
    elif epoch < 80:
        return target_lr * 0.01
    else:
        return target_lr * 0.001

# تفصيل تنفيذي مهم: تسوية الدفعات لكل عامل تستخدم n=32 عيّنة.
# الدفعة الكلية k*n = 8192 لكن إحصاءات التسوية تبقى محلية.
# هذا يُبقي دالة الخسارة متطابقة بين أحجام الدفعات المختلفة.

النتائج: ساعة واحدة بنفس الدقة

النتائج واضحة ومقنعة. باستخدام قاعدة القياس الخطّي والإحماء التدريجي، حقّق ResNet-50 المُدرَّب بدفعة 8192 صورة خطأ top-1 بنسبة 23.74% — مقابل 23.60% لخط الأساس بدفعة 256 صورة. الفارق 0.14% فحسب، وهو ضمن هامش التذبذب العشوائي (±0.12%).

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

الورقة اختبرت أحجام دفعات تتراوح من 64 إلى 65,536. الدقة بقيت مستقرة حتى 8192، ثم بدأت بالتراجع عند 16 ألفاً وانهارت تماماً عند 64 ألفاً. النقطة المثلى لـ ImageNet مع ResNet-50 كانت حول 8 آلاف — وهو الحدّ الذي يبدأ بعده افتراض استقرار التدرُّجات بالتفكك حتى مع الإحماء.

افتح في المختبر
استكشف كيف يتغيّر خطأ التحقق مع حجم الدفعة. لاحظ الاستقرار حتى 8 آلاف ثم التدهور الحاد بعد ذلك.
تستيقظ التجربة عند وصولك…

هل ينجح خارج نطاق ImageNet؟

السؤال الحاسم: هل الخصائص التي تعلّمها النموذج بدفعات كبيرة تنتقل لمهام أخرى بنفس الكفاءة؟ لاختبار ذلك، درّب الباحثون ResNet-50 بأحجام دفعات مختلفة (من 256 إلى 16 ألفاً)، ثم استخدموا كل نموذج لتهيئة Mask R-CNN لاكتشاف الأجسام على مجموعة COCO.

النتيجة: ما دام خطأ التحقق على ImageNet منضبطاً (أحجام دفعات حتى 8 آلاف)، كانت دقة الاكتشاف على COCO مطابقة تماماً لخط أساس الدفعة الصغيرة — 35.8% دقة صندوق AP و33.9% دقة قناع AP بصرف النظر عن حجم الدفعة. لا فجوة تعميم حتى عند الانتقال بين مجموعتي بيانات مختلفتين ومهمتين مختلفتين معاً.

بل إن قاعدة القياس الخطّي نجحت أيضاً حين طُبِّقت مباشرة على تدريب Mask R-CNN نفسه من وحدة واحدة إلى 8 وحدات، مما يُؤكّد أن الفكرة ليست خاصة بالتصنيف وحده.

البنية التحتية: جعل 256 وحدة تعمل معاً

لا فائدة من الخوارزمية إذا صار التواصل بين الوحدات هو العائق. تصميم النظام في هذه الورقة حقّق كفاءة توسُّع تقارب 90% من 8 إلى 256 وحدة معالجة، باستخدام شبكة Ethernet عادية بسرعة 50 غيغابت — دون الحاجة لشبكات ربط متخصصة.

الحيلة الأساسية هي تداخل التواصل مع الحساب: أثناء ، بمجرّد حساب تدرُّجات طبقة ما، تُرسل فوراً لعملية allreduce بينما تُحسَب تدرُّجات الطبقة التالية. النتيجة أن معظم زمن التواصل يختبئ خلف حسابات مفيدة تجري بالتوازي.

لعملية allreduce ذاتها، استخدمت الورقة خوارزمية التنصيف والمضاعفة التكرارية (recursive halving-doubling)، وهي أسرع بـ 3 أضعاف من خوارزمية الحلقة المعتادة لأحجام مخازن التدرُّجات النموذجية، إذ تعمل في 2log2(p)2\log_2(p) خطوة بدلاً من 2(p1)2(p-1) حيث pp عدد الخوادم.

افتح في المختبر
شاهد كيف يتداخل حساب التدرُّجات مع تواصل allreduce أثناء الانتشار الخلفي لتحقيق تسارع شبه خطّي.
تستيقظ التجربة عند وصولك…

حيلة تهيئة معامل γ في تسوية الدفعات

تعديل صغير لكن أثره ملموس: في كل كتلة متبقية، يُهيَّأ معامل التقييس γ\gamma في آخر طبقة تسوية دُفعات بالقيمة 0 بدلاً من 1 المعتادة. عملياً، هذا يعني أن الكتلة المتبقية تبدأ صامتة تماماً — كل الإشارات تمرّ عبر وصلة التخطّي فقط كأن الكتلة غير موجودة. ومع تقدّم التدريب، ينمو γ\gamma تلقائياً ويبدأ الفرع المتبقي بالمساهمة شيئاً فشيئاً.

هذا التعديل حسّن الدقة لجميع أحجام الدفعات، لكن أثره كان الأوضح مع الدفعات الكبيرة: قلّص الفجوة من 0.51% (بالتهيئة المعتادة) إلى 0.14% فقط.

لماذا غيَّر كل شيء

  1. 2014

    Krizhevsky: حيلة غريبة واحدة

    أول اقتراح بقياس معدّل التعلّم خطياً مع حجم الدفعة للشبكات الالتفافية، لكن بخسارة دقة 1% عند الانتقال من دفعة 128 إلى 1024.

  2. 2017

    هذه الورقة — القياس الخطّي + الإحماء التدريجي

    أثبتت أن أحجام دفعات حتى 8192 ممكنة بلا خسارة في الدقة. درّبت ImageNet في ساعة واحدة على 256 وحدة معالجة. أصبحت الوصفة المعيارية للتدريب الموزَّع.

  3. 2017

    LARS — قياس المعدّل التكيّفي طبقةً بطبقة

    وسّع التدريب بدفعات كبيرة إلى حجم 32 ألفاً بقياس معدّل تعلّم كل طبقة على حدة بنسبة وزنها إلى تدرجها.

  4. 2019

    LAMB — لحظات تكيّفية طبقيّة للتدريب بدفعات

    جمع بين قياس LARS الطبقي ومُحسِّن Adam، ممكِّناً أحجام دفعات تصل إلى 64 ألفاً لتدريب BERT المسبق. قلّص وقت تدريب BERT من 3 أيام إلى 76 دقيقة.

  5. 2020

    التدريب بدفعات كبيرة يُشعل عصر التوسيع

    GPT-3 وDALL·E والنماذج اللاحقة كلها تعتمد على تقنيات الدفعات الكبيرة المنحدرة من هذه الورقة للتدريب بكفاءة على مئات وحدات المعالجة.

المرجعGoyal, Dollár, Girshick, Noordhuis, Wesolowski, Kyrola, Tulloch, Jia, He. Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour. arXiv, 2017.

مصطلحات هذه الورقة