English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

konuk
1 / ?
derslere geri dön

Yerel Gradyanlar Çarpılır

İleri & Geri Çekirdekler


İleri Geçiş

ANDREA-120M'nin ileri geçişi girdiyi bir dizi işlemden geçirir:


x = embed(token_ids)         # token gömme katmanları
for layer in 12_layers:
x = x + attn(LN(x))      # dikkat alt katmanı
x = x + mlp(LN(x))       # MLP alt katmanı
logits = LN(x) @ embed.T     # bağlı çıktı projeksiyonu
loss   = cross_entropy(logits, targets)

Her işlem giriş tensörlerini okur ve çıkış tensörleri üretir. İleri geçiş, bu toplu iş için çapraz entropi kaybı olan tek bir skaler ile sonlanır.


Geriye Dönük Geçiş

Eğitim, kaybı azaltan yönde ağırlıkları günceller. Güncelleme yönlerini elde etmek için motorun ihtiyacı olan:


Modeldeki her öğrenilebilir W için dL/dW

Zincir kuralı bunu verir. loss = f(g(h(x))) zinciri için:


dL/dx = (dL/df) * (df/dg) * (dg/dh) * (dh/dx)

Her faktör yerel bir gradyandır: bir işlemin çıktısının, girdisi küçük bir miktar değiştiğinde nasıl değiştiği. Yerel gradyanları graf üzerinden geriye doğru çarparak, kayıp sinyalini her ağırlığa yayar.


Ters-Mod Ayrıştırma

Backprop, gradyanları ters sırada hesaplar: dL/dlogits = 1'den başlayarak, çapraz-entropi, çıktı projeksiyonu, katman normalizasyonu, on iki transformer bloğu ve ardından gömme katmanları üzerinden geriye doğru ilerler. Her adımda, gelen gradyanı yerel Jacobian ile çarpar.


Ters-mod, çıktı tek bir skaler (kayıp) olduğunda ve çok sayıda girdi (ağırlıklar) olduğunda verimlidir. Tek bir geriye doğru geçiş, modeldeki her ağırlık için gradyan üretir. İleri-mod, ağırlık başına bir geçiş gerektirir; ~120M ağırlıklı ANDREA-120M için ileri-mod uygulanamaz.

Neden Ters-Mod

ANDREA-120M'nin ~120M ağırlığı vardır ve her eğitim adımında tek bir skaler kayıp üretir. Ters-yönlü otomatik türevlemeyi ileri-yönlü ile karşılaştırın. Belirtin (1) hangi modun tek bir geriye doğru geçişte tüm ağırlık gradyanlarını ürettiğini; (2) tüm 120M ağırlık gradyanını hesaplamak için kaç ileri-yönlü geçiş gerektiğini; (3) ANDREA'nın hangi modu kullandığını ve nedenini.

Her İleri İşlem Bir Geriye Çift Alır

Eşleştirme Disiplini

microgpt_cuda.cu her işlem için iki CUDA çekirdeği gönderir: biri ileri çıktıyı hesaplayan, diğeri çıktı gradyanları verildiğinde girdi gradyanlarını hesaplayan. Eşleştirme birebirdir:


İleri çekirdekGeri çekirdekİşlem
k_embed_fwdk_embed_bwdToken gömme bakımı
k_layernorm_fwdk_layernorm_bwdKatman normalizasyonu
k_attn_qkv_fwdk_attn_qkv_bwdQ, K, V projeksiyonları
k_attn_fwdk_attn_bwdÖlçekli nokta-çarpım dikkati
k_attn_out_fwdk_attn_out_bwdÇıkış projeksiyonu W_O
k_mlp_fwdk_mlp_bwdMLP (GELU ile)
k_residual_addk_residual_add_bwdKalıntı bağlantısı
k_loss_fwdk_loss_bwdÇapraz-entropi kaybı

