jancll.com

Lekce 10 · 25 min čtení

Mini-GPT (finální projekt)

Slepíme všechno z kurzu do jednoho funkčního GPT, natrénujeme ho na Švejkovi a uvidíme, jak se učí psát i kde naráží na své limity.

Úvod

Tak jsme tady. Devět lekcí jsme stavěli jednotlivé dílky a teď je spojíme do kompletního GPT. Malého, ale opravdového. Dáme mu Švejka a necháme ho, ať se naučí psát. Celé to poběží v tvém prohlížeči.

A rovnou tě připravím na to, co uvidíš, protože je to poučnější než nějaká nablýskaná ukázka. Náš model bude mít pár desítek tisíc parametrů a uvidí jen jednotlivé znaky. Naučí se psát švejkovinu, ale taky narazí na svůj strop. A přesně na tom stropu pochopíš, proč musí být opravdové modely tak obří. Tohle není zklamání, tohle je ta nejdůležitější lekce celého kurzu.

Voják u stolu píše na papír, zatímco důstojník podezřívavě kontroluje hromádku opisů

Malý model už píše. Teď ještě poznat, jestli tvoří, nebo jen opisuje.

Co máme v ruce

Malá inventura. Každý kousek už znáš:

  • Tokenizace (lekce 2): nakrájíme text. Teď nejjednodušeji, po znacích.
  • Embeddingy (lekce 3) a poziční kódování (lekce 8): znak na vektor plus informace o pozici.
  • Attention a multi-head (lekce 7 a 8): každý znak se podívá po ostatních.
  • Transformer blok (lekce 9): attention, feed-forward, reziduum, normalizace.
  • Trénink (lekce 5 a 6): cross-entropy, gradient, krok. Pořád dokola.

Mini-GPT je tohle poskládané ve správném pořadí. Nic víc.

Mini-GPT, dílek po dílku

Cesta jednoho znaku skrz model: vezmeme posledních pár desítek znaků a chceme předpovědět ten následující.

  1. Každý znak se přes embedding změní na vektor a přičte se k němu poziční kódování. Model ví, co to jsou za znaky a v jakém jsou pořadí.
  2. Sekvence vektorů projde transformer blokem: znaky se přes attention podívají jeden na druhý, feed-forward to promyslí, reziduum a normalizace to drží pohromadě. (Velká GPT tu mají bloků mnoho. My pro rychlost jeden.)
  3. Závěrečná vrstva převede vektor každé pozice na logity přes celý slovník.
  4. Softmax z logitů udělá pravděpodobnosti dalšího znaku.

Trénujeme to stejně jako bigram v lekci 6: hádej další znak, změř cross-entropy, sjeď gradientem z kopce. Jen toho model uvnitř dělá mnohem víc.

Jak se učí psát

Tahle nahrávka je skutečný průběh tréninku našeho mini-GPT na švejkovském korpusu. Klikni spustit trénink a sleduj tři věci: jak klesá loss, jak se proměňuje generovaný text, a hlavně ten řádek opsáno doslova.

TrainingDashboard · mini-GPT se učí psát

Skutečný průběh tréninku. Sleduj, jak text dozrává, a hlídej délku doslovného opisu.

loss (cross-entropy)krok 1/6000 · loss 3.71
stav: čistý šumopsáno doslova: 7 znaků z 190 (zbytek složil sám)

co model napsal v kroku 0

pan švejk áakaědí difvčúopčííbíkřšaíugyczfímg.múřokuéípnbvúrudžčpřéufičůčňeížvžáůlguátvt čcséyípúembřběamkéjnaeděůvytůúžčíeaýguzueťyfgůňfřůáz:teúgžamnyzspaheodymfňvft

Projdi si ten oblouk pozorně, protože vypráví celý příběh učení:

  • Krok 0 až 400: nejdřív šum, pak slabiky, pak se začnou rojit slova. Model pochopil, že existují mezery, samohlásky, interpunkce.
  • Krok 1000 až 2500: souvislejší věty ve švejkovském duchu. A všimni si, že opsáno doslova je pořád nízko, kolem 30 znaků. To znamená, že model text z velké části skládá sám, nereprodukuje korpus.
  • Krok 6000: tady pozor. Text je nejhladší, ale opsáno doslova vyletí na 124 znaků. Model přestal vymýšlet a začal recitovat trénovací text zpaměti.

Nikdo modelu neřekl jediné pravidlo češtiny. Naučil se mezery, slova, interpunkci i švejkovský tón jen z toho, že hádal další znak a sjížděl z kopce chyby. To je celé strojové učení v jedné animaci.

Opsal to, nebo vymyslel?

Tohle je jádro věci a stojí za to se u něj zastavit, protože je snadné nechat se napálit. Když ti model vyplivne hladkou švejkovskou větu, jak poznáš, jestli ji vymyslel, nebo jenom doslova opsal kus trénovacího textu?

Změříme to. Vezmeme vygenerovaný text a najdeme nejdelší souvislý úsek, který je doslova i v korpusu. Když je ten úsek krátký (pár slov), model očividně skládá něco vlastního. Když je dlouhý (celé věty), jen recituje.

A přesně tohle je rozdíl mezi učením a memorováním:

  • Generalizace (učení): model se naučil obecné vzorce jazyka a skládá nové, nikdy neviděné věty. Tohle chceme.
  • Memorování (overfitting): model má tolik kapacity a tak málo dat, že si rovnou zapamatuje celý korpus a přehrává ho. Vypadá to chytře, ale je to drahá vyhledávací tabulka.

Náš malý model na malém korpusu sklouzne k memorování, když ho trénuješ moc dlouho. To není chyba kódu, je to základní jev. A je to důvod, proč v kódu níž trénujeme jen do chvíle, kdy model vymýšlí, a ne dokud začne opisovat.

