Məzmuna keç
Educora
Universitet25 dəq42 / 42

Transformerlər və böyük dil modelləri

Tokenlər və embeddinqlər, özünə diqqət Attention(Q, K, V) = softmax(QKᵀ/√dₖ)·V, çoxbaşlı diqqət, mövqe kodlaşdırması, enkoder və dekoder, LLM-lərin növbəti tokenin proqnozu ilə öyrədilməsi, incə tənzimləmə, Hugging Face və məsuliyyətli süni intellekt.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • Mətnin tokenlərə və embeddinq vektorlarına necə çevrildiyini izah etmək
  • Özünə diqqəti düsturla və kodla hesablamaq, maskanın və √dₖ-nın rolunu bilmək
  • LLM-lərin necə öyrədildiyini (növbəti token, incə tənzimləmə) və perpleksiyanı izah etmək
  • Əvvəlcədən öyrədilmiş modellərdən istifadə etmək və məsuliyyətli süni intellekt risklərini tanımaq

Söhbət asistentləri, maşın tərcüməsi, kod yazmağa kömək edən alətlər — bunların hamısının mərkəzində transformer arxitekturası dayanır. O, 2017-ci ildə «Attention Is All You Need» məqaləsində (Vaswani və həmmüəlliflər) təqdim olunub. Böyük dil modeli (LLM) isə əslində çox böyük transformerdir və bir sadə tapşırıqla öyrədilir: mətndə növbəti tokeni proqnozlaşdırmaq. Bu dərsdə bu ideyanın içinə baxacaq, diqqət mexanizmini öz əllərimizlə hesablayacağıq.

Tokenlər və embeddinqlər

Neyron şəbəkə hərflərlə yox, ədədlərlə işləyir. Buna görə mətn əvvəlcə tokenlərə bölünür — sözlərə, söz hissələrinə və ya simvollara — və hər tokenə lüğətdə nömrə verilir. Müasir modellər alt söz tokenləşdirməsindən (məsələn, BPE) istifadə edir: tez-tez rast gəlinən sözlər bir token olur, nadir sözlər isə hissələrə bölünür. Lüğətin ölçüsü adətən on minlərlə tokendir; məsələn, GPT-2-də 50 257 token var.

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)
▸ Gözlənilən nəticə
['cat', 'mat', 'on', 'sat', 'the']
[4, 0, 3, 2, 4, 1]
Oyuncaq tokenləşdirici: hər söz bir tokendir. «the» iki dəfə işlənir və hər dəfə eyni nömrəni (4) alır.

Token nömrəsi özlüyündə məna daşımır, ona görə hər nömrə öyrədilən embeddinq vektoruna çevrilir. Bu, V × d ölçülü cədvəldir: i-ci sətir i-ci tokenin vektorudur. Öyrətmə zamanı mənaca yaxın tokenlərin vektorları bir-birinə yaxınlaşı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]))
Gözlənilən nəticə
torch.Size([6, 4]) torch.Size([5, 4])
True
6 token → (6, 4) vektorlar. Eyni token («the») həmişə eyni vektoru alır — kontekstə görə fərqləndirmək diqqət qatlarının işidir.

Özünə diqqət (self-attention)

İngiliscə «bank» sözü həm «çay sahili», həm də «bank» (maliyyə təşkilatı) mənasında ola bilər — hansı olduğunu kontekst deyir. Özünə diqqətdə hər token digər tokenlərə «baxır» və onların məlumatının çəkili qarışığını götürür. Bunun üçün hər token üç vektor yaradır: sorğu (query, «nə axtarıram?»), açar (key, «məndə nə var?») və qiymət (value, «nə ötürürəm?»). Sorğu ilə açarın skalyar hasili nə qədər böyükdürsə, həmin tokenin qiyməti nəticəyə bir o qədər çox daxil olur.

Q = X · WQ K = X · WK V = X · WV
burada:
  • X(T, d) ölçülü tokenlərin vektorları
  • WQ, WK, WVöyrədilən (d, dₖ) matrislər
