Anatomia LLM: sieci, parametry i trening
🚀 Intro
W poprzednim przystanku tej serii - jednej z gałęzi przeglądowego wpisu „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 , 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: . 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.
🕸️ 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 , mnożymy ją przez wektor wejść, dodajemy bias i przepuszczamy przez aktywację. Jeden zapis, , 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”1. 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ów1. 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 przecinku2. Połowa bitów to połowa pamięci i często rząd wielkości szybsze obliczenia.
📐 Dla dociekliwych: warstwa jako mnożenie macierzy i precyzja liczb
Pojedyncza warstwa w pełni połączona to . Gdy przetwarzamy paczkę przykładów naraz, wejście jest macierzą , a całą warstwę liczymy jednym mnożeniem:
To właśnie GEMM. Symbol 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)2. 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óżnicy3.
👉 Pobaw się: na stronie interaktywnej masz diagram warstw i sieci - 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”4. 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, 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.
📐 Dla dociekliwych: reguła łańcuchowa i przepływ błędu
Dla warstwy , wprowadza się sygnał błędu (delta) - pochodną straty względem wejścia warstwy, . Propaguje się on wstecz wzorem:
Symbol to transpozycja macierzy (zamiana wierszy z kolumnami), a to mnożenie „po współrzędnych” (element po elemencie). Kluczowe jest to, że liczy się z gotowego już z warstwy następnej - stąd „wstecz” i stąd efektywność.
Mając sygnał błędu, gradienty wag i biasów to:
Pełne wyprowadzenie: Goodfellow, Bengio, Courville, Deep Learning, rozdz. 6.55.
🎯 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ę6.
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).
📐 Dla dociekliwych: cross-entropy, NLL i perplexity
Model zwraca rozkład - prawdopodobieństwo tokenu pod warunkiem wszystkiego, co było wcześniej. Strata to średnia ujemna logarytmów prawdopodobieństw prawdziwych tokenów:
Dla pojedynczej pozycji to entropia krzyżowa między rozkładem prawdziwym (jedynka na właściwym tokenie, zera gdzie indziej) a przewidywanym: . 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:
czyli po prostu ze straty. Stąd interpretacja „efektywnej liczby opcji”: dla rozkładu jednostajnego na tokenach perplexity wynosi dokładnie .
⚙️ 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), 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).
Prawdziwy przełom przyniósł Adam (Kingma i Ba, 2015)7. 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)8. 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 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 Transformerze9). Potem tempo łagodnie maleje, najczęściej wg krzywej kosinusowej (cosine schedule) - tak trenowano m.in. modele Chinchilli10. 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.
📐 Dla dociekliwych: od SGD do AdamW, plus harmonogram tempa
SGD: , gdzie to tempo uczenia.
Momentum dodaje wygładzoną średnią gradientów (pęd), sterowaną przez (beta):
Adam utrzymuje estymaty momentu pierwszego () i drugiego () rzędu, z dwoma współczynnikami wygładzania (beta jeden) i (beta dwa):
Symbol (epsilon) to maleńka stała chroniąca przed dzieleniem przez zero. Domyślne wartości z pracy: , , 7.
AdamW odsprzęga weight decay (sterowany przez , lambda) od kroku gradientowego - dopisuje go osobno, zamiast wpychać do gradientu:
Cosine schedule - po warmupie tempo maleje wg krzywej kosinusowej od do :
📈 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 , gdzie to liczba warstw, a to „szerokość” modelu6. 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”6. 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ć”10. Z tego wzięła się słynna reguła kciuka: około 20 tokenów treningowych na każdy parametr modelu10. 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”.
📐 Dla dociekliwych: skąd współczynnik 12 i wzory praw skalowania
Liczba parametrów. Przy założeniu Kaplan podaje (równanie 2.1)6:
Współczynnik 12 rozkłada się tak: na warstwę przypadają cztery macierze mechanizmu uwagi (Q, K, V i projekcja wyjściowa: ) oraz dwie macierze bloku FFN (), razem . Stąd proporcja 2/3 (FFN) do 1/3 (uwaga). Parametry embeddingów () liczy się osobno i dla dużych modeli są relatywnie małe.
Prawa skalowania Kaplana - strata jako prawo potęgowe względem rozmiaru i danych 6:
gdzie (alfa) to wykładniki potęgowe.
Parametryczna strata Chinchilli (równanie 2)10 - rozkłada stratę na nieusuwalny szum plus człony malejące z rozmiarem i danymi:
z dopasowaniem , , , , . To z minimalizacji tej funkcji przy stałym budżecie wychodzi reguła „skaluj i równo”.
👉 Pobaw się: na stronie interaktywnej masz sekcję o parametrach i wagach - 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 gradientu5.
- 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ąć5.
- Regularyzacja - rodzina technik hamujących przeuczenie: weight decay (poznany przy AdamW), early stopping, augmentacja danych i dropout5.
- 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 naraz11.
🌗 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ą.12 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 , 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” 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.
Footnotes
-
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 ↩ ↩2
-
D. Kalamkar et al. (2019). A Study of BFLOAT16 for Deep Learning Training. arXiv:1905.12322. https://arxiv.org/abs/1905.12322 ↩ ↩2
-
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 ↩
-
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 ↩
-
I. Goodfellow, Y. Bengio, A. Courville (2016). Deep Learning, MIT Press (backprop rozdz. 6.5; mini-batche, overfitting, regularyzacja). https://www.deeplearningbook.org/ ↩ ↩2 ↩3 ↩4
-
J. Kaplan et al. (2020). Scaling Laws for Neural Language Models (OpenAI). arXiv:2001.08361. https://arxiv.org/abs/2001.08361 ↩ ↩2 ↩3 ↩4 ↩5
-
D. P. Kingma, J. Ba (2015). Adam: A Method for Stochastic Optimization. arXiv:1412.6980 (ICLR 2015). https://arxiv.org/abs/1412.6980 ↩ ↩2
-
I. Loshchilov, F. Hutter (2019). Decoupled Weight Decay Regularization (AdamW). arXiv:1711.05101. https://arxiv.org/abs/1711.05101 ↩
-
A. Vaswani et al. (2017). Attention Is All You Need (warmup tempa uczenia). arXiv:1706.03762. https://arxiv.org/abs/1706.03762 ↩
-
J. Hoffmann et al. (2022). Training Compute-Optimal Large Language Models (Chinchilla). arXiv:2203.15556. https://arxiv.org/abs/2203.15556 ↩ ↩2 ↩3 ↩4
-
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 ↩
-
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”. ↩