İçeriğe atla
Öğrencilere ve Mezunlarımıza Özel %20 İndirim Sepette!
Self-Attention: Bir Kelime Diğerlerine Nasıl Bakar?

Self-Attention: Bir Kelime Diğerlerine Nasıl Bakar?

Erkan ŞİRİN|

Bugün kullandığınız her LLM'in altında tek bir fikir var: her kelimenin, cümledeki bütün diğer kelimelere aynı anda bakıp "senden ne almam gerekiyor?" diye sorması. Bu yazıda o fikri sıfırdan, adım adım ve gerçek rakamlarla kuracağız — sonunda formülü ezberlemiş değil, anlamış olacaksınız.

Şu iki cümleyi okuyun:

Kupa bavula sığmadı çünkü çok büyüktü.
Kupa bavula sığmadı çünkü çok küçüktü.

Birincide büyük olan kupa, ikincide küçük olan bavul. Tek bir sıfat değişti ve cümlenin öznesi bambaşka bir yere kaydı. Siz bunu düşünmeden yaptınız — ama nasıl yaptınız? Cümledeki diğer kelimelere baktınız. "Büyüktü"yü "kupa"ya, "küçüktü"yü "bavul"a bağladınız.

Önce şunu okuyun (isteğe bağlı): Bu yazı bir LLM'in ne olduğunu, model dosyasının içinde ne bulunduğunu ve "eğitim" derken neyin kastedildiğini bildiğinizi varsayıyor. Bunlar sizin için bulanıksa Bir LLM Aslında Nedir? İndirdiğiniz Dosyanın İçinde Ne Var? yazısıyla başlayın — burada geçen token, embedding, parametre ve ağırlık matrisi kavramlarının hepsi orada tek tek kuruluyor.

İşte self-attention (öz-dikkat) tam olarak bu işi yapan matematiksel mekanizmanın adı. Bir kelimenin, diğer kelimelere uzanıp onlardan anlam devşirmesi. Bu yazıda o uzanmanın nasıl bir matris çarpımına dönüştüğünü göreceğiz; hem de her adımda gerçek sayılarla, elle takip edebileceğiniz şekilde. Yazının sonunda scaled dot-product attention formülüne baktığınızda her sembolün orada neden durduğunu bileceksiniz.

1. Neden RNN Yetmedi?

2017 öncesinde dil modellerinin omurgası RNN'lerdi (recurrent neural network — yinelemeli sinir ağı). RNN kelimeleri tek tek, soldan sağa okur. Her adımda bir hidden state (gizli durum) taşır ve o ana kadar okuduğu her şeyi bu tek vektörün içine sıkıştırmaya çalışır.

Sorun burada başlıyor. "Büyüktü" kelimesine gelindiğinde "kupa" beş adım geride kalmıştır ve o beş adım boyunca sinyal defalarca ezilip yeniden yazılmıştır. Bu, literatürde long-term dependency problem (uzun mesafeli bağımlılık problemi) diye geçen klasik bir kusur: gradient'ler geriye doğru yayılırken ya sıfıra eriyor ya da patlıyor, dolayısıyla model uzak bağlantıları öğrenemiyor[3].

Attention fikri aslında bu yazının kahramanı olan makaleden eskidir. 2014'te Bahdanau, Cho ve Bengio, çeviri yapan bir RNN'in her adımda kaynak cümlenin tamamına bakıp hangi kelimeye ne kadar ağırlık vereceğini öğrenmesini önerdi — attention o zaman RNN'in yanına takılan bir yardımcıydı[27]. 2017'de gelen sıçrama şuydu: yardımcıyı bırakıp asıl mekanizmayı attıklarında model daha iyi çalışıyordu. Makalenin adı bu yüzden "Attention Is All You Need" — dikkat, tek başına yeterli.

Transformer makalesinin en sevdiğim tablosu bu problemi tek satırda özetliyor. İki kelime arasındaki sinyalin kat etmesi gereken yolu ölçüyorlar — buna maximum path length diyorlar[1][2]:

