Gradient Accumulation
يجمع تراكم التدرجات التدرجات عبر عدة دفعات مصغّرة قبل تحديث الأوزان مرة واحدة، ما يحاكي استخدام دفعة أكبر عند محدودية ذاكرة GPU.
تجميع التدرجات تقنية تدريب تشغّل عدة دفعات صغيرة، تسمى الدفعات المصغرة، عبر المرور الأمامي والانتشار العكسي، وتجمع تدرجاتها، ثم تحدّث أوزان النموذج بعد ذلك فقط. ويقارب التحديث خطوة واحدة على دفعة بحجم مجموع الدفعات المصغرة، بينما لا يحتفظ GPU في أي وقت إلا بمواضع التنشيط الخاصة بدفعة مصغرة واحدة. ويتيح ذلك لجهاز محدود الذاكرة التدريب بحجم الدفعة الذي تتطلبه وصفة التدريب، دون خفض دقة الصورة أو تصغير النموذج. يساوي حجم الدفعة الفعلي حجم الدفعة المصغرة مضروبًا في عدد خطوات التجميع وعدد الأجهزة؛ لذا فإن تجميع دفعات من أربع صور على مدى ثماني خطوات باستخدام أربع وحدات GPU يعادل دفعة من 128 صورة.
آلية عمل تجميع التدرجات#
في PyTorch ومعظم الأطر الأخرى، تضيف كل دعوة إلى backward() تدرجات جديدة إلى تلك المخزنة مسبقًا في المعاملات بدلًا من استبدالها. ويستفيد التجميع من ذلك مباشرةً: نفّذ المرورين الأمامي والعكسي لكل دفعة مصغرة، واستدعِ المحسّن عند بلوغ العدد المحدد من الدفعات المصغرة، ثم امسح التدرجات وابدأ النافذة التالية:
تحسب معظم دوال الخسارة المتوسط على عينات الدفعة، لذا تُقسم خسارة كل دفعة مصغرة على عدد الخطوات لتحويل التدرجات المجمّعة إلى متوسط. وبهذا التحجيم، تنتج أربع دفعات مصغرة من ثماني عينات التدرج نفسه الذي تنتجه دفعة واحدة من 32 عينة:
import torch
from torch import nn
torch.manual_seed(0)
model = nn.Linear(16, 1)
x, y = torch.randn(32, 16), torch.randn(32, 1)
loss_fn = nn.MSELoss()
# Reference: one batch of 32 samples
loss_fn(model(x), y).backward()
batch_grad = model.weight.grad.clone()
model.zero_grad()
# Four micro-batches of 8: backward() adds into .grad, and dividing each loss by 4 turns the sum into a mean
steps = 4
for x_micro, y_micro in zip(x.chunk(steps), y.chunk(steps)):
(loss_fn(model(x_micro), y_micro) / steps).backward()
print("Matches the full-batch gradient:", torch.allclose(model.weight.grad, batch_grad, atol=1e-6))
print(f"Largest difference: {(model.weight.grad - batch_grad).abs().max():.1e}")يطبع Matches the full-batch gradient: True مع أكبر فرق مقداره 1.6e-07، وهو تقريب للفاصلة العائمة ناتج من جمع الأرقام نفسها بترتيب مختلف.
أوجه اختلاف التجميع عن الدفعة الكبيرة#
تصح المطابقة مع دوال الخسارة التي تحسب متوسط عينات مستقلة، لكنها لا تصح في ثلاث حالات شائعة:
- تطبيع الدفعة: يحسب المتوسط والتباين لكل دفعة مصغرة، لذا تكون إحصاءات أربع صور أكثر ضجيجًا من إحصاءات 128 صورة.
- التسلسلات متغيرة الطول: عندما يحسب نموذج لغوي متوسط خسارته على الرموز في كل دفعة مصغرة، تحصل الدفعات المصغرة التي تضم رموزًا قليلة على وزن مساوٍ للدفعات الأطول.
- قص التدرجات: يُطبّق مرة واحدة على التدرج المجمّع، مباشرةً قبل خطوة المحسّن؛ إذ يغيّر قص تدرج كل دفعة مصغرة على حدة النتيجة.
أصلحت Hugging Face وUnsloth اختلاف عدد الرموز في أكتوبر 2024 عند الضبط الدقيق لـنموذج اللغة الكبير (LLM)، بقسمة مجموع الخسارة على إجمالي عدد الرموز في نافذة التجميع كاملةً. ولا يحقق التجميع أي تسريع أيضًا: إذ تظل الشبكة تعالج العدد نفسه من العينات دفعة مصغرة تلو الأخرى، كما تستخدم الدفعات المصغرة الصغيرة GPU بكفاءة أقل. وفي التدريب الموزع، يوفر DistributedDataParallel في PyTorch سياق no_sync() يتخطى عملية جمع التدرجات الشاملة بين الأجهزة لكل دفعة مصغرة عدا الأخيرة، ما يقلل الاتصالات. وعادةً ما يتطلب حجم الدفعة الفعلي الأكبر معدل تعلم أعلى: فقد درّب باحثو Facebook نموذج ResNet-50 على ImageNet في ساعة واحدة باستخدام دفعات من 8,192 صورة على 256 وحدة GPU، وذلك بزيادة معدل التعلم خطيًا مع حجم الدفعة ورفعه تدريجيًا في مرحلة الإحماء.
تقنيات ذات صلة#
- نقاط تحقق التدرج: تعيد حساب مواضع التنشيط أثناء الانتشار العكسي بدلًا من تخزينها، موفرةً الذاكرة داخل كل دفعة مصغرة مقابل حوسبة إضافية.
- الدقة المختلطة: تخزن مواضع التنشيط بتنسيقات 16 بت، ما يتيح مساحة لدفعات مصغرة أكبر. ويعيد مقياس الخسارة تحجيم التدرجات مرة واحدة بعد الدفعة المصغرة الأخيرة.
- توازي خطوط المعالجة: يقسم كل دفعة إلى دفعات مصغرة تمر بمراحل النموذج على وحدات GPU مختلفة، ويجمع تدرجاتها قبل خطوة واحدة للمحسّن.
يجمع تدريب Ultralytics YOLO26 التدرجات افتراضيًا: ففي وضع التدريب، يشغّل المدرّب المحسّن كل round(nbs / batch) دفعات؛ لذا فإن batch=16 الافتراضي وحجم الدفعة الاسمي nbs=64 يوفّران أربع دفعات لكل تحديث، بينما يوفّر batch=8 ثماني دفعات. ويرتفع العدد تدريجيًا من واحد أثناء الإحماء، ويُحجّم اضمحلال الأوزان وفق batch × accumulation / nbs، لذا تظل المعلمات الفائقة الافتراضية المعدّة لدفعة من 64 صورة مناسبة حتى على GPU لا يتسع إلا لعدد قليل من الصور في المرة الواحدة.










