Ana içeriğe geç

Orta9 dk

GPT ile "Attention is All You Need" farkı

Önkoşul:Transformer'ın eğitimi ve çıkarımı

Kanca

  1. derste eğittiğimiz mini decoder, aslında zaten bir GPT’nin KÜÇÜK bir modeli. Peki GPT, 2017’nin “Attention is All You Need” mimarisinden TAM OLARAK ne değiştirdi — ve bu değişiklikler NEDEN bu kadar önemli oldu?

Sezgi

GPT (2018), orijinal encoder-decoder mimarisini YARIYA indirdi: encoder’ı ve çapraz dikkati TAMAMEN attı, SADECE decoder blokları bıraktı. Bu, sadece bir “basitleştirme” değil — eğitim verisi ihtiyacını KÖKTEN değiştiren bir karar.

Mekanizma

Önce mimari farkı SAYILARLA görelim:

Çapraz dikkatin yokluğu, %25 daha az parametre

# 16. derste TAM bir encoder-decoder kurduk: encoder (self-attention) + decoder
# (maskeli self-attention + ÇAPRAZ dikkat + FFN). GPT (2018), bu mimariyi YARIYA
# indirdi: SADECE decoder blokları, ÇAPRAZ dikkat YOK.
D_MODEL = 512

def alt_katman_parametreleri(d_model, capraz_dikkat_var):
    self_attn = 4 * d_model * d_model  # Wq+Wk+Wv+Wo (12. ders)
    capraz_attn = 4 * d_model * d_model if capraz_dikkat_var else 0
    ffn = 2 * d_model * (4 * d_model)  # W1+W2 (15. ders)
    return self_attn + capraz_attn + ffn

encoder_decoder_blok = alt_katman_parametreleri(D_MODEL, capraz_dikkat_var=True)
gpt_blok = alt_katman_parametreleri(D_MODEL, capraz_dikkat_var=False)

print(f"Bir encoder-decoder (16. ders) decoder bloğu: {encoder_decoder_blok:,} parametre")
print(f"  (self-attention + ÇAPRAZ dikkat + FFN)")
print(f"Bir GPT-tarzı (decoder-only) blok:            {gpt_blok:,} parametre")
print(f"  (SADECE self-attention + FFN -- çapraz dikkat YOK)")
print(f"\nGPT bloğu, encoder-decoder bloğunun %{100*gpt_blok/encoder_decoder_blok:.0f}'i kadar parametre kullanıyor --")
print("kalan fark TAMAMEN çapraz dikkat katmanının (Wq+Wk+Wv+Wo) yokluğundan geliyor.")
Bir encoder-decoder (16. ders) decoder bloğu: 4,194,304 parametre
  (self-attention + ÇAPRAZ dikkat + FFN)
Bir GPT-tarzı (decoder-only) blok:            3,145,728 parametre
  (SADECE self-attention + FFN -- çapraz dikkat YOK)

GPT bloğu, encoder-decoder bloğunun %75'i kadar parametre kullanıyor --
kalan fark TAMAMEN çapraz dikkat katmanının (Wq+Wk+Wv+Wo) yokluğundan geliyor.

Bu mimari fark, EĞİTİM VERİSİ ihtiyacını da değiştiriyor:

Eşleştirilmiş veri gerekmiyor

# Bu mimari fark, EĞİTİM VERİSİ ihtiyacını da DEĞİŞTİRİR.
print("\nEncoder-decoder (16. ders): EŞLEŞTİRİLMİŞ (kaynak, hedef) çiftleri gerektirir")
print("  örn. (Türkçe cümle, İngilizce çevirisi) -- bu veri PAHALI ve SINIRLI.")
print("\nGPT (decoder-only): SADECE düz metin yeterli -- 'bir sonraki kelimeyi tahmin et'")
print("  görevi, İNTERNETTEKİ HERHANGİ bir metinden (etiketleme gerektirmeden) öğrenilebilir.")
print("  Bu fark, GPT'nin NEDEN bu kadar BÜYÜK veriyle eğitilebildiğini açıklıyor.")

Encoder-decoder (16. ders): EŞLEŞTİRİLMİŞ (kaynak, hedef) çiftleri gerektirir
  örn. (Türkçe cümle, İngilizce çevirisi) -- bu veri PAHALI ve SINIRLI.

GPT (decoder-only): SADECE düz metin yeterli -- 'bir sonraki kelimeyi tahmin et'
  görevi, İNTERNETTEKİ HERHANGİ bir metinden (etiketleme gerektirmeden) öğrenilebilir.
  Bu fark, GPT'nin NEDEN bu kadar BÜYÜK veriyle eğitilebildiğini açıklıyor.

Matematik

