Od bigramu k transformeru

Postavíme model po krocích, každý řeší selhání předchozího.

Co se naučíš: Uvidíš na naměřených číslech, proč attention musela vzniknout, včetně kroku, který model zhoršil.

8 min čtení + cvičeníNavazuje na:🔬 Transformer po lopatě

Architektura z anatomie modelu vypadá jako něco, co někdo vymyslel naráz. Nevymyslel. Každý kus tam je proto, že ten předchozí model na něčem selhal. V téhle kapitole postavíme model čtyřikrát za sebou, pokaždé o kousek chytřejší a u každého kroku uvidíš skutečné číslo, o kolik se zlepšil.

Všechna čísla níž pocházejí z opravdového tréninku: znakový model nad textem téhle učebnice (200 000 znaků, slovník 121 znaků, kontext 16 znaků). Kód i postup jsou v kapitole postav si vlastní model, takže si to můžeš zopakovat.


Výchozí bod: náhodný model

Než začneme, dobré vědět, co znamená „nic neumět“. Model, který hádá rovnoměrně mezi 121 znaky, má loss ln(121) = 4,80. Tohle je hranice, od které se odráží každý pokus.


Cesta, kterou půjdeme


Krok 1: bigram, dívej se na jediný předchozí znak

Nejjednodušší možný jazykový model: tabulka 121 × 121. Pro každý znak si pamatuje, jak pravděpodobný je každý následující. Žádné vrstvy, žádná attention, jen počítadlo.

loss:  4,80 → 3,04
vzorek: "MBůXď3zinodé3, k0 mi hovnfOb. mu. ří čf. ná a kutet ene m tÚ"

Funguje to překvapivě dobře na to, jak je to hloupé: model se naučil, že po q chodí u, po mezeře velké písmeno, že samohlásky se střídají se souhláskami. Ale nemá paměť. Pro předpověď mu slouží jediný znak a všechno starší je pryč.

Problém: potřebujeme, aby se model díval na víc než jeden znak zpátky.


Krok 2: průměr kontextu, dívej se na všechno stejně

Nejpřímočařejší nápad: vezmi průměr vektorů všech předchozích znaků. Kontext tím pádem neztratíme.

h_t = průměr(x_1 … x_t)

Výsledek je ale překvapení:

loss:  4,80 → 3,27      ← HORŠÍ než bigram (3,04)

Proč to zhoršilo? Průměrování všechno rozmělní. Poslední znak, zdaleka nejdůležitější informace, má v průměru přes deset znaků váhu jednu desetinu. Model dostal víc informace a přitom si pohoršil, protože ji neumí odlišit podle důležitosti.

Problém: kontext nestačí namíchat, je potřeba vážit.


Krok 3: naučené váhy, ať si model určí, kam se dívat

Nahradíme rovnoměrný průměr naučenou maticí vah: model se sám naučí, jakou váhu dát pozici o jedna zpátky, o dvě zpátky a tak dál.

h_t = Σ w[t,i] · x_i      kde w je naučené a maskované (jen do minulosti)
loss:  4,80 → 2,53      ← výrazně lepší než bigram

Skvělý pokrok. Model si sám zjistil, že poslední dva tři znaky rozhodují a vzdálenější mají menší váhu a naučil se to bez toho, aby mu to někdo řekl.

Ale je tu strop: ty váhy jsou pořád stejné bez ohledu na obsah. Pozice 3 dostane vždycky tutéž váhu, ať tam stojí mezera, samohláska nebo uvozovka. Jenže po písmenu q chceš koukat jinam než uprostřed dlouhého slova.

Problém: váhy musí záviset na tom, co v kontextu skutečně je.


Krok 4: attention, váhy počítané z obsahu

A tady vzniká pozornost. Váhy se nenaučí jako konstanty, ale spočítají se pro každý vstup znovu: každý token vyšle dotaz (q), každý nabídne klíč (k) a jejich shoda určí váhu.

w = softmax(q · kᵀ / √d)      ← závisí na obsahu, mění se s každým vstupem
h = w · v
loss:  4,80 → 2,40      ← nejlepší ze všech

A vzorek už drží tvar slov:

"Model čege závitrinka uto, a lloují kálože sthro prač ití pov shlad sce
 exténe si se stepou zece brata terel sálověď vyhání zhla tobnitř dely stup"

Není to čeština, ale všimni si: slabiky sedí, délka slov sedí, interpunkce je na rozumných místech. Model o čtyřech tisících parametrech, natrénovaný pár minut na notebooku.


