İçeriğe geç
Educora
Üniversite25 dk42 / 42

Transformerlar ve büyük dil modelleri

Tokenler ve gömmeler, öz-dikkat Attention(Q, K, V) = softmax(QKᵀ/√dₖ)·V, çok başlı dikkat, konum kodlaması, kodlayıcı ve kod çözücü, LLM'lerin sonraki token tahminiyle eğitilmesi, ince ayar, Hugging Face ve sorumlu yapay zekâ.

Kendini test et
Bu derste öğreneceklerin
  • Metnin tokenlere ve gömme vektörlerine nasıl dönüştüğünü açıklamak
  • Öz-dikkati formülle ve kodla hesaplamak, maskenin ve √dₖ'nın rolünü bilmek
  • LLM'lerin nasıl eğitildiğini (sonraki token, ince ayar) ve perpleksitenin ne olduğunu açıklamak
  • Önceden eğitilmiş modelleri kullanmak ve sorumlu yapay zekânın ele aldığı riskleri tanımak

Sohbet asistanları, makine çevirisi, kod yazmaya yardım eden araçlar; hepsinin kalbinde transformer mimarisi vardır. 2017'de “Attention Is All You Need” makalesinde (Vaswani ve arkadaşları) tanıtıldı. Büyük dil modeli (LLM) ise aslında tek bir basit görevle eğitilmiş çok büyük bir transformerdır: bir metinde sonraki tokeni tahmin etmek. Bu derste bu fikrin içine bakacak ve dikkat mekanizmasını kendi ellerimizle hesaplayacağız.

Tokenler ve gömmeler

Bir sinir ağı harflerle değil sayılarla çalışır. Bu yüzden metin önce tokenlere (sözcükler, sözcük parçaları ya da karakterler) bölünür ve her tokene bir sözlükte bir numara verilir. Modern modeller alt sözcük tokenleştirmesi (örneğin BPE) kullanır: sık görülen sözcükler tek bir token olur, nadir sözcükler parçalara bölünür. Sözlükler genellikle on binlerce token içerir; örneğin GPT-2'de 50.257 token vardır.

Python
text = 'the cat sat on the mat'
words = text.split()
vocab = sorted(set(words))
stoi = {w: i for i, w in enumerate(vocab)}
ids = [stoi[w] for w in words]
print(vocab)
print(ids)
▸ Beklenen çıktı
['cat', 'mat', 'on', 'sat', 'the']
[4, 0, 3, 2, 4, 1]
Oyuncak bir tokenleştirici: her sözcük bir tokendir. “the” iki kez geçer ve iki seferde de aynı numarayı (4) alır.

Bir token numarası kendi başına anlam taşımaz; bu yüzden her numara öğrenilen bir gömme (embedding) vektörüne dönüştürülür. Bu, V × d boyutunda bir tablodur: i. satır i. tokenin vektörüdür. Eğitim sırasında anlamca yakın tokenlerin vektörleri birbirine yaklaşır.

Python
import torch
from torch import nn

torch.manual_seed(42)
emb = nn.Embedding(num_embeddings=5, embedding_dim=4)
ids = torch.tensor([4, 0, 3, 2, 4, 1])
vectors = emb(ids)
print(vectors.shape, emb.weight.shape)
print(torch.equal(vectors[0], vectors[4]))
Beklenen çıktı
torch.Size([6, 4]) torch.Size([5, 4])
True
6 token → (6, 4) vektör. Aynı token (“the”) her zaman aynı vektörü alır; bağlamları ayırt etmek dikkat katmanlarının işidir.

Öz-dikkat (self-attention)