Katman tipi Katman başına hesap Sıralı işlem sayısı İki kelime arası maksimum yol
Recurrent (RNN) O(n · d²) O(n) O(n)
Self-attention O(n² · d) O(1) O(1)

RNN'de iki kelime arasındaki mesafe cümle uzadıkça büyüyor. Self-attention'da her zaman bir. Cümlenin ilk kelimesiyle son kelimesi arasında tek bir adım var. Bunun bedeli de tabloda görünüyor: hesap yükü n² ile büyüyor — 12. bölümde bu bedele geri döneceğiz.

RNN — sinyal kelime kelime taşınıyorKupabavulasığmadıçünküçokbüyüktü"büyüktü" → "Kupa": 5 adım geriye. Sinyal yolda eriyor (vanishing gradient).Self-attention — herkes herkese doğrudan bakıyorKupabavulasığmadıçünküçokbüyüktüMesafe her zaman 1 adım. Kalın çizgi = güçlü bağ.Üstelik bu bağlantıların hepsi aynı anda, paralel hesaplanıyor — RNN'de olduğu gibi sırayla değil.
Şekil 1 — RNN'de "büyüktü" ile "Kupa" arasında beş adım var ve sinyal her adımda zayıflıyor. Self-attention'da her kelime çifti arasındaki yol sabit: bir adım [1][3].

2. Önce Kelimeler Sayıya Dönüşüyor

Matematik yapabilmemiz için kelimelerin sayı olması lazım. Her token (metnin model tarafından işlenen en küçük parçası) bir embedding vektörüyle temsil edilir: d tane gerçel sayıdan oluşan bir liste. Bu vektör kelimenin "kimlik kartı" gibidir; benzer anlamlı kelimeler bu uzayda birbirine yakın düşer.

Bu vektörler eğitimde öğrenilir. Kısaca hatırlatalım: model devasa bir metin yığını üzerinde tek bir hedefle koşturulur — sıradaki token'ı tahmin et. Başta bütün sayılar rastgeledir; her yanlış tahmin backpropagation ile geriye taşınır ve her sayıyı doğru cevabı biraz daha olası kılacak yönde milimetrik olarak iter. Bu döngü trilyonlarca token boyunca tekrarlanır. Yani modeldeki hiçbir sayı elle yazılmamıştır; hepsi bu tekrarın tortusudur. Önkoşul yazısında bu süreci adım adım anlatmıştım.

Yazı boyunca üç token'lık minik bir cümleyle çalışacağız: "kedi mindere oturdu". Gerçek modellerde embedding boyutu 512, 4096 ya da daha fazladır; biz elle takip edebilelim diye d = 4 alacağız. Üç vektörü alt alta dizince X girdi matrisi çıkıyor — 3 satır (token sayısı), 4 sütun (boyut).

Token → embedding → X matrisikedimindereoturduembedding vektörü (d = 4)1.00.20.90.10.11.10.31.00.80.70.90.6istifleX — girdi matrisi1.00.20.90.10.11.10.31.00.80.70.90.6şekil: 3 × 4 (token sayısı × boyut)↑ her  bir token
Şekil 2 — Her token bir embedding vektörüne, vektörler de üst üste dizilerek X girdi matrisine dönüşüyor. Self-attention'ın başlangıç noktası bu matris.

3. Q, K, V: Aynı Kelimenin Üç Farklı Kimliği

Şimdi işin can alıcı fikrine geliyoruz. Self-attention, X matrisini üç ayrı matrise projekte eder (yansıtır). Bunun için — az önce tarif ettiğimiz pre-training sırasında öğrenilen — üç ağırlık matrisi kullanılır: WQ, WK ve WV. Bunlar cümleden cümleye değişmez; modelin kalıcı parametreleridir ve gelen her cümleye aynı üç matris uygulanır. Çarpımların sonucunda elimize üç matris geçer:

Matris Adı Anlamı
Q = X · WQ Query (sorgu) "Ben ne arıyorum?" — kelimenin diğerlerinden talebi
K = X · WK Key (anahtar) "Bende ne var?" — kelimenin ilan ettiği etiket
V = X · WV Value (değer) "Alırsan sana ne veririm?" — aktarılacak asıl içerik