Celý mini-GPT v kódu

A teď to hlavní. Tady je celý mini-GPT, od korpusu po generování, ve zhruba 150 řádcích čistého numpy. Embeddingy, pozice, attention, blok, cross-entropy, ruční gradient descent i sampling. Na konci ti vypíše vygenerovaný text a změří, kolik z něj doslova opsal.

Klikni Run. Je to opravdový trénink, takže to chvíli poběží (řádově půl minuty, plus první načtení numpy). Pak uvidíš švejkovinu i důkaz, že si ji model složil sám.

python · pyodide

To je ono. Celý jazykový model, od nuly, který se právě naučil psát švejkovinu. A ten poslední řádek je důkaz: pokud opsal jen pár desítek znaků z dvou stovek, zbytek opravdu složil sám. Není to vyhledávací tabulka, je to model, který se naučil vzorce.

A když mu dáme celou knihu?

Korpus v kódu výš je malý a model se ho při delším tréninku naučí nazpaměť. Co se stane, když mu místo pár vět dáme celého Švejka, všech 1,2 milionu znaků? Stáhl jsem celou knihu z Wikisource (je public domain) a natrénoval na ní ten samý model. Můžeš si ji celou přečíst i stáhnout tady.

Stane se přesně to, co od učení chceme: model úplně přestane opisovat. Z 270 vygenerovaných znaků teď bere doslova z knihy jen 16. Tak velký text si prostě nemá jak zapamatovat, takže je donucen se učit obecné vzorce. Vypadá to takhle:

pan švejk za stál poručík dub neděli musí vodu věděl … povídal, že je tak se na říkalice, a který se přemýšlí pokračoval…

Je to drsné, uznávám. Ale podívej se, co se děje: jsou to skutečná česká slova ze švejkovského světa (poručík, neděli, nemocní, pána), poskládaná do vět, které v knize nikdy nebyly. Opsaných 16 znaků z 270 je tvrdý důkaz, že model negeneruje opisováním, ale ze vzorců. Jen je na souvislý smysl moc malý: jeden blok, pár set tisíc parametrů.

A to je celé finále v kostce. Aby ten samý model skládal vzorce do smysluplných vět, musel by být mnohem, mnohem větší. Rozdíl mezi „pan švejk za stál poručík dub" a odstavcem od ChatGPT není jiný nápad. Je to měřítko.

Co se vlastně stalo

Stojí za to se zastavit. Dali jsme stroji hromadu textu a jednoduchý úkol: hádej další znak. Žádná pravidla, žádný slovník, žádná gramatika. A on se z čistě statistického tlaku naučil mezery, slova, interpunkci, větnou stavbu i Haškův tón. A skládá z toho věty, které v knize nikdy nebyly.

Přesně tohle dělá GPT-4. Vážně. Stejný úkol (hádej další token), stejná architektura (transformer bloky na sobě), stejné učení (cross-entropy a gradient descent). Všechno, co jsi v kurzu postavil, v něm je taky. Liší se jen měřítkem, přesně jak jsi viděl o kousek výš na celé knize: víc dat a větší model dělí roztomilé švejkovské blábolení od nástroje, co umí psát kód.

Proč zrovna char-level a tak malý model

Kdybychom šli po tokenech jako lekce 2 a měli větší model i korpus, výstup by byl o dost hladší. My jdeme po znacích a malý, aby se to celé stihlo v prohlížeči za půl minuty a abys viděl každý řádek kódu. Ta cena za jednoduchost je, že model občas vyrobí slovo, co neexistuje. Ber to jako roztomilý rys GPT-0.001.

Cvičení

Cvičení · lekce10-cv1

Generování je autoregresivní: model vyrobí jeden znak, přilepí ho ke kontextu a jede znovu. Kolik forward passů potřebuješ na vygenerování 100 znaků?

Cvičení · lekce10-cv2

Slovník má 40 znaků (tolik jich kód vypíše). Náhodný (nenatrénovaný) model hádá rovnoměrně. Jaký bude zhruba jeho počáteční cross-entropy loss? (Nápověda: je to ln(40), a kód ti to ukáže v prvním kroku.)

Cvičení · lekce10-cv3

V dashboardu nahoře přetoč trénink až na krok 6000. Kolik znaků tam model opisuje doslova z korpusu? (To číslo je důkaz overfittingu.)

Cvičení · lekce10-cv4

Pusť kód výš. Jakou nejlepší nebo nejpodivnější větu ti mini-GPT vyplivl? A kolik znaků podle posledního řádku opsal doslova? Napiš sem obojí.

Shrnutí

  • Mini-GPT je všechno z kurzu pohromadě: embeddingy a pozice, transformer blok, závěrečná vrstva na logity, softmax. Trénuje se jako bigram.
  • Generuje se autoregresivně, znak po znaku.
  • Rozdíl mezi generalizací a memorováním je celá hra. Měříme ho délkou doslova opsaného úseku.
  • Malý model na malém korpusu sklouzne k overfittingu (memoruje). Únik je víc dat, než se vejde do paměti.
  • Proto jsou opravdové modely obří. Stejný nápad jako tvůj mini-GPT, jiné měřítko.

Co bude příště

Postavil sis vlastní GPT a na vlastní oči viděl, kde naráží. Zbývá jediná, bonusová lekce, čistě na čtení.

V Lekci 11 (Co dělá GPT-4 jiné) si projdeme, co všechno se mezi naším mini-GPT a opravdovým chatbotem ještě děje: obří měřítko a data (přesně ten lék na memorování, co jsme tu odhalili), instruction tuning a RLHF.