Transformers documentation
Gradient biriktirme
Gradient biriktirme
Büyük partiler, GPU belleğini tüketen büyük aktivasyonlar üretir. Gradyan biriktirme, gradyan hesabını birden fazla mini-partiye yayarak daha büyük bir etkili parti boyutuyla eğitim yapmanızı sağlar.
Gradyanlar, optimizör ağırlıkları güncellemeden önce n mini-toplu arasında birikir. Örneğin, cihaz başına toplu boyutu 8 ve 4 birikim adımı ile etkin toplu boyutu 32 olur.
Step 1: mini-batch 1 → forward → backward → grads = G₁
Step 2: mini-batch 2 → forward → backward → grads = G₁ + G₂
Step 3: mini-batch 3 → forward → backward → grads = G₁ + G₂ + G₃
Step 4: mini-batch 4 → forward → backward → grads = G₁ + G₂ + G₃ + G₄
→ optimizer.step() ← same update as if batch_size × 4
→ zero_grad()Gradyan biriktirme, daha büyük bir batch belleğe sığmadığında kullanılmalıdır. Gerçek bir büyük batch ile eğitime kıyasla işleme hızını (throughput) artırmaz.
per_device_train_batch_size üzerinden gradient_accumulation_steps boyunca gradyanları biriktirin.
from transformers import TrainingArguments
args = TrainingArguments(
...,
per_device_train_batch_size=8,
gradient_accumulation_steps=4,
)Kayıp ölçekleme
Özel bir kayıp fonksiyonu için, Trainer'ın kaybı tüm mini-partilerdeki tahmin hedeflerinin sayısına bölmesini sağlamak üzere num_items_in_batch parametresini dahil edin. Bu, gradient_accumulation_steps ile sabit bir adım sayısı yerine token bazında normalizasyon sağlar. Aksi takdirde, Trainer kaybı gradient_accumulation_steps değerine böler.
import torch.nn.functional as F
def compute_loss(outputs, labels, num_items_in_batch=None):
logits = outputs["logits"]
loss = F.cross_entropy(logits, labels, reduction="sum")
return loss / num_items_in_batchNedensel LM modelleri için num_items_in_batch, kaydırılmış etiketleri sayar. Kayıp, tahminin i konumundaki hedefin i + 1 konumundaki token olması için etiketleri kaydırır; bu da her dizinin 0. konumunun hedef olmadan kalmasına neden olur. Trainer bu konumları hariç tutar ve labels[..., 1:] üzerinden sayım yapar, böylece payda, kaybın kullandığı tahmin hedeflerinin sayısı ile eşleşir. Veri toplayıcısı shift_labels değerini doğrudan sağladığında, örneğin dolgu içermeyen bir toplayıcıda, Trainer bunun yerine bu tensör üzerinden sayım yapar. Maskeli LM ve sınıflandırma gibi diğer kayıp türleri, tam etiket tensörünü sayar.
Trainer sınıfından türetip compute_loss() metodunu geçersiz kılıyorsanız, kaybınızın nasıl normalize edildiğini belirtmek için loss_is_scaled_for_ga parametresini ayarlayın: Trainer'ın daha sonra gradient_accumulation_steps değerine böleceği parti başına ortalama için False veya zaten num_items_in_batch değerine böldüyseniz True.
class MyTrainer(Trainer):
loss_is_scaled_for_ga = True
def compute_loss(self, model, inputs, return_outputs=False, num_items_in_batch=None):
...
return loss_sum / num_items_in_batchSonraki adımlar
- Eğitim sırasında GPU'daki bellek kullanımını neyin tetiklediğini anlamak için GPU bellek kullanımı belgesini okuyun.
- Aktivasyon belleğini önbelleğe almak yerine aktivasyonları yeniden hesaplayarak azaltmanın nasıl yapılacağını öğrenmek için Gradient checkpointing kılavuzuna bakın.
- Daha düşük hassasiyetli veri türlerini kullanarak belleği azaltmanın ve eğitimi hızlandırmanın nasıl yapılacağını öğrenmek için Mixed precision training kılavuzuna göz atın.
- Gradient accumulation'un nasıl hesaplandığını öğrenmek için Gradient Accumulation Fix blog yazısını okuyun.