Benzetmeyi kütüphaneden alalım: elinizdeki arama fişi query, rafların üstündeki etiketler key, kitabın içindeki metin ise value. Fişinizi bütün etiketlerle karşılaştırırsınız, en çok uyanı bulursunuz ve o rafın içeriğini alırsınız. Kritik ayrım şu: eşleşmeyi belirleyen şey key, size aktarılan şey value. Bu ikisi ayrı olduğu için model "kime bakacağım" ile "ne alacağım" sorularını birbirinden bağımsız öğrenebiliyor.

Çarpımın mekaniği de basit: Q'nun ilk satırını bulmak için X'in ilk satırıyla WQ'nun her sütununun dot product'ını (nokta çarpımını) alırsınız. Aynı işlem her satır için tekrarlanır; üç ağırlık matrisi için de aynı şey yapılır ve Q, K, V hazır olur.

Tek bir X, üç ayrı projeksiyonX3 × 4girdi× W_Q× W_K× W_VQqueryKkeyVvalue"Ben ne arıyorum?"Arama fişi. Kelimenin diğerlerinden beklentisi."Bende ne var?"Raf etiketi. Eşleşmeyi bu belirler."Sana ne veririm?"Rafın içeriği. Aktarılan asıl bilgi budur.Kritik ayrım:  Ayrı oldukları için model "kime bakayım" ile "ne alayım"ı bağımsız öğrenir.
Şekil 3 — Aynı girdi matrisi, üç öğrenilmiş ağırlık matrisiyle çarpılarak query, key ve value'ya dönüşüyor. Üçü de aynı kelimeden türüyor — "self" (öz) kelimesi buradan geliyor.

Peki bu W matrisleri nereden geliyor? Kısa cevap: X sizin cümlenizden gelir, W'ler gelmez. X her istekte sıfırdan oluşur ve cevap dönünce atılır; W'ler ise modelin kendisidir — indirdiğiniz dosyanın içinde duran, pre-training'den çıkmış ve donmuş sayılar. Sizin cümlenizden haberleri yoktur, gelen her cümleye aynı üç matris uygulanır. Ölçek fikri versin diye: Llama 3 8B'de bu attention matrisleri modelin 8,03 milyar parametresinin ~1,34 milyarını oluşturuyor, geri kalanın çoğu feed-forward katmanlarında[28][29]. Önkoşul yazısında bu matrislerin dosyanın neresinde durduğunu, şekillerinin neden öyle olduğunu ve nasıl oluştuklarını şemalarıyla birlikte bulabilirsiniz.

Bundan sonraki adımlar için elimizdeki Q, K ve V şu olsun. (Rakamları takip edilebilir olsun diye seçtim; gerçek bir modelde bu değerler eğitim sonunda kendiliğinden oluşur.)

            Q                        K                        V
kedi     [3, 1, 3, 1]     kedi     [1, 0, 1, 0]     kedi     [2, 0, 1, 0]
mindere  [1, 1, 1, 5]     mindere  [0, 1, 0, 1]     mindere  [0, 2, 0, 1]
oturdu   [3, 2, 3, 1]     oturdu   [1, 1, 0, 0]     oturdu   [1, 1, 2, 2]

4. Skorlar: Her Kelime Herkesle Tanışıyor

Query "ne aradığımı", key "bende ne olduğunu" söylüyorsa, ikisinin ne kadar uyuştuğunu ölçmek için dot product almak yeterli. İki vektör aynı yöne bakıyorsa çarpım büyük, farklı yönlere bakıyorsa küçük ya da negatif çıkar.

Bunu tek tek yapmak yerine tek hamlede hallederiz: Q · KT. Sonuç 3×3'lük bir skor matrisi. Satırlar soru soran kelimeyi, sütunlar cevap veren kelimeyi temsil eder. Örneğin "kedi" satırındaki "oturdu" sütunu, qkedi · koturdu = 3·1 + 1·1 + 3·0 + 1·0 = 4.