Post-norm ve pre-norm
Post-norm (2017):y=LayerNorm(x+AltKatman(x))\text{Post-norm (2017)}: \quad y = \text{LayerNorm}(x + \text{AltKatman}(x))Pre-norm (GPT-2+):y=x+AltKatman(LayerNorm(x))\text{Pre-norm (GPT-2+)}: \quad y = x + \text{AltKatman}(\text{LayerNorm}(x))

Fark küçük görünüyor — SADECE LayerNorm’un YERİ değişiyor. Ama pre-norm’da, "+x+x" terimi HİÇBİR normalizasyondan GEÇMEDEN doğrudan bir sonraki katmana aktarılır — 14. dersteki “gradyan kestirme yolu” hiçbir engelle KARŞILAŞMAZ. Post-norm’da ise bu yol, HER katmanda LayerNorm’dan geçmek ZORUNDA kalır.

Kod

Bu küçük fark, DERİN bir yığında NASIL bir etki yaratıyor?

Pre-norm, derin modelleri kurtarıyor

# 14. derste "post-norm" (LayerNorm(x + Alt(x))) kullandık -- orijinal 2017 makalesi
# BUNU kullanıyordu. GPT-2 ve sonrası İSE "pre-norm" (x + Alt(LayerNorm(x))) kullanır.
# Bu, sadece bir DETAY mı, yoksa SONUCU DEĞİŞTİREN bir seçim mi?
def alt_katman(boyut, seed, std=0.2):
    torch.manual_seed(seed)
    katman = nn.Linear(boyut, boyut)
    nn.init.normal_(katman.weight, std=std)
    return katman

def gradyan_olc(derinlik, mod, boyut=16):
    torch.manual_seed(1)
    x = torch.randn(1, boyut, requires_grad=True)
    h = x
    for i in range(derinlik):
        katman = alt_katman(boyut, seed=100 + i)
        norm = nn.LayerNorm(boyut)
        if mod == "post":
            h = norm(h + torch.tanh(katman(h)))          # orijinal makale
        else:
            h = h + torch.tanh(katman(norm(h)))            # GPT-2+
    kayip = h.sum()
    kayip.backward()
    return x.grad.norm().item()

print(f"\n{'Derinlik':<10} {'Post-norm (2017 makale)':<26} {'Pre-norm (GPT-2+)':<20}")
for derinlik in [10, 50, 100]:
    g_post = gradyan_olc(derinlik, "post")
    g_pre = gradyan_olc(derinlik, "pre")
    print(f"{derinlik:<10} {g_post:<26.2e} {g_pre:<20.2e}")
print("\nPost-norm'da, 10 katman sonra bile gradyan TAM SIFIRA çöküyor (sayısal underflow) --")
print("derin bir GPT'yi (96+ katman) post-norm ile eğitmek NEREDEYSE İMKANSIZ olurdu.")
print("Pre-norm'da, 100 katmanda bile gradyan SAĞLIKLI kalıyor -- GPT'nin NEDEN pre-norm")
print("seçtiğinin doğrudan nedeni bu.")

Derinlik   Post-norm (2017 makale)    Pre-norm (GPT-2+)   
10         0.00e+00                   9.31e+00            
50         1.93e-07                   1.36e+01            
100        0.00e+00                   8.12e+00            

Post-norm'da, 10 katman sonra bile gradyan TAM SIFIRA çöküyor (sayısal underflow) --
derin bir GPT'yi (96+ katman) post-norm ile eğitmek NEREDEYSE İMKANSIZ olurdu.
Pre-norm'da, 100 katmanda bile gradyan SAĞLIKLI kalıyor -- GPT'nin NEDEN pre-norm
seçtiğinin doğrudan nedeni bu.
Katman derinliğine karşı log ölçekte gradyan normunu gösteren grafik; post-norm çizgisi hızla sıfıra düşerken pre-norm çizgisi 100 katman boyunca sağlıklı kalıyor.
Post-norm (mavi), 10 katman sonra gradyanı tamamen sıfırlıyor. Pre-norm (turuncu), 100 katmanda bile sağlıklı kalıyor -- GPT'nin 96+ katmanlı modelleri EĞİTİLEBİLİR olmasının doğrudan nedeni.

Nerede işe yarar

Bu iki değişiklik (decoder-only + pre-norm), modern LLM’lerin standart tarifi hâline geldi:

  • BERT (2018), GPT’nin TERSİNİ yaptı: SADECE encoder kullandı (maskesiz self-attention) — metin ÜRETMEZ, ama metni ANLAMA (sınıflandırma, arama) görevlerinde güçlüdür.
  • “Decoder-only + sadece düz metin” tarifi, GPT’nin İNTERNET ölçeğinde veriyle eğitilebilmesini sağladı — bugünün büyük dil modellerinin (GPT-4, Claude, LLaMA…) BÜYÜK çoğunluğu bu tarifi izler.
  • Pre-norm’un TEK dezavantajı var: post-norm’a göre biraz daha DÜŞÜK “ifade gücü” (representational capacity) taşıdığı gözlemlenmiştir — ama derinlik avantajı bu dezavantajı FAZLASIYLA telafi eder.