Celý příběh v jedné tabulce

ModelCo umí navícLossPoznámka
náhodanic4,80ln(121)
bigramjeden předchozí znak3,04žádná paměť
průměr kontextuvidí celou minulost3,27horší, rozmělní důležité
naučené váhyváží podle pozice2,53ale slepé k obsahu
attentionváží podle obsahu2,40váhy se počítají za běhu

Tohle je celý důvod, proč attention existuje. Není to elegantní nápad hledající uplatnění, je to odpověď na konkrétní selhání tří jednodušších řešení.


Co zbývá do plnohodnotného transformeru

Náš model z kroku 4 má jednu hlavu, jednu vrstvu a skoro nic dalšího. Do dnešní architektury zbývá dodat právě to, co popisují ostatní kapitoly a každý z těch kusů zase řeší nějaký problém:

PřidámeJaký problém to řeší
víc hlavJedna sada vah sleduje jeden typ vztahu; hlav je potřeba víc naráz
FFN za attentionPozornost jen míchá existující informace, nic nového nespočítá
residual + normBez nich nejde naskládat víc vrstev na sebe
víc vrstevJedna úroveň zpracování na jazyk nestačí
RoPENaše poziční embeddingy neumí kontext delší, než na jaký se trénovalo
GQAKV cache by jinak sežrala paměť (attention do hloubky)

Cvičení

  1. Proč byl model s průměrováním horší než bigram, přestože „viděl víc“? Formuluj to jednou větou.
  2. Krok 3 se naučil váhy podle pozice. Vymysli konkrétní příklad textu, kde takové váhy selžou a attention uspěje.
  3. Kdyby měl slovník 1 000 znaků místo 121, jaká by byla loss náhodného modelu?
Náčrt řešení: rozbal, až si cvičení zkusíš sám
  1. Průměr rozmělnil to podstatné: nejužitečnější token, tedy ten bezprostředně předchozí, dostal váhu 1/t úplně stejnou jako všechny ostatní. Čím delší kontext, tím menší vliv měl ten jediný znak, ze kterého se dalo něco poznat. Model tedy neviděl víc informace, viděl tu samou informaci rozmazanou.
  2. Kdekoli, kde se vzdálenost k rozhodujícímu tokenu mění. Například shoda přísudku s podmětem, mezi které se vloží vedlejší věta: „Kočka, která už od rána seděla na okně, spala“ oproti „Kočka spala“. Podmět je jednou tři slova zpět a podruhé dvanáct. Váhy podle pozice mají pro každou vzdálenost jedno pevné číslo, takže se musí rozhodnout pro jednu z variant. Attention si podmět najde podle obsahu bez ohledu na to, jak daleko leží.
  3. ln(1000) = 6,91. Model, který rozděluje pravděpodobnost rovnoměrně mezi V možností, má vždy loss ln(V). Je to zároveň nejdůležitější kontrolní číslo na začátku každého tréninku, viz když se trénink pokazí.

Shrnutí

  • Bigram vidí jeden znak zpět: 3,04. Funguje překvapivě dobře, ale nemá paměť.
  • Rovnoměrný průměr kontextu je horší (3,27), protože rozmělní nejdůležitější informaci.
  • Naučené váhy podle pozice pomohou (2,53), ale nereagují na obsah.
  • Attention počítá váhy z obsahu (2,40), a proto je v architektuře nenahraditelná.
Proč je model, který průměruje celý kontext, horší než bigram, i když má k dispozici víc informací?

Protože rovnoměrný průměr rozmělní to podstatné. Poslední znak je zdaleka nejdůležitější, ale v průměru přes deset znaků má váhu jednu desetinu. Víc informace bez schopnosti odlišit její důležitost tedy může uškodit.

V čem je attention lepší než naučené váhy podle pozice?

Naučené váhy jsou konstantní: pozice tři zpět dostane vždycky stejnou váhu bez ohledu na to, co tam stojí. Attention počítá váhy z obsahu, pro každý vstup znovu, takže se po písmenu q dívá jinam než uprostřed dlouhého slova.

Model má slovník 121 znaků a loss 4,80. Co to říká o jeho stavu?

Že ještě nic neumí. Rovnoměrné hádání mezi 121 možnostmi dává loss ln(121) ≈ 4,80, takže model je přesně na úrovni náhody. Každý pokles pod tuhle hodnotu už znamená naučenou strukturu.