Q · Kᵀ — üç kelime, dokuz skortek hücre nasıl doluyor?q(kedi)3131k(oturdu)11003·1 + 1·1 + 3·0 + 1·0 = 
Şekil 4 — Q · Kᵀ çarpımı, her kelime çifti için bir "ne kadar ilgiliyiz" skoru üretiyor. Bu matris ham attention haritası; henüz yorumlanabilir bir olasılık değil.

5. Neden √dk'ye Bölüyoruz?

Formülün en çok "bu da nereden çıktı" dedirten parçası burası. Cevabı aslında makalede tek cümleyle veriliyor: dk büyüdükçe dot product'lar büyük değerlere ulaşıyor ve softmax'i gradient'lerin son derece küçük olduğu bölgeye itiyor[1].

Neden büyüyorlar? Basit bir istatistik: query ve key bileşenleri ortalaması 0, varyansı 1 olan bağımsız değişkenler ise, dk tane çarpımın toplamı olan dot product'ın varyansı dk olur — yani standart sapması √dk[1]. Bunu doğrulamak kolay; rastgele vektörlerle deneyin:

dk Dot product'ın standart sapması (ölçülen) √dk
4 1.99 2
64 8.00 8
512 22.62 22.6

dk = 512'de skorların ±60, ±100 gibi değerlere savrulması normal. Softmax'e böyle bir sıra verdiğinizde ne olur? En büyük değer 1'e, geri kalan her şey 0'a yapışır. Dağılım tek bir token'ın üstüne çöker, gradient'ler sıfırlanır ve öğrenme durur. √dk'ye bölmek, skorların standart sapmasını dk'den bağımsız olarak 1 civarına çeker — ne olursa olsun softmax'in sağlıklı çalıştığı aralıkta kalırsınız[10][11].

Kendi örneğimizde dk = 4, yani 2'ye bölüyoruz. Farkı görün:

"kedi" satırı — ölçeklemeden önce ve sonraÖLÇEKLEMESİZ · skorlar [6, 2, 4] → softmaxkedi%86.7mindere%1.6oturdu%11.7↑ Tek kelime her şeyi süpürdü. Cümlenin geri kalanı neredeyse yok sayıldı.√d_k = 2'ye BÖLÜNMÜŞ · skorlar [3, 1, 2] → softmaxkedi%66.5mindere%9.0oturdu%24.5↑ "oturdu" hâlâ masada. Bağlam korunuyor, gradient akıyor.
Şekil 5 — Aynı skorlar, tek fark √d_k'ye bölme. Ölçeklemesiz softmax dağılımı tek token'ın üzerine çöküyor (%86.7); ölçeklenmiş halde cümlenin diğer parçaları da katkı verebiliyor [1][10].

6. Softmax: Skorları Paylaştırmak

Ölçeklenmiş skorları softmax'ten geçirdiğimizde iki iş birden olur. Önce exponent alınır — farklar keskinleşir; sonra normalize edilir — her satır tam olarak 1'e toplanır. Artık elimizde ham sayılar değil, geçerli bir olasılık dağılımı var. Tam matrisimiz şu:

Soran ↓ / Bakılan → kedi mindere oturdu toplam
kedi %66.5 %9.0 %24.5 %100
mindere %10.7 %78.7 %10.7 %100
oturdu %54.7 %12.2 %33.1 %100

Son satır güzel: "oturdu" dikkatinin yarısından fazlasını "kedi"ye ayırıyor. Fiil, öznesine uzanmış. Kimse modele "fiiller öznesini bulsun" diye bir kural yazmadı; bu desen tamamen ağırlıkların ürünü.

Bu arada "her satır 1'e toplanmak zorunda" kuralının ilginç bir yan etkisi var: bir kelimenin bakacak anlamlı bir şey bulamadığı durumlarda bile o %100'ü bir yere koyması gerekiyor. Modeller bu artık dikkati genelde cümlenin ilk token'larına boşaltıyor — literatürde attention sink diye geçen olay bu. Sonucu çok pratik: uzun sohbetlerde eski token'ları cache'ten atarken ilk birkaç token'ı (pratikte 4 tanesini) sabit tutmazsanız model çöküyor; sabit tutunca aynı model milyonlarca token'lık akışta ayakta kalabiliyor[8][9].

