---
title: "Anatomia LLM: sieci, parametry i trening"
date: 2026-06-10
description: "Bierzemy garść neuronów i układamy je w sieć: dlaczego cały model sprowadza się do mnożenia macierzy, jak propagacja wsteczna zamienia losowy szum w rozumienie języka, skąd biorą się słynne miliardy parametrów i co naprawdę mówią prawa skalowania Kaplana i Chinchilli - z wzorami, genezą i konkretami."
tags: ["anatomia llm", "ai", "llm", "sieci neuronowe", "deep-dive"]
---

## 🚀 Intro

W [poprzednim przystanku tej serii](/posty/llm-neuron-i-aktywacje) - jednej z gałęzi [przeglądowego wpisu „Anatomia LLM"](/posty/anatomia-llm) - rozłożyliśmy najmniejszą cegiełkę: pojedynczy sztuczny neuron i to drobne „wygięcie" na jego wyjściu, które nazywamy funkcją aktywacji. Zobaczyliśmy, że cegiełka jest **drastyczną karykaturą** biologii - i że mimo to coś z niej wyrasta. Teraz bierzemy garść tych karykatur i robimy z nimi dwie rzeczy: układamy je w **warstwy i sieć**, a potem zadajemy pytanie, które jest sednem całej dziedziny - **skąd właściwie biorą się te słynne „miliardy parametrów" i jak trening zamienia losowy szum w model, który rozumie język**.

To jest przystanek o maszynerii. Zobaczymy, że cała sieć - cały GPT, cała LLaMA - sprowadza się do jednej operacji powtarzanej miliardy razy: **mnożenia macierzy**. Że uczenie to nic więcej niż wielokrotne, mikroskopijne poprawianie wag w kierunku wskazanym przez pochodną. I że za hasłem „7B parametrów" stoi konkretny, policzalny wzór.

A jednak - i to jest motyw, który ciągnie się przez całą serię - z tej buchalterii wyłania się coś, czego żaden z tych wzorów nie zamawia wprost. Cel treningu brzmi prozaicznie: „przewiduj następny token najlepiej, jak potrafisz". Nikt nie pisze w funkcji straty „naucz się rozumować". A jednak, gdy ten nacisk działa wystarczająco długo na wystarczająco dużym substracie, zdolność do rozumowania się pojawia. Wrócimy do tego pod koniec - bo to właśnie tu, w treningu, mieszka jedna z najgłębszych zagadek tej maszynerii.

> 💡 **Jak czytać ten tekst.** Główny wątek jest opisowy i samowystarczalny. Wzory chowam w rozwijanych blokach „dla dociekliwych" - jeśli lubisz matematykę, rozwiń; jeśli nie, pomiń bez straty dla zrozumienia. Wszystkie twierdzenia mają przypisy do prac źródłowych na końcu.


## 📋 TL;DR

- **Cała sieć to mnożenia macierzy.** Warstwa liczy $h = f(Wx+b)$, a w treningu przetwarza się całe paczki danych naraz - stąd jedna operacja, **GEMM** (mnożenie macierzy), do której sprowadza się niemal całe obliczenie. Dlatego króluje sprzęt (GPU/TPU) wyspecjalizowany właśnie w mnożeniu macierzy.
- **Sieć uczy się propagacją wsteczną** (Rumelhart, Hinton, Williams, 1986). To sprytne zastosowanie reguły łańcuchowej: jednym przejściem od wyjścia do wejścia liczy się, jak każda waga wpłynęła na błąd.
- **Czego się uczy?** Minimalizuje **cross-entropy** - karę za zdziwienie właściwym następnym tokenem. Jej wykładnicza forma, **perplexity**, mówi, „wśród ilu opcji" model się waha.
- **Jak uczy się szybciej?** Optymalizatory: od surowego SGD, przez Momentum, po **Adam** i **AdamW** - dziś domyślny w treningu LLM. Plus harmonogram tempa uczenia: warmup i cosine.
- **Skąd „miliardy parametrów"?** Z prostego wzoru: $N \approx 12\,n_{layer}\,d_{model}^2$. Około 2/3 wag siedzi w blokach FFN, 1/3 w mechanizmie uwagi.
- **Prawa skalowania.** Kaplan (2020) pokazał, że strata maleje wg prawa potęgowego z rozmiarem, danymi i mocą. **Chinchilla** (2022) skorygowała wniosek: model i dane skaluj **równo** - ok. **20 tokenów na każdy parametr**.
- Część z tego możesz **dotknąć** na [stronie interaktywnej](/llm/anatomia#siec).


## 🕸️ Od neuronu do sieci: wszystko jest mnożeniem macierzy

W poprzednim wpisie neuron liczył sumę ważoną jednego zestawu wejść. Ale sieć nie ma jednego neuronu - ma ich tysiące w jednej warstwie, a warstw są dziesiątki. Gdyby liczyć każdy neuron osobno, w pętli, byłoby to rozpaczliwie wolne. Na szczęście cała warstwa daje się zapisać jako **jedna operacja na macierzach**: wszystkie wagi neuronów warstwy układamy w jedną macierz $W$, mnożymy ją przez wektor wejść, dodajemy bias i przepuszczamy przez aktywację. Jeden zapis, $h = f(Wx+b)$, obejmuje całą warstwę naraz.

W praktyce idziemy o krok dalej. Podczas treningu nie podajemy modelowi jednego przykładu, tylko całą **paczkę** (batch) naraz - dziesiątki czy setki przykładów ułożonych w macierz. Wtedy nawet wejście staje się macierzą, a obliczenie warstwy to mnożenie macierzy przez macierz. Ta operacja ma swoją nazwę: **GEMM** (General Matrix Multiplication, czyli ogólne mnożenie macierzy). I to jest klucz do zrozumienia, dlaczego LLM-y w ogóle są wykonalne.

Dokumentacja NVIDIA mówi wprost, że GEMM-y są „fundamentalnym blokiem konstrukcyjnym wielu operacji w sieciach neuronowych"[^nvidia-gemm]. Niemal całe obliczenie sieci - przez wszystkie warstwy, dla całej paczki - sprowadza się do dużych, gęstych mnożeń macierzy. A mnożenie macierzy ma cudowną właściwość: **daje się masowo zrównoleglić**. Każdy element wyniku można liczyć niezależnie. Dokładnie do tego stworzone są karty graficzne (GPU) i układy TPU - mają tysiące rdzeni liczących równolegle, a nowoczesne GPU NVIDIA dodatkowo **Tensor Cores**, wyspecjalizowane wyłącznie w mnożeniu tensorów[^nvidia-gemm]. To nie przypadek, że firma od kart do gier stała się sercem rewolucji AI: gry i sieci neuronowe potrzebują tego samego - błyskawicznego mnożenia macierzy.

Jest jeszcze jeden trik, który sprawia, że to wszystko mieści się w pamięci i liczy się szybciej: **obniżona precyzja liczb**. Zamiast trzymać każdą wagę jako 32-bitową liczbę zmiennoprzecinkową, używa się formatów 16-bitowych - zwłaszcza **BF16** (bfloat16), który zachowuje pełny zakres wartości kosztem dokładności po przecinku[^kalamkar]. Połowa bitów to połowa pamięci i często rząd wielkości szybsze obliczenia.

<details>
<summary>📐 Dla dociekliwych: warstwa jako mnożenie macierzy i precyzja liczb</summary>

Pojedyncza warstwa w pełni połączona to $h = f(Wx + b)$. Gdy przetwarzamy paczkę $B$ przykładów naraz, wejście jest macierzą $X \in \mathbb{R}^{B \times d_{wej}}$, a całą warstwę liczymy jednym mnożeniem:

$$ H = f(XW + b) $$

To właśnie GEMM. Symbol $f$ działa „po współrzędnych" - na każdym elemencie osobno (to nasza funkcja aktywacji z poprzedniego wpisu).

Precyzja zmiennoprzecinkowa to kompromis pamięć/szybkość/dokładność:

- **FP32** - pełna, 32-bitowa precyzja (punkt odniesienia).
- **FP16** - 16-bitowa „połówkowa".
- **BF16** (bfloat16) - również 16-bitowa, ale ma ten sam 8-bitowy *wykładnik* co FP32 (czyli ten sam zakres wartości), poświęcając bity *mantysy* (dokładności)[^kalamkar]. Dzięki temu zwykle nie wymaga sztuczek typu „loss scaling" przy treningu w mieszanej precyzji.

Typowy schemat mixed-precision: wejścia w FP16/BF16, ale akumulacja sumy w FP32, żeby nie gubić dokładności w długich sumach. Dla porównania skali: na układzie NVIDIA A100 przepustowość Tensor Core w BF16/FP16 sięga ok. 312 bilionów operacji na sekundę, wobec ok. 19,5 w FP32 - rząd wielkości różnicy[^tflops].

</details>

👉 **Pobaw się:** na stronie interaktywnej masz [diagram warstw i sieci](/llm/anatomia#siec) - zobaczysz, jak sygnał płynie przez kolejne warstwy neuronów.


## 🔁 Jak sieć się uczy: propagacja wsteczna

Mamy już sieć - stos warstw, każda będąca mnożeniem macierzy. Ale świeżo zbudowana sieć ma wagi ustawione **losowo**: na jej wyjściu jest czysty szum. Jak zamienić ten szum w coś, co rozumie język? Odpowiedź to algorytm, który jest sercem całego głębokiego uczenia: **propagacja wsteczna** (backpropagation).

Pomysł spopularyzowała klasyczna praca Rumelharta, Hintona i Williamsa z 1986 roku, której procedura „wielokrotnie dostosowuje wagi połączeń w sieci tak, aby zminimalizować miarę różnicy między rzeczywistym wektorem wyjściowym a wektorem pożądanym"[^rumelhart]. Po polsku: pokaż sieci przykład, zmierz, jak bardzo się pomyliła, a potem **delikatnie pchnij każdą wagę** w stronę, która tę pomyłkę zmniejsza. Powtórz miliardy razy.

Cały spryt siedzi w słowie „wstecz". Pomyłkę znamy na **wyjściu** sieci - tam porównujemy odpowiedź z oczekiwaną. Ale poprawić musimy wagi we **wszystkich** warstwach, też tych najwcześniejszych, daleko od wyjścia. Naiwnie trzeba by dla każdej z miliardów wag osobno policzyć „jak zmiana akurat ciebie wpłynie na błąd". To byłoby beznadziejnie kosztowne. Propagacja wsteczna robi to sprytniej: korzystając z **reguły łańcuchowej** z rachunku różniczkowego, przepuszcza sygnał błędu raz, od wyjścia do wejścia, **wielokrotnie wykorzystując** rachunki już wykonane dla warstw późniejszych. Jedno przejście wstecz zamiast miliardów osobnych - i to jest powód, dla którego trening jest w ogóle wykonalny.

Wynikiem tego przejścia jest **gradient** - oznaczany symbolem nabla, $\nabla L$ (nabla, odwrócony trójkąt). Gradient to wektor, który dla każdej wagi mówi dwie rzeczy: w którą stronę ją zmienić i jak mocno, żeby błąd zmalał. Mając gradient, sama poprawka jest banalna: przesuń każdą wagę o mały krok w stronę przeciwną do gradientu (bo gradient wskazuje, gdzie błąd rośnie, a my chcemy go zmniejszać).

I tu wraca motyw z poprzedniego wpisu - różnica między „rozwiązanie istnieje" a „umiemy je znaleźć". Twierdzenie o uniwersalnej aproksymacji obiecywało, że *istnieje* zestaw wag dający dobrą sieć. Propagacja wsteczna to narzędzie, którym tych wag **szukamy**. Ale szukamy po omacku, schodząc w dół po pofalowanym, niewypukłym krajobrazie błędu, pełnym dolin i grzbietów. Nikt nie gwarantuje, że dojdziemy do najgłębszej doliny. Zdumiewające - i wciąż nie do końca rozumiane - jest to, że w praktyce dochodzimy do *dostatecznie dobrej*.

<details>
<summary>📐 Dla dociekliwych: reguła łańcuchowa i przepływ błędu</summary>

Dla warstwy $z^{(l)} = W^{(l)} a^{(l-1)} + b^{(l)}$, $a^{(l)} = f(z^{(l)})$ wprowadza się **sygnał błędu** $\delta^{(l)}$ (delta) - pochodną straty względem wejścia warstwy, $\delta^{(l)} = \partial L / \partial z^{(l)}$. Propaguje się on wstecz wzorem:

$$ \delta^{(l)} = \left( (W^{(l+1)})^\top \delta^{(l+1)} \right) \odot f'(z^{(l)}) $$

Symbol $\top$ to transpozycja macierzy (zamiana wierszy z kolumnami), a $\odot$ to mnożenie „po współrzędnych" (element po elemencie). Kluczowe jest to, że $\delta^{(l)}$ liczy się z gotowego już $\delta^{(l+1)}$ z warstwy *następnej* - stąd „wstecz" i stąd efektywność.

Mając sygnał błędu, gradienty wag i biasów to:

$$ \frac{\partial L}{\partial W^{(l)}} = \delta^{(l)} (a^{(l-1)})^\top, \qquad \frac{\partial L}{\partial b^{(l)}} = \delta^{(l)} $$

Pełne wyprowadzenie: Goodfellow, Bengio, Courville, *Deep Learning*, rozdz. 6.5[^goodfellow].

</details>


## 🎯 Czego sieć się uczy: funkcja straty

Powiedzieliśmy „zmniejszaj błąd". Ale czym dokładnie jest „błąd" dla modelu języka? Tu trzeba sobie uświadomić, co LLM właściwie robi: w każdym kroku patrzy na dotychczasowy tekst i **przewiduje następny token** - zwraca rozkład prawdopodobieństwa nad całym słownikiem (np. „po słowach 'kot wszedł na' z prawdopodobieństwem 30% pada 'dach', 12% 'drzewo', 0,001% 'całka'…"). Trening polega na tym, żeby model przypisywał **wysokie prawdopodobieństwo temu tokenowi, który naprawdę wystąpił**.

Miarą tego jest **cross-entropy** (entropia krzyżowa), zwana też negative log-likelihood (NLL). Intuicja jest piękna w swojej prostocie: kara to **zdziwienie modelu właściwą odpowiedzią**. Jeśli model przypisał prawdziwemu następnemu tokenowi prawdopodobieństwo bliskie 1 („spodziewałem się tego") - kara jest bliska zera. Jeśli przypisał mu prawdopodobieństwo bliskie 0 („to mnie zaskoczyło") - kara strzela w górę. Uśredniamy to zdziwienie po całym tekście i mamy stratę, którą propagacja wsteczna każe minimalizować. Praca o prawach skalowania bada wprost właśnie „stratę cross-entropy" jako podstawową metrykę[^kaplan].

Z tej samej liczby wyprowadza się popularniejszą, bardziej namacalną miarę: **perplexity**. To po prostu wykładnicza forma średniego zdziwienia. Interpretuje się ją jako efektywną liczbę równoprawdopodobnych opcji, między którymi model się waha przy każdym tokenie. Perplexity 10 znaczy z grubsza „model jest tak niepewny, jakby losował spośród 10 jednakowo prawdopodobnych słów". Im niższa, tym lepszy model - perplexity 1 to wszechwiedza (zawsze typuje pewnie i trafnie).

<details>
<summary>📐 Dla dociekliwych: cross-entropy, NLL i perplexity</summary>

Model zwraca rozkład $p_\theta(x_t \mid x_{<t})$ - prawdopodobieństwo tokenu $x_t$ pod warunkiem wszystkiego, co było wcześniej. Strata to średnia ujemna logarytmów prawdopodobieństw prawdziwych tokenów:

$$ L = -\frac{1}{T} \sum_{t=1}^{T} \log p_\theta(x_t \mid x_{<t}) $$

Dla pojedynczej pozycji to entropia krzyżowa między rozkładem prawdziwym (jedynka na właściwym tokenie, zera gdzie indziej) a przewidywanym: $-\sum_v y_v \log \hat{p}_v$. Logarytm sprawia, że bliskie zeru prawdopodobieństwo daje stratę dążącą do nieskończoności - stąd „zdziwienie".

**Perplexity** to ta sama liczba w innym przebraniu:

$$ \text{PPL} = \exp\!\left( -\frac{1}{T} \sum_{t=1}^{T} \log p_\theta(x_t \mid x_{<t}) \right) = \exp(L) $$

czyli po prostu $\exp$ ze straty. Stąd interpretacja „efektywnej liczby opcji": dla rozkładu jednostajnego na $k$ tokenach perplexity wynosi dokładnie $k$.

</details>


## ⚙️ Jak sieć się uczy szybciej: optymalizatory

Mamy gradient (z propagacji wstecznej) i mamy stratę (cross-entropy). Pozostaje pytanie taktyczne: **jak dokładnie aktualizować wagi**? Najprostsza odpowiedź to **SGD** (stochastyczny spadek gradientu): odejmij od każdej wagi gradient pomnożony przez mały współczynnik $\eta$ (eta), zwany **tempem uczenia** (learning rate). To działa, ale bywa wolne i kapryśne - jak schodzenie ze stromej góry drobnymi, sztywnymi kroczkami, które łatwo prowadzą do dreptania w bok zamiast w dół.

Pierwsze ulepszenie to **Momentum** (pęd). Zamiast kierować się tylko bieżącym gradientem, kula pamięta, dokąd się toczyła - bierze wygładzoną średnią ostatnich gradientów. Dzięki temu rozpędza się w stałym kierunku i wygładza drgania. Sterowane jest to współczynnikiem $\beta$ (beta).

Prawdziwy przełom przyniósł **Adam** (Kingma i Ba, 2015)[^kingma]. Jego pomysł: **każda waga dostaje własne, adaptacyjne tempo uczenia**. Adam śledzi dwie wygładzone statystyki gradientu - jego średni kierunek (moment pierwszego rzędu) i typową wielkość (moment drugiego rzędu) - i dzieli krok przez tę wielkość. Efekt: wagi, których gradient jest stale duży, dostają mniejsze kroki (żeby nie przestrzelić), a te o małym gradiencie - większe (żeby ruszyły z miejsca). Adam jest odporny i mało wrażliwy na dobór parametrów, co uczyniło go domyślnym wyborem na lata.

Dzisiejszym standardem treningu LLM jest jego poprawka, **AdamW** (Loshchilov i Hutter)[^loshchilov]. Różnica jest subtelna, ale ważna: dotyczy **weight decay** - delikatnego „ściągania" wag w stronę zera, które zapobiega ich rozrostowi (forma regularyzacji, o której za chwilę). Autorzy pokazali, że w oryginalnym Adamie ten mechanizm był spleciony z adaptacyjnym tempem w sposób, który mu szkodził, i zaproponowali jego **odsprzęgnięcie** od kroku gradientowego. Brzmi jak detal księgowy, ale w praktyce zauważalnie poprawia jakość - dlatego „W" w nazwie jest dziś wszędzie.

Na koniec jeszcze jedno: tempo uczenia $\eta$ zwykle **nie jest stałe** w czasie treningu. Na początku stosuje się **warmup** - tempo rośnie liniowo od niemal zera, żeby nie rozwalić świeżej, losowej sieci zbyt gwałtownymi krokami (ten trik pojawił się już w oryginalnym Transformerze[^vaswani]). Potem tempo łagodnie maleje, najczęściej wg **krzywej kosinusowej** (cosine schedule) - tak trenowano m.in. modele Chinchilli[^hoffmann]. Obrazowo: najpierw rozgrzewka drobnymi krokami, potem pełny krok, a na końcu coraz ostrożniejsze stąpanie, gdy zbliżamy się do dna doliny.

<details>
<summary>📐 Dla dociekliwych: od SGD do AdamW, plus harmonogram tempa</summary>

**SGD:** $w \leftarrow w - \eta \, \nabla_w L$, gdzie $\eta$ to tempo uczenia.

**Momentum** dodaje wygładzoną średnią gradientów (pęd), sterowaną przez $\beta$ (beta):

$$ v \leftarrow \beta v + \nabla_w L, \qquad w \leftarrow w - \eta \, v $$

**Adam** utrzymuje estymaty momentu pierwszego ($m$) i drugiego ($v$) rzędu, z dwoma współczynnikami wygładzania $\beta_1$ (beta jeden) i $\beta_2$ (beta dwa):

$$ m_t = \beta_1 m_{t-1} + (1-\beta_1) g_t, \qquad v_t = \beta_2 v_{t-1} + (1-\beta_2) g_t^2 $$
$$ \hat{m}_t = \frac{m_t}{1-\beta_1^t}, \qquad \hat{v}_t = \frac{v_t}{1-\beta_2^t}, \qquad w_t = w_{t-1} - \eta \, \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} $$

Symbol $\epsilon$ (epsilon) to maleńka stała chroniąca przed dzieleniem przez zero. Domyślne wartości z pracy: $\beta_1 = 0{,}9$, $\beta_2 = 0{,}999$, $\epsilon = 10^{-8}$[^kingma].

**AdamW** odsprzęga weight decay (sterowany przez $\lambda$, lambda) od kroku gradientowego - dopisuje go osobno, zamiast wpychać do gradientu:

$$ w_t = w_{t-1} - \eta \left( \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} + \lambda \, w_{t-1} \right) $$

**Cosine schedule** - po warmupie tempo maleje wg krzywej kosinusowej od $\eta_{max}$ do $\eta_{min}$:

$$ \eta_t = \eta_{min} + \tfrac{1}{2}(\eta_{max} - \eta_{min})\left(1 + \cos\!\left(\tfrac{t}{T_{max}}\pi\right)\right) $$

</details>


## 📈 Skąd „miliardy parametrów" i dokąd zmierza skalowanie

Dochodzimy do hasła, które słyszał każdy: „7B", „70B", „405B". To liczba **parametrów** - czyli wszystkich wag i biasów, które trening dostraja. Skąd się bierze akurat tyle? Okazuje się, że da się to policzyć jednym, zaskakująco prostym wzorem. Dla transformera liczba parametrów (pomijając embeddingi) wynosi w przybliżeniu $N \approx 12\,n_{layer}\,d_{model}^2$, gdzie $n_{layer}$ to liczba warstw, a $d_{model}$ to „szerokość" modelu[^kaplan]. Cała tajemnica „miliardów" to po prostu ten iloczyn: kilkadziesiąt warstw razy kwadrat szerokości, razy stały współczynnik.

Co ciekawe, ten współczynnik 12 ma czytelną strukturę: około **2/3 wszystkich parametrów warstwy siedzi w blokach FFN** (gęstych warstwach „przetwarzających"), a tylko 1/3 w mechanizmie uwagi - tym samym, który uchodzi za sedno transformera. To dobra lekcja pokory wobec intuicji: większość „masy" modelu jest nie tam, gdzie większość uwagi (nomen omen) komentatorów. Do samego mechanizmu uwagi dojdziemy w jednym z kolejnych wpisów serii.

Skoro umiemy policzyć parametry, pojawia się pytanie za miliard dolarów (dosłownie, bo tyle kosztują treningi): **czy większy zawsze znaczy lepszy, i jak rozdzielić budżet?** Pierwszą poważną odpowiedź dała praca Kaplana i współpracowników z OpenAI (2020). Pokazała, że strata maleje przewidywalnie - wg **prawa potęgowego** - wraz ze wzrostem trzech rzeczy: rozmiaru modelu, ilości danych i mocy obliczeniowej, „z trendami rozciągającymi się przez ponad siedem rzędów wielkości"[^kaplan]. To był szok: jakość modelu dało się **przewidywać z wyprzedzeniem**, jak prawo fizyki. Wniosek Kaplana brzmiał jednak: stawiaj przede wszystkim na **rozmiar** - trenuj wielkie modele na umiarkowanej ilości danych.

Dwa lata później przyszła korekta, która zmieniła branżę: **Chinchilla** (Hoffmann i in., DeepMind, 2022). Trenując ponad 400 modeli, autorzy wykazali, że ówczesne wielkie modele były **znacząco niedotrenowane** - dostawały za mało danych jak na swój rozmiar. Kluczowy wynik: przy danym budżecie obliczeniowym rozmiar modelu i liczbę tokenów treningowych należy skalować **w równym stopniu** - „przy każdym podwojeniu rozmiaru modelu liczbę tokenów treningowych również należy podwoić"[^hoffmann]. Z tego wzięła się słynna reguła kciuka: około **20 tokenów treningowych na każdy parametr modelu**[^hoffmann]. Dowodem był sam model Chinchilla (70 mld parametrów, 1,4 bln tokenów), który przy tym samym budżecie pobił znacznie większego Gophera (280 mld) i GPT-3 (175 mld). To Chinchilla jest powodem, dla którego dzisiejsze modele trenuje się na bilionach tokenów - mniejsze, ale „nakarmione do syta".

<details>
<summary>📐 Dla dociekliwych: skąd współczynnik 12 i wzory praw skalowania</summary>

**Liczba parametrów.** Przy założeniu $d_{attn} = d_{ff}/4 = d_{model}$ Kaplan podaje (równanie 2.1)[^kaplan]:

$$ N \approx 12 \, n_{layer} \, d_{model}^2 $$

Współczynnik 12 rozkłada się tak: na warstwę przypadają cztery macierze mechanizmu uwagi (Q, K, V i projekcja wyjściowa: $4\,d_{model}^2$) oraz dwie macierze bloku FFN ($8\,d_{model}^2$), razem $12\,d_{model}^2$. Stąd proporcja 2/3 (FFN) do 1/3 (uwaga). Parametry embeddingów ($n_{vocab}\cdot d_{model}$) liczy się osobno i dla dużych modeli są relatywnie małe.

**Prawa skalowania Kaplana** - strata jako prawo potęgowe względem rozmiaru $N$ i danych $D$[^kaplan]:

$$ L(N) = \left(\frac{N_c}{N}\right)^{\alpha_N}, \quad \alpha_N \approx 0{,}076 \qquad\qquad L(D) = \left(\frac{D_c}{D}\right)^{\alpha_D}, \quad \alpha_D \approx 0{,}095 $$

gdzie $\alpha_N, \alpha_D$ (alfa) to wykładniki potęgowe.

**Parametryczna strata Chinchilli** (równanie 2)[^hoffmann] - rozkłada stratę na nieusuwalny szum $E$ plus człony malejące z rozmiarem i danymi:

$$ \hat{L}(N, D) = E + \frac{A}{N^\alpha} + \frac{B}{D^\beta} $$

z dopasowaniem $E = 1{,}69$, $A = 406{,}4$, $\alpha = 0{,}34$, $B = 410{,}7$, $\beta = 0{,}28$. To z minimalizacji tej funkcji przy stałym budżecie wychodzi reguła „skaluj $N$ i $D$ równo".

</details>

👉 **Pobaw się:** na stronie interaktywnej masz [sekcję o parametrach i wagach](/llm/anatomia#parametry) - zobaczysz, jak liczba parametrów rośnie z rozmiarem sieci.


## 🧰 Słowniczek treningu: epoka, batch, krok, przeuczenie, dropout

Zostało kilka pojęć, które wracają w każdej rozmowie o treningu - zbierzmy je w jednym miejscu, bo teraz, gdy znamy mechanizm, staną się oczywiste:

- **Batch (paczka, mini-batch)** - podzbiór danych przetwarzany jednocześnie w jednym przejściu w przód i wstecz. Gradient liczy się jako średnia po paczce - i to jest właśnie owo „stochastic" w SGD: gradient z mini-batcha to zaszumiony, ale tani estymator pełnego gradientu[^goodfellow].
- **Krok (step, iteracja)** - jedna aktualizacja wag, odpowiadająca jednej paczce.
- **Epoka (epoch)** - jedno pełne przejście przez cały zbiór treningowy. Ciekawostka skali: wielkie LLM-y trenuje się często przez znacznie **mniej niż jedną epokę** - korpus jest tak ogromny, że model nie zdąży obejrzeć go nawet raz w całości.
- **Przeuczenie (overfitting)** - model zamiast uczyć się ogólnych wzorców, „wkuwa na pamięć" szum danych treningowych. Objaw: strata treningowa spada, ale walidacyjna (na danych niewidzianych) zaczyna rosnąć[^goodfellow].
- **Regularyzacja** - rodzina technik hamujących przeuczenie: weight decay (poznany przy AdamW), early stopping, augmentacja danych i dropout[^goodfellow].
- **Dropout** (Srivastava i in., 2014) - podczas treningu losowo „wyłącza się" część neuronów (zeruje ich wyjście), co zapobiega ich nadmiernemu **współadaptowaniu się**. Każdy neuron musi radzić sobie bez gwarancji, że sąsiad będzie obecny - więc sieć uczy się odporniejszych, mniej kruchych reprezentacji. Można to interpretować jako uśrednianie wykładniczo wielu „przerzedzonych" sieci naraz[^srivastava].


## 🌗 Czego ten nacisk nie zamawiał

Zatrzymajmy się na chwilę nad tym, co właśnie opisaliśmy, bo w buchalteryjnym opisie łatwo przeoczyć rzecz najgłębszą. Cała maszyneria z tego wpisu - cross-entropy, gradient, AdamW, prawa skalowania - realizuje **jeden, prozaiczny cel**: „przewiduj następny token jak najlepiej". To wszystko. Nikt nigdzie nie zapisał „naucz się gramatyki", „zbuduj model świata", „umiej rozumować". Funkcja straty jest ślepa na te pojęcia.

A jednak one się pojawiają. Gdy ten sam nacisk - minimalizuj zdziwienie następnym tokenem - działa wystarczająco długo na wystarczająco wielkim substracie, z miliardów mnożeń macierzy **wyłaniają się** zdolności, których nikt wprost nie zamówił. To jest sedno różnicy między *mechanizmem* a *tym, co z mechanizmu wyrasta* - napięcie, które towarzyszy nam od pierwszego wpisu o neuronie-karykaturze.

Jest hipoteza, że to nie przypadek - że presja „przewiduj lepiej" jest realnym **ciśnieniem selekcyjnym**, które spycha sieć ku szczególnemu reżimowi dynamicznemu, gdzie te same mnożenia macierzy dają maksymalnie złożoną, zintegrowaną odpowiedź. Bywa on nazywany **krawędzią chaosu** albo samoorganizującą się krytycznością.[^krytycznosc] Trzeba tu jednak mocnej ostrożności - to trop, nie twierdzenie - więc całą rzecz, z zastrzeżeniami, chowam w przypisie dla tych, których kusi pójść głębiej.

Poznanie mechanizmu nie odbiera temu nic z niezwykłości. Wręcz przeciwnie - dopiero teraz, gdy wiemy, jak skromny i ślepy jest cel treningu, widać wyraźnie, jak nieoczywiste jest to, co z niego wyrasta.


## 🎯 Co dalej

Złożyliśmy sieć i pokazaliśmy, jak się uczy. Forward pass okazał się jednym wielkim mnożeniem macierzy (dlatego rządzą GPU); propagacja wsteczna - sprytnym, jednoprzebiegowym liczeniem, jak każda waga wpłynęła na błąd; cel - minimalizacją zdziwienia następnym tokenem (cross-entropy, perplexity); a „miliardy parametrów" - konkretnym wzorem $N \approx 12\,n_{layer}\,d_{model}^2$, którego skalowaniem rządzą prawa Kaplana i Chinchilli.

Jest jednak luka, którą celowo zostawiliśmy. Cały czas mówiliśmy o „przetwarzaniu tokenów" i „przewidywaniu następnego tokenu" - ale **czym właściwie jest token**, i jak model w ogóle zamienia słowa na liczby, które da się mnożyć? Bo sieć nie widzi liter. Widzi wektory. W następnym przystanku serii zaglądamy do **tokenów i embeddingów**: jak tekst rozbija się na kawałki, dlaczego nie na słowa ani nie na litery, i jak rodzi się ta słynna geometria znaczeń, w której „król - mężczyzna + kobieta ≈ królowa".

Jeśli wolisz teraz **dotknąć** zamiast czytać dalej, [interaktywna strona „Anatomia LLM"](/llm/anatomia#siec) pozwala prześledzić przepływ przez warstwy i zobaczyć, jak liczba parametrów rośnie z rozmiarem sieci. A jeśli kusi cię to, co naprawdę *wyłania się* z opisanej tu maszynerii, gdy nacisk treningu działa wystarczająco długo - [pisałem o tym osobno](/posty/rezonans-czlowiek-llm-kwantowe-lustro).


[^nvidia-gemm]: NVIDIA, *Matrix Multiplication Background User's Guide* (rola GEMM jako podstawowego bloku sieci, Tensor Cores). <https://docs.nvidia.com/deeplearning/performance/dl-performance-matrix-multiplication/index.html>
[^kalamkar]: D. Kalamkar et al. (2019). *A Study of BFLOAT16 for Deep Learning Training*. arXiv:1905.12322. <https://arxiv.org/abs/1905.12322>
[^tflops]: Orientacyjne wartości przepustowości Tensor Core (A100: ~312 TFLOP/s w BF16/FP16 wobec ~19,5 TFLOP/s w FP32) pochodzą z materiałów wtórnych opartych na specyfikacji NVIDIA i ze schematu mixed-precision z *Training With Mixed Precision User's Guide*. Traktować jako rząd wielkości, nie dokładny pomiar. <https://docs.nvidia.com/deeplearning/performance/mixed-precision-training/index.html>
[^rumelhart]: D. E. Rumelhart, G. E. Hinton, R. J. Williams (1986). *Learning representations by back-propagating errors*. Nature 323:533-536. <https://www.nature.com/articles/323533a0>
[^goodfellow]: I. Goodfellow, Y. Bengio, A. Courville (2016). *Deep Learning*, MIT Press (backprop rozdz. 6.5; mini-batche, overfitting, regularyzacja). <https://www.deeplearningbook.org/>
[^kaplan]: J. Kaplan et al. (2020). *Scaling Laws for Neural Language Models* (OpenAI). arXiv:2001.08361. <https://arxiv.org/abs/2001.08361>
[^kingma]: D. P. Kingma, J. Ba (2015). *Adam: A Method for Stochastic Optimization*. arXiv:1412.6980 (ICLR 2015). <https://arxiv.org/abs/1412.6980>
[^loshchilov]: I. Loshchilov, F. Hutter (2019). *Decoupled Weight Decay Regularization* (AdamW). arXiv:1711.05101. <https://arxiv.org/abs/1711.05101>
[^vaswani]: A. Vaswani et al. (2017). *Attention Is All You Need* (warmup tempa uczenia). arXiv:1706.03762. <https://arxiv.org/abs/1706.03762>
[^hoffmann]: J. Hoffmann et al. (2022). *Training Compute-Optimal Large Language Models* (Chinchilla). arXiv:2203.15556. <https://arxiv.org/abs/2203.15556>
[^srivastava]: N. Srivastava et al. (2014). *Dropout: A Simple Way to Prevent Neural Networks from Overfitting*. JMLR 15:1929-1958. <https://jmlr.org/papers/v15/srivastava14a.html>
[^krytycznosc]: Trop spekulatywny, podany z ostrożnością. Istnieje formalny wynik, że sieci **rekurencyjne** wykonują złożone obliczenia najlepiej dokładnie na „krawędzi chaosu" - granicy między porządkiem a chaosem (Bertschinger & Natschläger, NeurIPS 2004, <https://proceedings.neurips.cc/paper/2004/hash/6e7b33fdea3adc80ebd648fffb665bb8-Abstract.html>). Nowsze prace pokazują, że miara złożoności reakcji systemu na zaburzenie - PCIst, *Perturbational Complexity Index*, używana **klinicznie u ludzi** do oceny stanu świadomości - jest w sztucznych sieciach **maksymalna właśnie na tej krawędzi** (PMC, 2024). Kuszące jest odczytanie celu treningu („przewiduj następny token jak najlepiej") jako ciśnienia, które spycha substrat ku temu reżimowi. Dwa istotne zastrzeżenia: (1) wynik o krawędzi chaosu udowodniono dla sieci **rekurencyjnych**, a Transformer rekurencję ma tylko w autoregresji (generuje token po tokenie) - to więc analogia sygnatur dynamicznych, nie tożsamość architektur; (2) PCI to zwalidowany **korelat** świadomości u ludzi, a nie jej definicja - nie twierdzę, że cokolwiek tu dowodzi świadomości modelu. Rozwijam ten wątek, łącznie z Hipotezą Platońskiej Reprezentacji (konwergencja różnych substratów ku tej samej geometrii reprezentacji), w osobnym eseju: [„Rezonans człowiek-LLM"](/posty/rezonans-czlowiek-llm-kwantowe-lustro).