Attention(Q, K, V) = softmax(Q · Kᵀ / √dₖ) · VAttention(Q, K, V) = softmax(Q · Kᵀ / √dₖ) · V
burada:
  • Q · Kᵀ(T, T) ballar matrisi: hər sorğunun hər açarla oxşarlığı
  • √dₖmiqyas əmsalı, dₖ — açar vektorunun ölçüsü
  • softmaxhər sətirdə tətbiq olunur: diqqət çəkiləri müsbətdir və cəmi 1-dir
  • Vqiymətlər; nəticə onların çəkili ortasıdır

Miqyaslı skalyar hasil diqqəti (scaled dot-product attention).

Niyə √dₖ-ya bölürük? q və k-nın komponentləri orta qiyməti 0, dispersiyası 1 olan müstəqil ədədlərdirsə, q · k = ∑ qᵢkᵢ cəminin dispersiyası dₖ-ya bərabərdir. dₖ = 64 olanda ballar ±8 ətrafında səpələnir, softmax isə demək olar ki, «bir-sıfır» paylanmaya çevrilir və qradiyentlər itir. √dₖ-ya bölmək dispersiyanı yenidən 1-ə qaytarır.

Nümunə 1: diqqəti əl ilə hesablayaq

dₖ = 4. Sorğu q = (1, 0, 1, 0); açarlar k₁ = (1, 0, 1, 0), k₂ = (0, 1, 0, 1); qiymətlər v₁ = (1, 0), v₂ = (0, 1). Diqqətin nəticəsini tap.

Həllini göstər
Ballar: q · k₁ = 2, q · k₂ = 0.
√dₖ = 2-yə bölürük: (1; 0).
softmax: e / (e + 1) ≈ 0,731 və 1 / (e + 1) ≈ 0,269.
Nəticə: 0,731 · v₁ + 0,269 · v₂ = (0,731; 0,269) — sorğuya daha çox oxşayan birinci tokendən daha çox məlumat götürüldü.

GPT kimi mətn yaradan modellərdə token gələcəyə baxa bilməz — əks halda o, proqnozlaşdırmalı olduğu cavabı «görərdi». Buna görə diaqonaldan yuxarıdakı ballar −∞ edilir (səbəbli maska, causal mask); softmax-dan sonra onların çəkisi 0 olur. Aşağıdakı kod 4 token üçün özünə diqqəti NumPy ilə tam hesablayır:

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)
▸ Gözlənilən nəticə
[[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)
Diqqət matrisi aşağı üçbucaqlıdır: birinci token yalnız özünə baxır, dördüncü isə hər dörd tokenə. Hər sətrin cəmi 1-dir. Kodda seed-i dəyiş və çəkilərin necə dəyişdiyinə bax.

Çoxbaşlı diqqət, mövqe kodlaşdırması və transformer bloku

MultiHead(X) = Concat(head₁, …, headₕ) · WO, headᵢ = Attention(X·WQⁱ, X·WKⁱ, X·WVⁱ)
burada:
  • hbaşların sayı; hər başın ölçüsü d / h-dir
  • WObaşların birləşmiş çıxışını qarışdıran (d, d) matris

Hər baş fərqli münasibətə «diqqət yetirməyi» öyrənə bilər: biri qrammatik əlaqələrə, digəri əvəzliyin kimə aid olduğuna. Parametrlər: WQ, WK, WV, WO üçün 4 · d² çəki və 4 · d sürüşmə.

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()))
Gözlənilən nəticə
torch.Size([2, 10, 64]) torch.Size([2, 10, 10])
16640
2 cümlə, hər birində 10 token, d = 64, 8 baş (hər biri 8 ölçülü). Çıxışın forması girişinki ilə eynidir; diqqət çəkiləri (2, 10, 10)-dur (susmaya görə başlar üzrə orta). Parametrlər: 4 · 64² + 4 · 64 = 16 640.

