Gradient Accumulation
Gradyan biriktirme, sınırlı GPU belleğiyle daha büyük bir toplu iş boyutunu taklit etmek için tek bir ağırlık güncellemesinden önce birkaç mikro toplu işin gradyanlarını toplar.
Gradyan biriktirme, mikro gruplar adı verilen birkaç küçük grubu ileri geçişten ve geri yayılımdan geçirip gradyanlarını toplar ve model ağırlıklarını ancak bundan sonra günceller. Bu güncelleme, tüm mikro grupların toplamı kadar büyük bir grup üzerinde atılacak tek bir adıma yaklaşırken GPU belleğinde yalnızca bir mikro grubun aktivasyonları bulunur. Belleği sınırlı bir aygıtın, görüntü çözünürlüğünü düşürmeden veya modeli küçültmeden tarifte belirtilen grup boyutuyla eğitim yapmasını sağlar. Etkin grup boyutu; mikro grup boyutunun biriktirme adımı sayısıyla ve aygıt sayısıyla çarpımına eşittir. Dolayısıyla 4 GPU'da 8 adım boyunca biriktirilen 4 görüntülük mikro gruplar, 128 görüntülük bir grup gibi davranır.
Gradyan Biriktirme Nasıl Çalışır#
PyTorch ve diğer birçok çerçevede, backward() öğesine yapılan her çağrı, parametrelerde zaten saklanan gradyanları değiştirmek yerine bunlara yenilerini ekler. Biriktirme doğrudan bundan yararlanır: her mikro grup için ileri ve geri geçişi çalıştır, belirlenen mikro grup sayısına ulaşıldığında eniyileyiciyi bir kez çağır, ardından gradyanları temizleyip sonraki pencereyi başlat:
Kayıp işlevlerinin çoğu, bir gruptaki örneklerin ortalamasını alır. Bu nedenle, toplanan gradyanların ortalamasını elde etmek için her mikro grubun kaybı adım sayısına bölünür. Bu ölçeklendirmeyle 8 örnekli dört mikro grup, 32 örnekli tek bir grupla aynı gradyanı üretir:
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}")En büyük fark 1.6e-07 olmak üzere Matches the full-batch gradient: True çıktısını verir; bu fark, aynı sayılar farklı sırada toplandığı için oluşan kayan nokta yuvarlama hatasından kaynaklanır.
Biriktirme, Büyük Bir Gruptan Nasıl Farklıdır?#
Eşdeğerlik, bağımsız örneklerin ortalamasını alan kayıplarda geçerlidir; ancak yaygın üç durumda bozulur:
- Grup normalleştirme: Ortalamasını ve varyansını her mikro grup üzerinde hesaplar; bu nedenle 4 görüntüden elde edilen istatistikler, 128 görüntüden elde edilenlerden daha gürültülüdür.
- Değişken uzunluklu diziler: Bir dil modeli kaybının ortalamasını her mikro gruptaki tokenlar üzerinden aldığında, az token içeren mikro gruplar uzun olanlarla aynı ağırlığı alır.
- Gradyan kırpma: Bir kez, eniyileyici adımından hemen önce biriktirilmiş gradyana uygulanmalıdır. Her mikro grubu ayrı ayrı kırpmak sonucu değiştirir.
Hugging Face ve Unsloth, büyük dil modeli (LLM) ince ayarında token sayısı uyuşmazlığını, Ekim 2024'te biriktirme penceresinin toplam token sayısına göre toplanmış kaybı bölerek giderdi. Biriktirme hız artışı da sağlamaz: aynı sayıda örnek, ağdan her seferinde bir mikro grup olarak geçer ve küçük mikro gruplar GPU'yu daha verimsiz kullanır. Dağıtık eğitimde, PyTorch'un DistributedDataParallel aracı, son mikro grup dışındakiler için gradyanları tüm cihazlarda birleştirme işlemini atlayan bir no_sync() bağlamı sunar; bu da iletişim maliyetini azaltır. Daha büyük bir etkin grup genellikle daha yüksek bir öğrenme oranı gerektirir: Facebook araştırmacıları, grup boyutuyla öğrenme oranını doğrusal biçimde ölçeklendirip bunu kademeli olarak ısıtarak, 256 GPU'da 8.192 görüntülük gruplarla ResNet-50'yi ImageNet üzerinde bir saatte eğitti.
İlgili Teknikler#
- Gradyan kontrol noktası belirleme: Bellekten tasarruf etmek için aktivasyonları depolamak yerine geri yayılım sırasında yeniden hesaplar; bunun karşılığında ek hesaplama gerektirir.
- Karma duyarlılık: Aktivasyonları 16 bitlik biçimlerde depolar; böylece daha büyük mikro gruplara yer açar. Kayıp ölçekleyicisi, son mikro gruptan sonra gradyanların ölçeğini bir kez geri alır.
- İşlem hattı paralelliği: Her grubu, farklı GPU'lardaki model aşamalarından geçen mikro gruplara böler ve tek bir eniyileyici adımından önce bu mikro grupların gradyanlarını biriktirir.
Ultralytics YOLO26 eğitimi, varsayılan olarak gradyan biriktirme uygular: eğitim kipinde eğitici, eniyileyiciyi her round(nbs / batch) grupta bir adımla ilerletir. Böylece varsayılan batch=16 ve nominal grup boyutu nbs=64, her güncellemede dört grup; batch=8 ise sekiz grup anlamına gelir. Sayı, ısınma sırasında birden başlayarak artar ve ağırlık çürümesi batch × accumulation / nbs ile ölçeklenir. Böylece 64 görüntülük bir grup için belirlenen varsayılan hiperparametreler, aynı anda yalnızca birkaç görüntüyü belleğinde tutabilen GPU'larda da geçerliliğini korur.