7. Çıktı: Value'ların Ağırlıklı Karışımı

Son adım şaşırtıcı derecede sade. Her kelimenin çıktı vektörü, bütün value vektörlerinin — attention ağırlıklarıyla çarpılmış — toplamıdır. "kedi" için:

çıktı(kedi) = 0.665 × v(kedi) + 0.090 × v(mindere) + 0.245 × v(oturdu)
            = 0.665 × [2, 0, 1, 0]
            + 0.090 × [0, 2, 0, 1]
            + 0.245 × [1, 1, 2, 2]
            = [1.575, 0.425, 1.155, 0.579]

Bu vektör artık "kedi"nin yalnız başına anlamı değil; bu cümledeki kedinin anlamı. Kendi kimliğini ağırlıklı olarak koruyor ama içine "oturdu"dan ciddi bir pay karışmış durumda. Aynı işlem her token için yapılır ve self-attention katmanının çıktısı hazır olur: girdiyle aynı şekilde (3×4), ama her satır artık bağlamla zenginleşmiş.

Baştan sona tek şema: X'ten çıktıyaX3 × 4Q = X·W_QK = X·W_KV = X·W_VQ · Kᵀ÷ √d_ksoftmaxağırlık × VV doğrudan son adıma giderSon adımın içi: "kedi"nin çıktısı, value'ların ağırlıklı karışımı%66.5 ×v(kedi)[2, 0, 1, 0]%9.0 ×v(mindere)[0, 2, 0, 1]%24.5 ×v(oturdu)[1, 1, 2, 2]= çıktı(kedi)[1.575, 0.425, 1.155, 0.579]Ne değişti?Girdi vektörü kelimenin 
Şekil 6 — Üstte tüm pipeline, altta son adımın içi. Çıktı vektörü, value'ların attention ağırlıklarıyla karıştırılmış hali; girdiyle aynı boyutta ama artık bağlam taşıyor.

Bütün bu anlattığımız tek satırlık formülün açılımıydı — makalenin meşhur denklemi[1]:

Attention(Q, K, V) = softmax( Q·Kᵀ / √d_k ) · V

Kodu da aynı ölçüde kısa:

import math
import torch.nn.functional as F

def self_attention(X, Wq, Wk, Wv):
    Q, K, V = X @ Wq, X @ Wk, X @ Wv
    scores  = Q @ K.transpose(-2, -1) / math.sqrt(Q.size(-1))
    weights = F.softmax(scores, dim=-1)      # her satır 1'e toplanır
    return weights @ V, weights

Prod notu: Bu beş satırı öğrenmek için elle yazın, ama gerçek işlerde torch.nn.functional.scaled_dot_product_attention'ı çağırın. Aynı matematiği yapar, ama donanıma göre FlashAttention gibi optimize edilmiş kernel'lere düşer[23]. Aradaki fark uzun context'lerde katlarla ölçülür — 12. bölümde nedenini göreceğiz.

8. Eksik Parça I: Modelin Kelime Sırasından Haberi Yok

Şimdi rahatsız edici bir gerçeği fark edelim. Yukarıdaki hesabın hiçbir yerinde "kedi birinci token, oturdu üçüncü token" bilgisi geçmedi. Token'ların sırasını değiştirseniz skor matrisinin satır-sütunları yer değiştirir ama içerik aynı kalır. Yani self-attention kelime sırasına kördür.

Bu ciddi bir problem: "Kedi fareyi kovaladı" ile "Fareyi kedi kovaladı" arasındaki farkı kaçırırsınız. Çözüm, konum bilgisini embedding'lere eklemek. Orijinal makale farklı frekanslarda sinüs ve kosinüs fonksiyonları kullandı[1]. Bugünün modellerinin çoğu ise RoPE (rotary position embedding) kullanıyor: konumu toplamak yerine query ve key vektörlerini konuma bağlı bir açıyla döndürüyor. Böylece iki token'ın dot product'ı doğal olarak aralarındaki göreli mesafeye duyarlı hale geliyor[6][7].

9. Eksik Parça II: Maskeleme