Sekiz işlem çifti tam transformeri kapsar. Artı birkaç yardımcı kernel: k_grad_norm_partial, k_grad_norm_final, k_grad_scale gradyan kırpması için (bkz. aktivite 75).


Bir Geri Kernel'in Görevi

Sonraki katmanlardan gelen gradyan (grad_output) verildiğinde, bir geri kernel hesaplar:


1. grad_input: İşlem giriş tensörü ile ilgili gradyan. Bu, daha fazla geriye doğru iletilir.

2. grad_weight: İşlemdeki öğrenilebilir parametrelerle ilgili gradyan. Bu, optimizer durumuna gider.


Her ikisi de tek bir kernel başlatmasında hesaplanır. CUDA thread'leri, gradyan tensörünün karoları üzerinde paralel olarak işbirliği yapar.


Kaydedilmiş Tensörler

Geriye doğru hesaplama genellikle ileri geçişten değerlere ihtiyaç duyar. Örneğin, k_layernorm_bwd ileri geçiş sırasında hesaplanan ortalama ve varyansa ihtiyaç duyar; k_mlp_bwd GELU öncesi aktivasyona ihtiyaç duyar. Eğitim motoru bunları ileri geçiş sırasında özel tamponlarda depolar, sonra geriye doğru sırasında okur.


Bellek maliyeti: her kaydedilen tensör için ileri geçiş çıktısının kabaca aynı şekli. ANDREA-120M için batch=8, seq=1024, d_model=768 ile, bir kaydedilen tensör 8 × 1024 × 768 × 4 bayt = 25 MB. 12 katman boyunca & katman başına birden fazla kaydedilen tensör ile, aktivasyonlar eğitim sırasında VRAM'i domine eder (~24 GB kartta 5-10 GB).

Bir Geriye Dönük Adımı İzleme

ANDREA-120M bir transformer bloğu üzerinden bir ileri geçişi tamamlar. Aynı blok üzerinden geriye dönük geçiş sırasında neler olduğunu izleyin (pre-norm yapısı: `x = x + Attention(LN(x))` sonra `x = x + MLP(LN(x))`). Geriye dönük kernel'ları ateşlenme sırasına göre adlandırın & her birinin hangi ileri kernel ile eşleştiğini belirtin. En az 4 kernel kapsayın.

Gradients Bellekte Nerede Saklanır

Her Ağırlık Tensörü İçin Bir Gradyan Tensörü

ANDREA-120M'deki her öğrenilebilir ağırlık tensörünün, aynı şekle sahip eşleşen bir gradyan tensörü vardır. Her blok için:


W_Q       [768, 768]     ↔   grad_W_Q       [768, 768]
W_K       [768, 768]     ↔   grad_W_K       [768, 768]
W_V       [768, 768]     ↔   grad_W_V       [768, 768]
W_O       [768, 768]     ↔   grad_W_O       [768, 768]
W_1       [768, 3072]    ↔   grad_W_1       [768, 3072]
W_2       [3072, 768]    ↔   grad_W_2       [3072, 768]
LN1.gamma [768]          ↔   grad_LN1.gamma [768]
LN1.beta  [768]          ↔   grad_LN1.beta  [768]
LN2.gamma [768]          ↔   grad_LN2.gamma [768]
LN2.beta  [768]          ↔   grad_LN2.beta  [768]

Artı token gömme katmanları, pozisyon gömme katmanları ve son bir katman normalizasyonu. Gradyan tamponu toplam bellek kullanımı ağırlık belleğiyle eşleşir: ~120M float, FP32'de ~480 MB, FP16'da ~240 MB.


Mikrotopaklar Arasında Birikim

ANDREA'nın batch_size = 8 değeri FP16'da VRAM'e sığar. Daha büyük etkili toplu işler için gradyan birikimi gereklidir: küçük toplu işler üzerinde birden fazla ileri+geri geçiş çalıştırın, gradyanları aynı tampona toplayın, ardından bir optimizatör adımı atın.