İngilizce “bank” sözcüğü nehir kıyısı ya da bir finans kuruluşu anlamına gelebilir; hangisi olduğuna bağlam karar verir. Öz-dikkatte her token diğer tokenlere “bakar” ve onların bilgilerinin ağırlıklı bir karışımını alır. Bunun için her token üç vektör üretir: sorgu (query, “ne arıyorum?”), anahtar (key, “bende ne var?”) ve değer (value, “ne aktarıyorum?”). Bir sorgu ile bir anahtarın iç çarpımı ne kadar büyükse o tokenin değeri sonuca o kadar çok katılır.

Q = X · WQ K = X · WK V = X · WV
burada:
  • X(T, d) şeklinde token vektörleri
  • WQ, WK, WVöğrenilen (d, dₖ) matrisleri
Attention(Q, K, V) = softmax(Q · Kᵀ / √dₖ) · VAttention(Q, K, V) = softmax(Q · Kᵀ / √dₖ) · V
burada:
  • Q · Kᵀ(T, T) puan matrisi: her sorgunun her anahtarla benzerliği
  • √dₖölçek çarpanı; dₖ anahtar boyutudur
  • softmaxsatır satır uygulanır: dikkat ağırlıkları pozitiftir ve toplamı 1'dir
  • Vdeğerler; çıktı onların ağırlıklı ortalamasıdır

Ölçekli iç çarpım dikkati (scaled dot-product attention).

Neden √dₖ'ya bölüyoruz? q ve k'nın bileşenleri ortalaması 0, varyansı 1 olan bağımsız sayılarsa q · k = ∑ qᵢkᵢ toplamının varyansı dₖ olur. dₖ = 64 iken puanlar ±8 civarına yayılır, softmax neredeyse “one-hot” olur ve gradyanlar kaybolur. √dₖ'ya bölmek varyansı yeniden 1'e getirir.

Örnek 1: elle dikkat hesabı

dₖ = 4. Sorgu q = (1, 0, 1, 0); anahtarlar k₁ = (1, 0, 1, 0), k₂ = (0, 1, 0, 1); değerler v₁ = (1, 0), v₂ = (0, 1). Dikkatin çıktısını bul.

Çözümü göster
Puanlar: q · k₁ = 2, q · k₂ = 0.
√dₖ = 2'ye bölüyoruz: (1; 0).
softmax: e / (e + 1) ≈ 0,731 ve 1 / (e + 1) ≈ 0,269.
Çıktı: 0,731 · v₁ + 0,269 · v₂ = (0,731; 0,269); sorguya daha çok benzeyen birinci tokenden daha fazla bilgi alındı.

GPT gibi metin üreten modellerde bir token geleceğe bakamaz; yoksa tahmin etmesi gereken cevabı “görürdü”. Bu yüzden köşegenin üstündeki puanlar −∞ yapılır (nedensel maske, causal mask); softmax'tan sonra ağırlıkları 0 olur. Aşağıdaki kod 4 token için öz-dikkati NumPy ile baştan sona hesaplar:

Python
import numpy as np

def softmax(z):
    e = np.exp(z - z.max(axis=-1, keepdims=True))
    return e / e.sum(axis=-1, keepdims=True)

rng = np.random.default_rng(4)
T, d = 4, 8
X = rng.normal(size=(T, d))
Wq, Wk, Wv = (rng.normal(size=(d, d)) / np.sqrt(d) for _ in range(3))
Q, K, V = X @ Wq, X @ Wk, X @ Wv
scores = Q @ K.T / np.sqrt(d)
mask = np.triu(np.ones((T, T), dtype=bool), k=1)
scores[mask] = -np.inf
A = softmax(scores)
print(np.round(A, 2))
print(A.sum(axis=1))
print((A @ V).shape)
▸ Beklenen çıktı
[[1.   0.   0.   0.  ]
 [0.82 0.18 0.   0.  ]
 [0.14 0.47 0.39 0.  ]
 [0.23 0.66 0.03 0.08]]