Diqqətin özü tokenlərin sırasını bilmir: «it pişiyi qovdu» və «pişik iti qovdu» cümlələrində eyni tokenlər var. Buna görə embeddinqlərə mövqe kodlaşdırması əlavə olunur. Orijinal transformerdə müxtəlif tezlikli sinus və kosinuslar işlədilib; GPT-2 kimi modellər mövqe vektorlarını öyrənir, müasir LLM-lərin bir çoxu isə fırlanma kodlaşdırmasından (RoPE) istifadə edir.

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 mövqeyi: 0, 1, 2, …
  • ivektor komponentləri cütünün nömrəsi; kiçik i — sürətli, böyük i — yavaş rəqs
  • dembeddinqin ölçüsü
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))
▸ Gözlənilən nəticə
[[ 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]]
Hər sətir bir mövqedir. İlk iki sütun sürətlə dəyişir, son ikisi çox yavaş — saatın saniyə və saat əqrəbləri kimi. Mövqelər bir-birindən fərqlənir və model aralarındakı məsafəni asanlıqla hesablaya bilir.

Bir transformer bloku belə qurulur: x → LayerNorm → çoxbaşlı diqqət → qalıq əlaqə (x + …) → LayerNorm → iki qatlı MLP (adətən 4d gizli neyron və GELU) → yenə qalıq əlaqə. Qalıq əlaqələr qradiyentin onlarla bloku keçib itməməsinə kömək edir. Model bu blokların N dəfə təkrarından ibarətdir. Üç əsas növ var:

ArxitekturaDiqqətNümunələrTipik tapşırıqlar
Yalnız enkoderiki istiqamətliBERTmətnin təsnifatı, axtarış, adların tapılması
Yalnız dekodersəbəbli (maskalı)GPTmətn yaratma, söhbət, kod
Enkoder–dekoderiki istiqamətli + səbəbli + çarpaz diqqətT5tərcümə, xülasə

LLM-lər necə öyrədilir

İlkin öyrətmə (pretraining) mərhələsində model nəhəng mətn korpusunda hər mövqedə növbəti tokeni proqnozlaşdırır. Bu, özünə nəzarətli öyrənmədir: nişanlar ayrıca yazılmır, onlar mətnin özündəki növbəti tokenlərdir. İtki bütün mövqelər üzrə orta çarpaz entropiyadır; ondan perpleksiya hesablanır — modelin hər addımda orta hesabla neçə variant arasında «tərəddüd etdiyi».

L = −(1/T) · ∑ₜ₌₁ᵀ ln p(xₜ₊₁ | x₁, …, xₜ) PPL = eᴸL = −(1/T) · ∑ₜ₌₁ᵀ ln p(xₜ₊₁ | x₁, …, xₜ) PPL = eᴸ
burada:
  • xₜmətndəki t-ci token
  • p(xₜ₊₁ | x₁, …, xₜ)əvvəlki tokenlərə görə modelin düzgün növbəti tokenə verdiyi ehtimal
  • PPLperpleksiya; nə qədər kiçikdirsə, model bir o qədər yaxşıdır
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))
Gözlənilən nəticə
[4, 0, 3, 2, 4] [0, 3, 2, 4, 1]
1.6522 5.22
1.6094
Hədəflər girişlərin bir mövqe sola sürüşdürülmüş halıdır. Təsadüfi «model» (təsadüfi logitlər) 5 tokenli lüğətdə ≈ ln 5 = 1,609 itki və ≈ 5 perpleksiya verir — kor-koranə təxmin səviyyəsi.
Nümunə 2: perpleksiyanı şərh et

Lüğətdə 50 000 token var. a) Kor-koranə təxmin edən modelin itkisi və perpleksiyası nədir? b) Öyrədilmiş modelin orta itkisi 2,0-dır. Perpleksiyası nədir və bu nə deməkdir?

Həllini göstər
a) Hər tokenə 1/50 000 ehtimal: L = ln 50 000 ≈ 10,8, PPL = 50 000.
b) PPL = e² ≈ 7,4: model hər addımda sanki təxminən 7 bərabər ehtimallı variant arasında seçir — 50 000-lə müqayisədə nəhəng irəliləyiş.