for microbatch in range(n_microbatches):
forward(microbatch)
backward()           # Grad tamponlarına EKLER, üzerine yazmaz
scale_grads(1.0 / n_microbatches)  # Mikro partiler arasında ortalama al
optimizer_step()
zero_grads()             # Bir sonraki eğitim adımı için sıfırla

Backward kernel'ları += semantiğini kullanır, = değil. Her çağrı, mevcut tampona gradyan katkılarını ekler; tampon, zero_grads() temizleyene kadar çalışan toplamı tutar.


Optimizör Durumu

AdamW (etkinlik 73) her ağırlık için iki tampon daha tutar: birinci moment m & ikinci moment v. Toplam eğitim zamanı belleği:


ağırlıklar:    1× ağırlık sayısı
gradyanlar:  1× ağırlık sayısı
Adam m:     1× ağırlık sayısı
Adam v:     1× ağırlık sayısı
kaydedilmiş akt: katmanlara & batch'e göre ~2-4×
──────────────────────────────────────────
toplam:     ~6-8× ağırlık sayısı

ANDREA-120M FP16'da: ~240 MB × 4 tampon (ağırlık, grad, m, v) + ~5-10 GB aktivasyonlar = ~10-12 GB toplam. RTX 4090'ın 24 GB sınırının rahat altında. ANDREA-12M 1.4 GB'da eğitildi; 10× parametre ölçeklemesi ~10× bellek getirir.

Gradient Tamponlarını Boyutlandırma

ANDREA-120M yaklaşık 120.000.000 ağırlık tutar ve eğitim adım başına 4 mikro toplu ile gradyan biriktirme kullanır. Hesaplayın: (a) FP16'da gradyan tampon boyutu MB cinsinden; (b) FP16'da ağırlıklar + gradyanlar + Adam m + Adam v için toplam bellek; (c) eğitim adım başına kaç ayrı `forward()` + `backward()` çağrısı yapılır. Aritmetiğinizi gösterin.

Bellek ve Hassasiyet Üzerinde Tam Kontrol

Genel Çerçevelerin Maliyeti Nedir

PyTorch ve JAX autograd'ı kolaylaştırır: Python kodu yazın, gradyanları otomatik alın. Maliyet: kodunuz ile CUDA arasında genel bir dağıtım katmanı. Her işlem Python yorumlayıcısı yükü, çerçeve defter tutma ve dinamik çekirdek seçimi arasından geçer. Tek GPU'da küçük bir dil modelini eğitirken bu yük önemli hale gelir.


ANDREA'nın önlediği somut maliyetler:


1. Python yorumlayıcısı gecikmesi. Her PyTorch işlemi Python/C++ sınırını geçer. Eğitim adım başına ~100 çekirdek başlatma ile ~9 adım/dakika için, bu dakikada ~900 sınır geçişi anlamına gelir. C-seviyesi dağıtım bunu ortadan kaldırır.


2. Çerçeve tahsisçisi öngörülemezliği. PyTorch'un önbellek tahsisçisi ortalama iyi verimlilik sağlar ancak öngörülemez tepe bellek kullanımı. ANDREA'nın eğitim motoru her tamponu başlangıçta önceden tahsis eder; eğitim sırasında yeniden tahsis yok, parçalanma yok, 100K. adımda sürpriz OOM yok.


3. Genel çekirdek seçimi. PyTorch çekirdekleri çalışma zamanında sezgisel kurallarla seçer. ANDREA çekirdekleri derleme zamanında seçer, RTX 4090 tensör çekirdeği karo boyutlarına göre ayarlanmış.


4. Karma hassasiyet borulama. ANDREA-120M'nin FP16 cuBLAS yolu ve ANDREA'nın FP8 E4M3 tensor core deneyleri, hangi tensörlerin hangi hassasiyette yaşayacağı üzerinde kesin kontrol gerektirir. Genel çerçeveler bu kontrolü katmanlı API'ler aracılığıyla sunar; özel CUDA yazımı bunu doğrudan yazar.


