Skip to content

Self-Attention Recap: Q, K, V Matrisleri Yeniden

Caching'i içeriden anlamak için Q (query), K (key), V (value) matrislerinin ne yaptığını net görmeliyiz. Bu derste formülleri, sezgiyi ve görsel bir intuition kuruyoruz — kod ile birlikte.

Şükrü Yusuf KAYA
16 min read
Intermediate

Self-Attention Recap: Q, K, V Üçlüsü

Modül 1'de "caching neden var" sorusuna ekonomik cevap verdik. Bu modülde teknik cevabını kuracağız. İlk durak: transformer'ın kalbi olan self-attention.
Bu dersten sonra şunu net göreceksin:
Self-attention'ın çıktısı, her token için K ve V matrislerinin diğer tokenların K ve V'leriyle çarpımıdır. Aynı tokenları aynı sırada gönderirsen, K ve V matrisleri değişmez. İşte caching budur — değişmeyeni saklamak.
Bu cümle, ileriki dersler için mantra. Şimdi sıfırdan inşa edelim.

Token → Vektör: Embedding Adımı#

Her token önce bir vektöre çevrilir. Vektör boyutu (d_{\text{model}}) (Claude Sonnet için ~5120, GPT-4 için ~12K civarı — proprietary).
"merhaba" → [0.23, -0.47, 0.81, ..., 0.12] (d_model boyutunda vektör)
Sonra her vektöre pozisyon bilgisi eklenir (RoPE ile). Bunu Modül 1'de değindik.
Sonuç: (n) token için (X \in \mathbb{R}^{n \times d_{\text{model}}}) matris.

Q, K, V: Üç Doğrusal Dönüşüm#

(X) matrisinden üç ayrı projeksiyon ile Q, K, V türetilir:
Burada (W_Q, W_K, W_V \in \mathbb{R}^{d_{\text{model}} \times d_{\text{head}}}) öğrenilmiş ağırlık matrisleridir. Önemli: ağırlıklar sabit, sadece input değişir.
Sezgi:
  • Q (Query) — "Şu an hangi tokeni işliyorum, neye dikkat etmem lazım?"
  • K (Key) — "Ben hangi tokenım, kim sorarsa bana erişebilir?"
  • V (Value) — "Bana erişen birine ne içerik veririm?"
Kitap kütüphanesi analojisi:
  • Q = elindeki "ne arıyorum" kağıdı
  • K = kitap raflarındaki etiketler
  • V = kitabın içeriği

Attention Formülü#

Sihir tek satırda:
Bu formülü parçalayalım:
  1. (QK^T) — (n \times n) bir matris çıkar. Entry ([i,j]) = token (i)'nin token (j)'ye olan "ilgi puanı"
  2. (/\sqrt{d_k}) — Sayıları yumuşatır, gradient flow için
  3. (\text{softmax}) — Her satırı 1'e normalize eder, "attention weights" oluşur
  4. (\cdot V) — Weight'lerle V'leri ağırlıklı topla → her token için bir output vektörü
Çekirdek Sezgi
Sezgi düğümü: Attention "her token, diğer tüm tokenlara bakar ve onlardan ağırlıklı bir özet çıkarır" demektir. Token sayısı arttıkça (n^2) hesaplama artar — Modül 1'de gördüğümüz neden buradan.

Hand-Computed Mini Örnek#

3 tokenlı bir cümle düşün: "ben gel dim" (tokenizer parçaladı varsayalım).
(d_{\text{head}} = 2) olsun. Ağırlık matrisleri eğitilmiş haliyle bize Q, K, V verdi:
text
Q = [[1, 0], K = [[1, 0], V = [[1, 2],
[0, 1], [1, 1], [3, 0],
[1, 1]] [0, 1]] [0, 4]]
 
# Adım 1: QK^T (3×2 × 2×3 = 3×3)
QK^T = [[1, 1, 0],
[0, 1, 1],
[1, 2, 1]]
 
# Adım 2: scale (sqrt(2) ≈ 1.41) — basit tutalım, atlayalım
# Adım 3: softmax her satır için
softmax([1, 1, 0]) ≈ [0.42, 0.42, 0.16]
softmax([0, 1, 1]) ≈ [0.16, 0.42, 0.42]
softmax([1, 2, 1]) ≈ [0.21, 0.58, 0.21]
 
# Adım 4: weights × V
[[0.42, 0.42, 0.16], [[1, 2],
[0.16, 0.42, 0.42], × [3, 0],
[0.21, 0.58, 0.21]] [0, 4]]
=
[[1.68, 1.48],
[1.42, 2.00],
[1.95, 1.26]]
Self-attention adım adım — 3 tokenlı toy örnek
Anladığımız: her output satırı, 3 tokenın V'lerinin softmax ağırlıklı toplamı.
Kritik gözlem: İkinci token "gel"in Q'su, kendi K'sı ve ilk tokenın K'sıyla skorlandı. Yani aynı promptu tekrar gönderirsek, aynı K ve V matrisleri çıkar. İşte caching'in başlama noktası.
python
import numpy as np
 
Q = np.array([[1, 0], [0, 1], [1, 1]], dtype=float)
K = np.array([[1, 0], [1, 1], [0, 1]], dtype=float)
V = np.array([[1, 2], [3, 0], [0, 4]], dtype=float)
 
# QK^T
scores = Q @ K.T
print("QK^T:")
print(scores)
 
# scale
d_k = Q.shape[1]
scores = scores / np.sqrt(d_k)
print(f"\nScaled (÷√{d_k}):")
print(np.round(scores, 3))
 
# softmax (her satır için)
def softmax(x, axis=-1):
e = np.exp(x - x.max(axis=axis, keepdims=True))
return e / e.sum(axis=axis, keepdims=True)
 
weights = softmax(scores)
print(f"\nSoftmax weights:")
print(np.round(weights, 3))
 
# output
output = weights @ V
print(f"\nOutput:")
print(np.round(output, 3))
print(f"\n(Her satır bir tokenın 'attended' temsili)")
Yukarıdaki örneği numpy'da çalıştır, kendi sayılarınla dene

Multi-Head Attention#

Tek attention "head" değil; modern modeller çoklu head kullanır. Claude Sonnet ~40 head, GPT-4 ~96 head.
Her head kendi (W_Q, W_K, W_V) setine sahip. Sonra outputlar concat edilir, son bir projeksiyon ((W_O)) uygulanır.
Caching açısından önemli: Her head'in K ve V'si ayrıca saklanır. Yani toplam KV cache memory'si:
Bunu rakamlarla hissedeceğiz — Ders 3'te (KV Cache Memory Layout).

✓ Pekiştir#

Bir Sonraki Derste#

Self-attention'ın maliyet sırrını sökeceğiz: 1000 tokenlı bir output için neden saf attention (O(n^2)) tutuyor ve KV cache trick'i bunu nasıl (O(n))'e indiriyor?

Frequently Asked Questions

Eğer Q=K=V olsaydı (yani aynı X), self-similarity skorları aşırı dominant olurdu ve model esnekliğini kaybederdi. Üç farklı projeksiyon, modele 'query mantığı', 'key mantığı', 'value içeriği' arasında ayrım yapma gücü verir.

Yorumlar & Soru-Cevap

(0)
Yorum yazmak için giriş yap.
Yorumlar yükleniyor...

Related Content