Bu 2 hatayı yaparsın:

  1. GPT’nin “eksik” bir Transformer olduğunu düşünmek — encoder’ın çıkarılması BİLİNÇLİ bir tasarım kararı, dil modelleme hedefine daha İYİ uyduğu için.
  2. Pre-norm/post-norm farkını “önemsiz bir implementasyon detayı” sanmak — bu dersteki 0.00e+00 vs 8.12 farkı, derin bir modelin EĞİTİLEBİLİR olup olmadığını belirleyebilir.

Kendini test et

1. GPT, orijinal 'Attention is All You Need' mimarisinden hangi BÜYÜK bileşeni ÇIKARDI?
  1. Self-attention mekanizmasını
  2. Encoder'ı ve decoder'ın çapraz dikkat katmanını -- GPT SADECE (maskeli self-attention + FFN içeren) decoder bloklarını kullanır (doğru cevap)
  3. Position-wise feed-forward ağını
  4. Layer normalization'ı

Neden: mimari-fark bloğunda gpt_blok hesaplaması capraz_dikkat_var=False ile yapılıyor -- GPT bloğu, encoder-decoder bloğunun SADECE %75'i kadar parametre taşıyor, farkı tamamen çapraz dikkatin yokluğu açıklıyor.

2. GPT'nin encoder-decoder yerine SADECE decoder kullanması, EĞİTİM VERİSİ açısından NEDEN pratik bir avantaj sağlıyor?
  1. Hiçbir avantajı yok
  2. Encoder-decoder EŞLEŞTİRİLMİŞ (kaynak, hedef) veri çiftleri gerektirir (örn. çeviri çiftleri) -- GPT ise SADECE düz metinle, 'bir sonraki kelimeyi tahmin et' göreviyle eğitilebilir, bu da internetteki NEREDEYSE her metni kullanılabilir hale getirir (doğru cevap)
  3. GPT daha az veriyle eğitilir
  4. Encoder-decoder'ın veriye hiç ihtiyacı yoktur

Neden: egitim-verisi-farki bloğunda bu ayrım açıkça vurgulanıyor -- eşleştirilmiş veri PAHALI ve SINIRLIYKEN, düz metin BOL ve UCUZDUR; bu, GPT'nin ölçeklenebilirliğinin temel nedenidir.

3. Notebook'ta post-norm 10 katman sonra gradyanı TAM SIFIRA (0.00e+00) indirirken, pre-norm 100 katmanda bile sağlıklı (8.12) kalıyor. Bu farkın matematiksel nedeni ne?
  1. Rastgele bir sonuç, tekrarlanabilir değil
  2. Pre-norm'da '+x' terimi HİÇBİR normalizasyondan geçmeden bir sonraki katmana aktarılır (gradyan kestirme yolu engelsiz); post-norm'da bu yol HER katmanda LayerNorm'dan geçmek zorunda kalır, bu da derin yığınlarda gradyanı bozabilir (doğru cevap)
  3. Pre-norm daha fazla parametre kullanır
  4. İkisi arasında hiçbir matematiksel fark yoktur

Neden: MathBox'taki formüllerde pre-norm y = x + Alt(LayerNorm(x)) -- '+x' terimi DOĞRUDAN aktarılıyor; post-norm y = LayerNorm(x + Alt(x)) -- toplam SONRASINDA normalize ediliyor, bu da kestirme yolu her katmanda 'kesiyor'.

Özet

Özet

  • GPT, encoder'ı ve çapraz dikkati TAMAMEN çıkarıp SADECE decoder blokları (maskeli self-attention + FFN) kullanır.
  • Bu mimari, GPT'nin eşleştirilmiş veri yerine SADECE düz metinle eğitilebilmesini sağlar -- ölçeklenebilirliğin temel nedeni.
  • GPT-2 ve sonrası, orijinal makalenin post-norm'u yerine pre-norm kullanır: LayerNorm, artık bağlantıdan ÖNCE uygulanır.
  • Post-norm'da 10 katman sonra gradyan tam sıfıra çöküyor; pre-norm'da 100 katmanda bile sağlıklı -- bu, GPT'nin 96+ katmanlı olabilmesinin doğrudan nedeni.
  • BERT, GPT'nin TERSİNİ yapar (sadece encoder) -- metin üretmez ama metni anlama görevlerinde güçlüdür.
Sonraki adım: Transformer mimarisi: bütün resim →