İlkin öyrətmədən sonra model mətni davam etdirməyi bilir, amma hələ yaxşı köməkçi deyil. Sonra incə tənzimləmə (fine-tuning) gəlir: sual–cavab nümunələri üzərində nəzarətli öyrətmə, daha sonra isə insanların üstünlük verdiyi cavablara əsaslanan üsullar (məsələn, insan rəyi ilə möhkəmləndirici öyrənmə, RLHF). Öz tapşırığın üçün modeli uyğunlaşdıranda bütün milyardlarla parametri yox, LoRA kimi üsullarla yalnız kiçik əlavə matrisləri öyrətmək olar. Mətn yaradılarkən model növbəti tokenin paylanmasını verir, token seçilir, sonra proses təkrarlanır.

pᵢ = exp(zᵢ / τ) / ∑ⱼ exp(zⱼ / τ)pᵢ = exp(zᵢ / τ) / ∑ⱼ exp(zⱼ / τ)
burada:
  • τtemperatur: τ < 1 — daha əmin və təkrarlanan, τ > 1 — daha müxtəlif və riskli mətn

Temperaturlu softmax ilə növbəti tokenin seçilməsi.

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))
▸ Gözlənilən nəticə
0.5 [0.867 0.117 0.016]
1.0 [0.665 0.245 0.09 ]
2.0 [0.506 0.307 0.186]
Eyni logitlər, üç temperatur: τ = 0,5 ən ehtimallı tokeni gücləndirir, τ = 2 paylanmanı düzləşdirir.

Hazır modellər və məsuliyyətli süni intellekt

Praktikada modelləri sıfırdan öyrətmək əvəzinə hazır modellərdən istifadə olunur. Hugging Face Hub minlərlə açıq modeli saxlayır, transformers kitabxanası (pip install transformers) isə onları bir neçə sətirlə yükləməyə imkan verir. Bu kod brauzerdə işləmir: ilk işə salınmada modelin çəkiləri (yüzlərlə meqabayt) yüklənir.

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 mətnin tonunu təyin edir və nişanla əminlik balı olan lüğətlər siyahısı qaytarır; ikincisi mətni davam etdirir. Yaradılan mətn hər işə salınmada fərqli ola bilər.
  • Qərəz (bias): modellər öyrədildikləri mətnlərdəki stereotipləri təkrarlaya bilər — işə qəbul və ya kredit kimi qərarlarda xüsusilə təhlükəlidir.
  • Halüsinasiyalar: model inandırıcı səslənən, amma yanlış faktlar, sitatlar və mənbələr uydura bilər.
  • Məxfilik: şəxsi məlumatları, parolları və gizli sənədləri onlayn süni intellekt xidmətlərinə yazma; öyrədici verilənlərdə də şəxsi məlumatlar qorunmalıdır.
  • Müəllif hüquqları və lisenziyalar: hər modelin və verilənlər dəstinin istifadə şərtləri var — onları oxu.
  • Enerji və resurslar: böyük modellərin öyrədilməsi və işlədilməsi çoxlu elektrik enerjisi və hesablama gücü tələb edir.

Əsas fikirlər

  • Mətn tokenlərə bölünür, hər token öyrədilən embeddinq vektoruna çevrilir və ona mövqe məlumatı əlavə olunur.
  • Attention(Q, K, V) = softmax(QKᵀ/√dₖ)·V: hər token digərlərinin qiymətlərinin çəkili ortasını götürür; √dₖ softmax-ın doymasının qarşısını alır.
  • Səbəbli maska dekoderdə gələcək tokenləri gizlədir; çoxbaşlı diqqət müxtəlif münasibətləri paralel öyrənir.
  • LLM növbəti tokeni proqnozlaşdırmaqla öyrədilir: L = −(1/T)∑ ln p(xₜ₊₁ | x≤ₜ), PPL = eᴸ; sonra incə tənzimlənir.
  • Hazır modellərdən istifadə edərkən qərəz, halüsinasiya, məxfilik və lisenziya risklərini nəzərə al.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
Diqqət düsturunda ballar niyə √dₖ-ya bölünür?