Takas

Özel CUDA maliyetleri: yazılacak daha fazla kod, bulunacak daha fazla hata, topluluk ekosistemi yok. ANDREA'nın microgpt_cuda.cu dosyası ~6000 satır el yazımı CUDA olup aylarca hata ayıklama aldı. Her yeni işlem için bir ileri kernel, bir geri kernel ve testler yazmak gerekir.


ANDREA'nın kazandığı:


- Tam yeniden üretilebilirlik. Eğitim hattı bir C ikili dosyası ve bir Python vekilinden oluşur. PyTorch sürümleri arasında sürüm kayması yok, çerçeve tekerlekleriyle CUDA sürüm uyumsuzluğu yok.

- Bit tam özetlemeler. SIGTERM, GPU'nun gördüğü her tensörü tam olarak yakalayan bir kontrol noktası yazmasını tetikler. Özetleme, çalışmanın olduğu aynı kayıp yörüngesinden devam eder.

- Öngörülebilir bellek. ANDREA-120M 200K adım için eğitildi, hiç OOM yok. Bellek motor başlangıcında hesaplandı.

- Doğrudan donanım erişimi. Tensör çekirdek karo boyutları, FP8 E4M3 ayarları, asenkron bellek kopyaları: hepsi CUDA'da doğrudan erişilebilir, genel çerçevelerde opak.


Yeniden Üretilebilirlik Görevi Olarak

ANDREA beyaz kağıt bölüm 9, tam yeniden üretilebilirlik yığınını listeler:


Eğitim motoru: microgpt/microgpt_cuda.cu
Eğitim vekili: microgpt/training_proxy.py
Deneyim konfigürasyonları: experiments/ANDREA-*-TRAIN.json
Veri hattı: scripts/pull-hermes3.py, scripts/prep-megachat.py
Pano: scripts/live-loss-dashboard.html
Bandit spesifikasyonu: docs/FIREHOSE-BANDIT.md
Model belgeleri: docs/ANDREA.md

Donanım gereksinimi: ≥8 GB VRAM'e sahip bir NVIDIA GPU (RTX 3060 veya daha iyisi). Herkes bu artefaktlerden ANDREA-12M'i tekrarlayabilir. Özel CUDA yolu bunun bir parçası: framework sürüm dondurmaları yok, beş yıl sonra bağımlılık sürprizleri yok.


Sinyaller & Kontrol Noktaları

CUDA eğitim döngüsü iki POSIX sinyaline yanıt verir:


- SIGTERM: anında bir kontrol noktası yaz, sonra çık. Eğitimi temiz bir şekilde durdururken kullanılır.

- SIGUSR1: anında bir kontrol noktası yaz, eğitimi devam ettir. v3'teki polish pivot sırasında çalışmayı kesmeden durumu yakalamak için kullanılır.


Kontrol noktası formatı: [int32 step][int32 n_params][n_params × float32 weights][n_params × float32 m][n_params × float32 v]. Adım sayacı, ağırlık sayısı, ardından ağırlıklar ve Adam momentleri. Bit tam olarak devam eder. Proxy, polish sırasında .samples.json & .state.json'ı ayrı arşivler; .loss.json asla arşivlenmez (tam eğitim geçmişini biriktirir).

Neden PyTorch Değil

ANDREA, `microgpt_cuda.cu`'yu elle yazmak yerine PyTorch'un autograd'ını kullanabilirdi. ANDREA'nın özel CUDA'yı seçmesinin iki farklı mühendislik nedenini verin. Bir neden bellek veya hassasiyet kontrolüne atıfta bulunmalı; diğeri yeniden üretilebilirlik, çerçeve bağımlılıkları veya uzun vadeli bakıma atıfta bulunmalı.