İkinci eksik parça, cümleyi üreten modellerde (GPT ailesi gibi decoder mimarilerinde) hayati. Bir sonraki kelimeyi tahmin etmeyi öğrenirken model, cevabı ileriden okuyamamalı. Ama kurduğumuz mekanizma herkesi herkese bağlıyor — üçüncü kelime dördüncüye rahatça bakar.

Çözüm basit ve zarif: softmax'ten önce, ileriye bakan hücrelere −∞ yazılır. Exponent alındığında e−∞ = 0 olur ve o hücreler dağılımdan tamamen silinir; kalan hücreler kendi aralarında yeniden normalize edilir[12]. Buna causal mask (nedensel maske) denir.

Causal mask — geleceği görmek yasak① ham skorlar② maske uygulanır (−∞)③ softmax sonrası624262635→6−∞−∞26−∞635→%10000%11.9%88.10%54.7%12.2%33.1Satırlar: 1. kedi   2. mindere   3. oturdu  ·  Sütunlar aynı sırayla bakılan kelimeler.İlk token'ın bakabileceği tek yer kendisi: dikkatinin  oraya gider. Sıra ilerledikçe seçenek artar.
Şekil 7 — Causal mask, üst üçgeni −∞ yaparak geleceği siler. Exponent alındığında bu hücreler sıfırlanır ve kalan ağırlıklar kendi aralarında yeniden paylaşılır [12].

10. Eksik Parça III: Tek Kafa Yetmiyor

Buraya kadar kurduğumuz mekanizmanın bir sınırı var: tek bir attention head aynı anda tek tür ilişkiyi yakalayabiliyor. Ama diller bundan zengin. Bir cümlede aynı anda özne-fiil ilişkisi, sıfat-isim ilişkisi, zamir çözümlemesi ve konu bütünlüğü var. Hepsini tek bir ağırlıklı ortalamaya sıkıştırmak, bütün bu sinyalleri birbirine bulaştırmak demek.

Çözüm multi-head attention: aynı işi h tane paralel kopyada, her biri kendi WQ, WK, WV setiyle yapmak. Orijinal makalede h = 8 ve her head 64 boyutlu çalışıyor (dmodel = 512 ÷ 8)[1]. Dikkat edin: boyut bölünüyor, yani sekiz head'in toplam maliyeti tek büyük head'inkiyle aşağı yukarı aynı. Sonuçlar birleştirilip (concat) son bir WO matrisiyle karıştırılır[13][14].

Multi-head attention — aynı cümle, farklı merceklerÖrnek cümle: "Yorgun kedi eve döndü çünkü  çok üşümüştü."
Şekil 8 — Multi-head attention aynı cümleyi paralel mercekler altında okur. Her head kendi ilişki türünü yakalar, sonuçlar birleştirilip W_O ile karıştırılır [1][13].

11. Peki Gerçekten Dilbilgisi mi Öğreniyor?

Şimdiye kadar "model özneyi buluyor" gibi cümleler kurdum. Bunun ölçülmüş bir karşılığı var mı? Var. Stanford ve Facebook AI araştırmacılarının BERT'in 144 attention head'ini (12 katman × 12 head) tek tek incelediği çalışma, bazı head'lerin şaşırtıcı derecede temiz dilbilgisi işleri yaptığını gösterdi[4][5][30]:

Head Ne yapıyor Doğruluk
8-11 İsmin belirticisini (determiner) buluyor %94.3
8-10 Fiilin nesnesini (direct object) buluyor %86.8
7-6 İyelik zamirini bağlıyor %80.5
9-6 Edatın nesnesini buluyor %76.3
5-4 Zamiri gönderme yaptığı ismin başına bağlıyor (coreference) %65.1

Kimse bu modele sözdizimi kuralları öğretmedi; hedefi sadece maskelenmiş kelimeleri tahmin etmekti. Dilbilgisi, bu hedefi tutturmanın en verimli yolu olduğu için kendiliğinden ortaya çıktı.

Ama aynı çalışma bir uyarı da içeriyor: BERT'in 6–10. katmanlardaki dikkatinin yarısından fazlası ayırıcı [SEP] token'ına gidiyor ve yazarlar bunun bir tür "no-op" — yani "bu head'in şu an söyleyecek bir şeyi yok" sinyali olduğunu düşünüyor[5]. Yani attention haritasındaki her parlak nokta anlamlı değil.

