GPT ile "Attention is All You Need" farkı
Önkoşul:Transformer'ın eğitimi ve çıkarımı
Kanca
- 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
Fark küçük görünüyor — SADECE LayerNorm’un YERİ değişiyor. Ama pre-norm’da, "" 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.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:
- 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.
- 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?
- Self-attention mekanizmasını
- Encoder'ı ve decoder'ın çapraz dikkat katmanını -- GPT SADECE (maskeli self-attention + FFN içeren) decoder bloklarını kullanır (doğru cevap)
- Position-wise feed-forward ağını
- 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?
- Hiçbir avantajı yok
- 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)
- GPT daha az veriyle eğitilir
- 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?
- Rastgele bir sonuç, tekrarlanabilir değil
- 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)
- Pre-norm daha fazla parametre kullanır
- İ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.