Až doteď kurz říkal „za každou chybu se váhy trošku poopraví“. Tady se podíváme, co to přesně znamená. Je to motor celého učení a stojí na dvou věcech: čísle, které měří, jak moc se model spletl (loss), a na návodu, kterým směrem každý parametr posunout (gradient). Kdo tohle pochopí, přestane vnímat trénink jako magii.
Loss: jedno číslo, které měří chybu
Model pro každou pozici vydá pravděpodobnosti přes celý slovník. Známe správný token (je jím prostě ten další v textu), takže se stačí podívat, jakou pravděpodobnost mu model přidělil.
Používá se cross-entropy loss:
loss = −log p(správný token)
model dal správnému tokenu 90 % → −log(0,9) = 0,105 (malá chyba)
model dal správnému tokenu 10 % → −log(0,1) = 2,303 (velká chyba)
model dal správnému tokenu 1 % → −log(0,01) = 4,605 (katastrofa)
Logaritmus tam je proto, aby jistý omyl bolel násobně víc než mírná nejistota. Model se tak neučí jen „hádat správně“, ale i „nebýt sebejistý, když si nejsem jistý“.
Celková loss je průměr přes všechny pozice v dávce. Když se u modelu mluví o „loss 2,1“, znamená
to, že správnému tokenu dává v průměru pravděpodobnost kolem e⁻²·¹ ≈ 12 %. Vztah k perplexitě
rozebírá kapitola metriky.
💡 Všimni si, že není potřeba žádné anotování. Správná odpověď je vždycky další token v textu. Proto se dá trénovat na libovolném množství surového textu, a proto se tomu říká self-supervised učení.
⏩ Loss se nepočítá jen pro poslední token, ale pro každou pozici v sekvenci naráz, proč to jde a co z toho plyne, rozebírá trénink vs generování.
Gradient: kterým směrem posunout každý parametr
Gradient je odpověď na otázku: „Když tenhle jeden parametr nepatrně zvětším, loss vzroste, nebo klesne a jak rychle?“ Je to derivace loss podle daného parametru.
gradient parametru w = +0,3 → zvětšení w loss zvýší → posuň w dolů
gradient parametru w = −1,2 → zvětšení w loss sníží → posuň w nahoru (a víc)
gradient parametru w = 0,0 → na tomhle parametru teď nezáleží
Model má miliardy parametrů, takže gradient je vektor o miliardách čísel, pro každý parametr jeden. A spočítá se naráz jedním průchodem zpět.
🧮 Celý výpočet na jednom neuronu s konkrétními čísly najdeš v backprop ručně.
Forward počítá výsledek, backward počítá vinu. Obojí stojí zhruba stejně, proto se říká, že jeden krok tréninku vyjde na trojnásobek ceny jednoho forwardu.
Backpropagation: gradient bez šílených nákladů
Naivně by se muselo pro každý parametr zkusit, co udělá jeho změna, miliardy průchodů modelem. Backprop to řeší řetízkovým pravidlem: gradient se propaguje od loss zpátky vrstvu po vrstvě a každá vrstva ho jen „přeloží“ pro tu předchozí.
FORWARD → vstup → vrstva 1 → vrstva 2 → … → vrstva N → loss
BACKWARD ← gradienty ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ←
Cena backwardu je zhruba dvojnásobek forwardu, takže jeden trénovací krok stojí asi třikrát tolik co inference téhož vstupu.
Proč trénink žere tolik paměti
Tohle je nejčastější překvapení: model, který se do karty vejde k inferenci, se do ní nevejde k tréninku. Důvod je v tom, co všechno je potřeba držet:
| Co | Velikost pro model 7 B |
|---|---|
| Váhy (bf16) | 14 GB |
| Gradienty (bf16) | 14 GB |
| Stavy optimizeru (fp32, viz optimizer) | ~56 GB |
| Aktivace z forwardu (potřebné pro backward) | jednotky až desítky GB |
Dohromady klidně desetinásobek velikosti samotného modelu. Odtud plyne celý cirkus kolem distribuovaného tréninku a technik jako LoRA, které trénují jen malý přídavek místo celého modelu.
Gradient checkpointing je kompromis: část aktivací se neuloží a při backwardu se dopočítá znovu. Ušetří výrazně paměti za cenu zhruba 30 % času navíc.
Krok učení celý dohromady
1. vezmi dávku textu
2. FORWARD: spočítej předpovědi a loss
3. BACKWARD: spočítej gradient pro každý parametr
4. UPDATE: posuň parametry proti gradientu (o kolik, řeší optimizer)
5. opakuj, statisíckrát až milionkrát
Celý pretraining velkého modelu je tohle, spuštěné na tisících GPU po dobu týdnů.
Co se může pokazit
- Divergence. Příliš velký krok učení a loss vystřelí do nebe; model se z toho nemusí vzpamatovat.
- Loss spike. Náhlý skok kvůli nešťastné dávce dat nebo numerické nestabilitě. Provozně se řeší návratem k poslednímu uloženému bodu a přeskočením problémové dávky.
- Vanishing gradient. U hlubokých sítí gradient cestou dolů zmizí. Přesně tomuhle brání residual spojení a pre-norm (normalizace).
- Přeučení (overfitting). U pretrainingu na bilionech tokenů prakticky nehrozí (model vidí většinu dat jednou), zato u fine-tuningu na malé sadě je to hlavní riziko.
Cvičení
- Model přiřadil správnému tokenu pravděpodobnost 0,25. Jaká je loss? A jaká perplexita odpovídá průměrné loss 1,6?
- Trénuješ model 3 B v bf16 s AdamW. Odhadni paměť na váhy, gradienty a stavy optimizeru. Vejde se to na kartu s 80 GB i s aktivacemi?
- Proč nemá smysl počítat loss z pozice, která je maskovaná (padding)?
Náčrt řešení: rozbal, až si cvičení zkusíš sám
- Loss
1,386a perplexita4,95. Loss je−ln(0,25) = 1,3863. Perplexita jee^loss, takžee^1,6 = 4,953. Čte se to jako „model je v průměru na rozpacích mezi zhruba pěti možnostmi“, což je mimochodem docela dobrý model. - Zhruba 36 GB, takže se to vejde, ale ne s velkou rezervou. Váhy v bf16
3 × 2 = 6 GB, gradienty taky6 GB, stavy AdamW ve fp323 × 8 = 24 GB. Aktivace přidají jednotky až desítky GB podle délky sekvence a velikosti dávky, takže na kartě s 80 GB to projde, ale s velkou dávkou nebo dlouhým kontextem začneš potřebovat gradient checkpointing. - Protože na takové pozici není co predikovat. Padding je jen výplň do stejné délky, žádný skutečný následující token tam neexistuje. Kdybys loss z těch pozic počítal, model by se učil předpovídat výplň a zároveň bys si zředil průměr, takže by gradient ze skutečných tokenů byl slabší. Maskované pozice se proto z průměru vyhazují úplně.
Shrnutí
- Loss =
−logpravděpodobnosti správného tokenu; jistý omyl trestá násobně víc. - Správná odpověď je vždy další token v textu, proto není potřeba anotovat data.
- Gradient říká pro každý parametr, kterým směrem a jak moc ho posunout; počítá backprop.
- Trénink potřebuje řádově víc paměti než inference kvůli gradientům, stavům optimizeru a aktivacím.
Model přiřadil správnému tokenu pravděpodobnost 10 %. Jaká je loss a co znamená?
Loss je −log(0,1) ≈ 2,3. Znamená to, že model byl na správné odpovědi dost nejistý. Kdyby jí dal 90 %, byla by loss 0,1; kdyby 1 %, byla by 4,6, logaritmus zajišťuje, že sebejistý omyl bolí mnohem víc než mírná nejistota.
Proč se trénink LLM označuje jako self-supervised, když se model něco „učí“?
Protože správná odpověď se nemusí anotovat, je jí prostě další token v textu. Trénovací signál si tak model bere přímo z dat, takže se dá použít libovolné množství surového textu bez lidské práce navíc.
Model 7 B se ti vejde do karty na inferenci, ale trénink spadne na nedostatek paměti. Proč?
Kromě vah je potřeba držet gradienty, stavy optimizeru (typicky ve fp32, tedy několikanásobek vah) a aktivace z forwardu potřebné pro backward. Dohromady to bývá řádově desetinásobek velikosti modelu, proto se trénuje distribuovaně nebo jen přes adaptéry typu LoRA.