Dikkatli olun — attention bir açıklama değildir. Attention ağırlıklarını "modelin gerekçesi" gibi okumak yaygın ama tartışmalı bir alışkanlık. 2019'da yayımlanan "Attention is not Explanation" çalışması, ağırlıkları ciddi biçimde değiştirip aynı tahmini üretmenin mümkün olduğunu gösterdi[15]. Aynı yıl gelen "Attention is not not Explanation" cevabı bunun testlere bağlı olduğunu savundu[16]. Bugünkü dürüst özet şu: attention haritası modelin bilgi akışı hakkında bir ipucudur, kararının kanıtı değil.

12. Faturanın Geldiği Yer: n²

1. bölümdeki tabloya geri dönelim. Self-attention'ın verdiği sabit yol uzunluğunun bedeli, her kelime çiftinin hesaplanması: n token için n² skor. Bu, context uzadıkça acımasızlaşan bir büyüme:

Context uzadıkça hesaplanan kelime çifti sayısı (n²)512 token262 bin çift2.048 token4,2 milyon çift8.192 token67 milyon çift32.768 token1,07  çift
Şekil 9 — n² büyümesi. 128K context'te tek bir attention matrisi 17 milyara yakın hücre içerir; bunu belleğe açıkça yazmak imkânsıza yakındır — bu yüzden modern kernel'ler onu hiç oluşturmaz.

Bu faturayı hafifletmek son yılların en yoğun mühendislik alanı oldu. Üç ana yönü bilmekte fayda var:

FlashAttention — matrisi hiç oluşturma. Tekniğin kilit gözlemi şu: darboğaz çarpma değil, GPU'nun yavaş HBM belleğiyle hızlı SRAM'i arasındaki veri trafiği. FlashAttention devasa n×n matrisini belleğe hiç yazmaz; girdiyi bloklara bölüp softmax'i parça parça, çevrimiçi biçimde hesaplar. Sonuç bitine kadar aynıdır — yaklaşıklık yok — ama bellek ihtiyacı n² yerine doğrusal olur[17][18].

GQA ve MLA — KV cache'i küçült. Üretim sırasında model her token için key ve value'ları saklar (KV cache) ki her adımda baştan hesaplamasın. Bu cache uzun sohbetlerde modelin kendisinden fazla yer kaplayabiliyor. Grouped-query attention (GQA), birden fazla query head'in aynı key/value çiftini paylaşmasını sağlar; kalite kaybı küçük, cache tasarrufu büyüktür[19][20]. DeepSeek'in kullandığı multi-head latent attention (MLA) ise key ve value'ları düşük boyutlu bir latent vektöre sıkıştırıp cache'te onu tutar[21].

Hibrit mimariler — her katmanda tam attention'a gerek yok. 2026'nın en belirgin eğilimi bu: katmanların bir kısmında tam (quadratic) attention, kalanında sliding-window attention ya da Mamba benzeri doğrusal maliyetli state-space katmanları kullanmak. Sistematik karşılaştırmalar, doğru karışımın uzun context'te tam attention'a yakın kalite verirken maliyeti ciddi biçimde düşürdüğünü gösteriyor[22][24].

Bu üçünün ortak noktasına dikkat edin: hiçbiri self-attention'ın fikrini değiştirmiyor. Query sorar, key cevap verir, value taşınır. Değişen sadece bu işin nerede, hangi hassasiyette ve kaç kelime çifti için yapıldığı.

Kapanış

Başladığımız soruya dönelim: "çok büyüktü" derken neyin büyük olduğunu nereden biliyoruz? Cevap, kelimelerin tek başına anlam taşımaması. Anlam, kelimeler arasında duruyor.