[1. 1. 1. 1.]
(4, 8)
Dikkat matrisi alt üçgenseldir: birinci token yalnızca kendisine, dördüncüsü ise dört tokenin hepsine bakar. Her satırın toplamı 1'dir. Koddaki tohumu (seed) değiştir ve ağırlıkların nasıl değiştiğini izle.

Çok başlı dikkat, konum kodlaması ve transformer bloğu

MultiHead(X) = Concat(head₁, …, headₕ) · WO, headᵢ = Attention(X·WQⁱ, X·WKⁱ, X·WVⁱ)
burada:
  • hbaş sayısı; her başın boyutu d / h'dir
  • WObirleştirilmiş başları karıştıran (d, d) matris

Her baş farklı bir ilişkiye dikkat etmeyi öğrenebilir: biri dil bilgisel bağlara, diğeri bir zamirin neyi gösterdiğine. Parametreler: WQ, WK, WV, WO için 4 · d² ağırlık ve 4 · d sapma.

Python
import torch
from torch import nn

torch.manual_seed(42)
mha = nn.MultiheadAttention(embed_dim=64, num_heads=8, batch_first=True)
x = torch.randn(2, 10, 64)
out, weights = mha(x, x, x)
print(out.shape, weights.shape)
print(sum(p.numel() for p in mha.parameters()))
Beklenen çıktı
torch.Size([2, 10, 64]) torch.Size([2, 10, 10])
16640
Her biri 10 tokenli 2 cümle, d = 64, 8 baş (her biri 8 boyutlu). Çıktı girdiyle aynı şekildedir; dikkat ağırlıkları (2, 10, 10)'dur (varsayılan olarak başlar üzerinden ortalama). Parametreler: 4 · 64² + 4 · 64 = 16.640.

Dikkat kendi başına tokenlerin sırasını bilmez: “köpek kediyi kovaladı” ve “kedi köpeği kovaladı” cümlelerinde aynı tokenler vardır. Bu yüzden gömmelere bir konum kodlaması eklenir. Orijinal transformerda farklı frekanslarda sinüs ve kosinüsler kullanıldı; GPT-2 gibi modeller konum vektörlerini öğrenir, günümüzün birçok LLM'i ise dönel kodlama (RoPE) kullanır.

PE(pos, 2i) = sin(pos / 10000^(2i/d)) PE(pos, 2i + 1) = cos(pos / 10000^(2i/d))PE(pos, 2i) = sin(pos / 10000^(2i/d)) PE(pos, 2i + 1) = cos(pos / 10000^(2i/d))
burada:
  • postokenin konumu: 0, 1, 2, …
  • ibileşen çiftinin numarası; küçük i hızlı, büyük i yavaş salınır
  • dgömme boyutu
Python
import numpy as np

def positional_encoding(T, d):
    pos = np.arange(T)[:, None]
    i = np.arange(0, d, 2)[None, :]
    angles = pos / 10000 ** (i / d)
    pe = np.zeros((T, d))
    pe[:, 0::2] = np.sin(angles)
    pe[:, 1::2] = np.cos(angles)
    return pe

print(np.round(positional_encoding(T=5, d=4), 3))
▸ Beklenen çıktı
[[ 0.     1.     0.     1.   ]
 [ 0.841  0.54   0.01   1.   ]
 [ 0.909 -0.416  0.02   1.   ]
 [ 0.141 -0.99   0.03   1.   ]
 [-0.757 -0.654  0.04   0.999]]
Her satır bir konumdur. İlk iki sütun hızla, son ikisi çok yavaş değişir; bir saatin saniye ve akrep kolları gibi. Her konum farklı görünür ve model aralarındaki uzaklığı kolayca hesaplayabilir.

Bir transformer bloğu şöyle kurulur: x → LayerNorm → çok başlı dikkat → artık bağlantı (x + …) → LayerNorm → iki katmanlı bir MLP (genellikle 4d gizli nöron ve GELU) → yine bir artık bağlantı. Artık bağlantılar, gradyanın onlarca bloktan kaybolmadan geçmesine yardım eder. Bir model bu bloklardan N tanesinin art arda dizilmesidir. Üç ana tür vardır:

MimariDikkatÖrneklerTipik görevler
Yalnızca kodlayıcıçift yönlüBERTmetin sınıflandırma, arama, adlandırılmış varlık tanıma
Yalnızca kod çözücünedensel (maskeli)GPTmetin üretme, sohbet, kod
Kodlayıcı–kod çözücüçift yönlü + nedensel + çapraz dikkatT5çeviri, özetleme

LLM'ler nasıl eğitilir

Ön eğitim (pretraining) aşamasında model, devasa bir metin derleminin her konumunda sonraki tokeni tahmin eder. Bu öz-denetimli öğrenmedir: etiketleri kimse yazmaz, onlar metnin kendisindeki sonraki tokenlerdir. Kayıp, tüm konumlar üzerinden ortalaması alınmış çapraz entropidir; ondan perpleksite hesaplanır: modelin her adımda ortalama kaç seçenek arasında “kararsız kaldığı”.

L = −(1/T) · ∑ₜ₌₁ᵀ ln p(xₜ₊₁ | x₁, …, xₜ) PPL = eᴸL = −(1/T) · ∑ₜ₌₁ᵀ ln p(xₜ₊₁ | x₁, …, xₜ) PPL = eᴸ
burada:
  • xₜmetindeki t. token
  • p(xₜ₊₁ | x₁, …, xₜ)önceki tokenler verildiğinde modelin doğru sonraki tokene verdiği olasılık
  • PPLperpleksite; ne kadar düşükse model o kadar iyidir
Python
import torch
import torch.nn.functional as F

torch.manual_seed(42)
tokens = torch.tensor([4, 0, 3, 2, 4, 1])
inputs, targets = tokens[:-1], tokens[1:]
logits = torch.randn(len(inputs), 5)
loss = F.cross_entropy(logits, targets)
print(inputs.tolist(), targets.tolist())
print(round(loss.item(), 4), round(torch.exp(loss).item(), 2))
print(round(torch.log(torch.tensor(5.0)).item(), 4))
Beklenen çıktı
[4, 0, 3, 2, 4] [0, 3, 2, 4, 1]
1.6522 5.22
1.6094
Hedefler, girdilerin bir konum kaydırılmış hâlidir. Rastgele bir “model” (rastgele logitler) 5 tokenlik bir sözlükte yaklaşık ln 5 = 1,609 kayıp ve yaklaşık 5 perpleksite verir; körü körüne tahmin düzeyi.
Örnek 2: perpleksiteyi yorumlamak

Sözlükte 50.000 token var. a) Körü körüne tahmin eden bir modelin kaybı ve perpleksitesi nedir? b) Eğitilmiş bir modelin ortalama kaybı 2,0'dır. Perpleksitesi nedir ve bu ne anlama gelir?

Çözümü göster
a) Her tokene 1/50.000 olasılık: L = ln 50.000 ≈ 10,8, PPL = 50.000.
b) PPL = e² ≈ 7,4: model her adımda sanki yaklaşık 7 eşit olasılıklı seçenek arasından seçiyor; 50.000'e göre muazzam bir ilerleme.

Ön eğitimden sonra model metni sürdürmeyi bilir ama henüz iyi bir asistan değildir. Ardından ince ayar (fine-tuning) gelir: soru–cevap örnekleri üzerinde denetimli eğitim, sonra da insanların tercih ettiği cevaplara dayanan yöntemler (örneğin insan geri bildirimiyle pekiştirmeli öğrenme, RLHF). Bir modeli kendi görevine uyarlarken milyarlarca parametresinin hepsini eğitmen gerekmez: LoRA gibi yöntemler yalnızca küçük ek matrisleri eğitir. Metin üretilirken model sonraki tokenin dağılımını verir, bir token seçilir ve süreç tekrarlanır.