Self-attention'ın yaptığı iş, bu ilişkiyi hesaplanabilir hale getirmekten ibaret. Her kelime bir soru sorar (query), her kelime bir etiket taşır (key), eşleşme oranında içerik aktarılır (value). Dot product benzerliği ölçer, √dk ölçeği sağlıklı tutar, softmax bir bütçeye çevirir, son çarpım o bütçeyi harcar. Hepsi bu — ve milyarlarca parametre ölçeğinde tekrarlandığında dil modellerinin bizi anlamaya başlamasının sebebi bu oldu.

Peki nereden devam edeceğiz? Üç yol var ve üçü de bu yazının doğal devamı: attention'ı bir Transformer bloğunun içine yerleştirmek (residual bağlantılar, layer norm, feed-forward katman), cross-attention'ı görmek (query bir dizinden, key ve value başka bir dizinden gelirse ne olur — çeviri ve multimodal modellerin temeli), ve KV cache'in prod'da nasıl yönetildiğini incelemek.

Ama en iyisi şu: yukarıdaki beş satırlık fonksiyonu açıp kendi cümlenizle çalıştırın, attention matrisini yazdırın ve satırların gerçekten 1'e toplandığını kendi gözünüzle görün. Formülü okumakla çalıştırmak arasındaki fark, bu konuda sandığınızdan büyük. Görsel anlatım tarafında Jay Alammar'ın "The Illustrated Transformer"ı[25], satır satır kod tarafında ise Harvard NLP'nin "The Annotated Transformer"ı[26] bu yazının doğal iki devamı. Modelin geri kalanı — dosyanın içi, parametre bütçesi, üretim döngüsü — merak ediyorsanız önkoşul yazısı orayı anlatıyor. Kolay gelsin!


Kaynaklar

  1. Vaswani et al. — Attention Is All You Need (arXiv:1706.03762)
  2. Attention Is All You Need — NeurIPS 2017 Proceedings (PDF)
  3. Pascanu, Mikolov, Bengio — On the Difficulty of Training Recurrent Neural Networks
  4. Clark et al. — What Does BERT Look At? An Analysis of BERT's Attention (ACL Anthology)
  5. Clark et al. — What Does BERT Look At? (Stanford NLP, PDF)
  6. Su et al. — RoFormer: Enhanced Transformer with Rotary Position Embedding
  7. EleutherAI Blog — Rotary Embeddings: A Relative Revolution
  8. Xiao et al. — Efficient Streaming Language Models with Attention Sinks
  9. MIT HAN Lab — How Attention Sinks Keep Language Models Stable
  10. Outcome School — The Math Behind the √dₖ Scaling Factor in Attention
  11. ApX Machine Learning — Scaled Dot-Product Attention Explained
  12. Sebastian Raschka — What Is Causal Attention, and Why Can GPT-Style Models Not Look at Future Tokens?
  13. Sebastian Raschka — Multi-Head Attention (LLM Architecture Gallery)
  14. Sebastian Raschka — Understanding and Coding Self-Attention, Multi-Head, Causal and Cross-Attention in LLMs
  15. Jain & Wallace — Attention is not Explanation
  16. Wiegreffe & Pinter — Attention is not not Explanation
  17. Dao et al. — FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness
  18. Dao-AILab — flash-attention (GitHub)
  19. Ainslie et al. — GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints
  20. ZeroEntropy — Grouped-Query Attention: Shrinking the KV Cache
  21. LLMs From Scratch — Multi-Head Latent Attention (MLA)
  22. Hybrid Architectures for Language Models: Systematic Analysis and Design Insights
  23. PyTorch Docs — torch.nn.functional.scaled_dot_product_attention
  24. Sebastian Raschka — Hybrid Attention (LLM Architecture Gallery)
  25. Jay Alammar — The Illustrated Transformer
  26. Harvard NLP — The Annotated Transformer
  27. Bahdanau, Cho, Bengio — Neural Machine Translation by Jointly Learning to Align and Translate
  28. Llama 3 8B — config.json (hidden_size, head counts, layer count)
  29. Vizuara — Two-Thirds of Trainable Parameters in GPT Belong to the MLP, Not the Attention Heads
  30. Clark et al. — What Does BERT Look At? (arXiv:1906.04341)
  31. Kapak: Photo by byronetmedia on Unsplash
Bloga dön

Yorum yapın