pᵢ = exp(zᵢ / τ) / ∑ⱼ exp(zⱼ / τ)pᵢ = exp(zᵢ / τ) / ∑ⱼ exp(zⱼ / τ)
burada:
  • τsıcaklık: τ < 1 daha emin ve tekrarlı, τ > 1 daha çeşitli ve riskli metin verir

Sıcaklıklı softmax ile sonraki tokenin seçilmesi.

Python
import numpy as np

z = np.array([2.0, 1.0, 0.0])
for T in [0.5, 1.0, 2.0]:
    p = np.exp(z / T) / np.exp(z / T).sum()
    print(T, np.round(p, 3))
▸ Beklenen çıktı
0.5 [0.867 0.117 0.016]
1.0 [0.665 0.245 0.09 ]
2.0 [0.506 0.307 0.186]
Üç sıcaklıkta aynı logitler: τ = 0,5 en olası tokeni güçlendirir, τ = 2 dağılımı düzleştirir.

Hazır modeller ve sorumlu yapay zekâ

Uygulamada modelleri sıfırdan eğitmek yerine hazır modeller kullanılır. Hugging Face Hub binlerce açık modeli barındırır; transformers kütüphanesi (pip install transformers) ise onları birkaç satırla yükler. Bu kod tarayıcıda çalışmaz: ilk çalıştırmada modelin ağırlıkları (yüzlerce megabayt) indirilir.

Python
from transformers import pipeline

classifier = pipeline('sentiment-analysis', model='distilbert/distilbert-base-uncased-finetuned-sst-2-english')
print(classifier('I love learning with Educora!'))

generator = pipeline('text-generation', model='openai-community/gpt2')
result = generator('Deep learning is', max_new_tokens=20)
print(result[0]['generated_text'])
Birinci model metnin duygusunu sınıflandırır ve bir etiket ile güven puanı içeren sözlüklerden oluşan bir liste döndürür; ikincisi metni sürdürür. Üretilen metin her çalıştırmada farklı olabilir.
  • Yanlılık: modeller eğitim metinlerindeki kalıp yargıları tekrarlayabilir; işe alım ya da kredi gibi kararlarda özellikle tehlikelidir.
  • Halüsinasyonlar: model kulağa inandırıcı gelen ama yanlış olgular, alıntılar ve kaynaklar uydurabilir.
  • Gizlilik: kişisel verileri, parolaları ve gizli belgeleri çevrim içi yapay zekâ hizmetlerine yazma; eğitim verisindeki kişisel veriler de korunmalıdır.
  • Telif hakları ve lisanslar: her modelin ve veri kümesinin kullanım koşulları vardır; onları oku.
  • Enerji ve kaynaklar: büyük modelleri eğitmek ve çalıştırmak çok fazla elektrik ve hesaplama gücü gerektirir.

Önemli noktalar

  • Metin tokenlere bölünür, her token öğrenilen bir gömme vektörüne dönüşür ve ona konum bilgisi eklenir.
  • Attention(Q, K, V) = softmax(QKᵀ/√dₖ)·V: her token diğerlerinin değerlerinin ağırlıklı ortalamasını alır; √dₖ softmax'ın doymasını önler.
  • Nedensel maske kod çözücüde gelecekteki tokenleri gizler; çok başlı dikkat farklı ilişkileri paralel öğrenir.
  • Bir LLM sonraki tokeni tahmin edecek şekilde eğitilir: L = −(1/T)∑ ln p(xₜ₊₁ | x≤ₜ), PPL = eᴸ; ardından ince ayar yapılır.
  • Hazır modelleri kullanırken yanlılığı, halüsinasyonları, gizliliği ve lisansları aklında tut.

Kendini test et

10 soru. Her doğru cevap XP kazandırır.

1 / 10
Dikkat formülünde puanlar neden √dₖ'ya bölünür?