ML Atlas

Kurs: modele językowe od środka · Lekcja 3 z 12 · 15 min

Mały GPT: blok z N12, który się uczy

W skrócie

Jeden blok transformera z maską uczy się przewidywać następny znak. Jedno przejście daje stratę 16 pozycji, a pisanie idzie znak po znaku.

Rozgrzewka Dwa pytania z kursów NN i ML, na których ta lekcja się opiera. Minuta, a lekcji nie blokuje.
Z kursu NN, lekcja 12: Transformer: klocki, które już znasz Po co transformerowi kodowanie pozycji?

Pokaż odpowiedź

Poprawna odpowiedź: Bo bez niego uwaga bez maski widzi tylko zbiór słów, a nie ich kolejność

Zamiana słów miejscami zamienia wynik uwagi tak samo i nic więcej. W labie bez pozycji „uderzyło” ma w obu zdaniach różnicę 0,00, a z pozycją 0,38 po uwadze.

Z kursu NN, lekcja 11: Sekwencje: od pamięci RNN do uwagi Czym uwaga różni się od RNN w drodze od pierwszego słowa do dziesiątego?

Pokaż odpowiedź

Poprawna odpowiedź: Uwaga łączy je w jednym kroku, a RNN przez 9 kroków stanu

Każde słowo liczy wagę dla każdego innego słowa wprost, więc sygnał nie musi przechodzić przez 9 mnożeń.

W lekcji 12 kursu NN blok transformera miał losowe wagi i niczego nie umiał. Tu ten sam rodzaj bloku, ułożony jak w GPT-2 (normalizacja przed uwagą i MLP) i z maską, uczy się: dostaje tekst Atlasu po polsku i przewiduje następny znak. To pierwszy model w tym kursie, który jest siecią neuronową i naprawdę się trenuje. Obok stoi model, który tylko zlicza trójki znaków. Sprawdzimy uczciwie, który wypada lepiej.

Przewidź, potem sprawdź Mały transformer (1 blok, d = 16, kontekst 16 znaków) uczy się przez 300 kroków Adama. Model 3-gramowy zlicza, jaki znak idzie po każdej parze znaków. Oba uczą się na tych samych 5775 znakach. Który ma niższą perpleksję na odłożonym tekście walidacyjnym?
Jak bardzo jesteś pewny(-a)?

Eksperyment

Ten interaktywny eksperyment działa w przeglądarce z włączonym JavaScriptem. Tekst wokół opisuje, co w nim widać. W eksperymencie: Jeden blok transformera (4626 wag) uczy się przewidywać następny znak tekstu: po 300 krokach Adama perpleksja na walidacji wynosi 11,57, a model 3-gramowy, który tylko zlicza, ma 8,94; po 3200 krokach sieć schodzi do 8,86, a po 6400 walidacja rośnie do 9,54, choć trening dalej spada.

Pokaż odpowiedź

Poprawna odpowiedź: Model 3-gramowy, bo przy tak małym tekście i budżecie zliczanie wystarcza

Na każdym z pięciu startów wygrywa zliczanie. Transformer po 300 krokach ma na walidacji perpleksję od 10,60 do 11,57, a model 3-gramowy 8,94. Przy tak małym tekście i budżecie zliczanie trójek znaków wystarcza.

Spróbuj

  • Przesuwaj suwak kroków od 100 w prawo i patrz na dwie krzywe: walidację i trening. Gdzie walidacja przestaje spadać, choć trening dalej spada?
  • Przełącz na „bez kodowania pozycji” i porównaj krzywe przy 3200 krokach. Potem sprawdź to samo na innych startach.
  • Naciśnij „Trenuj od nowa” przy 300 krokach i napisz 40 znaków. Porównaj licznik przejść w treningu i w pisaniu.

Pomysł w prostych słowach

Model dostaje okno 16 znaków i dla każdej pozycji zgaduje, jaki znak jest następny. Maska przyczynowa sprawia, że pozycja 5 widzi tylko znaki 1–5, nigdy dalsze. Dzięki temu jedno przejście przez blok daje 16 uczciwych przewidywań naraz i 16 składników straty. W labie paczka ma 8 okien, więc jeden krok Adama to 8 przejść i 128 przewidywań, a 300 kroków to 2400 przejść i 38 400 przewidywań.

Pisanie tak nie działa. Następny znak zależy od poprzedniego, a ten trzeba najpierw wybrać. Dlatego model pisze po jednym znaku: 40 nowych znaków to 40 przejść przez blok.

Perpleksja to exp ze średniej entropii krzyżowej (lekcja 4 kursu NN). Mówi, spośród ilu równie prawdopodobnych znaków model zgaduje. Model bez żadnej wiedzy zgadywałby spośród 34 znaków, czyli wszystkich liter, spacji i kropki.

Dlaczego to działa

Strata to średnia entropia krzyżowa po wszystkich pozycjach paczki. Propagacja wsteczna i Adam z kursu NN robią resztę. W labie forward i backward są napisane ręcznie, bez biblioteki, a niezależne lustro w numpy daje te same liczby: na pięciu startach przez 400 kroków, a na starcie 1 przez całe 6400.

Krzywe pokazują, co robi trening na małym tekście. Na starcie 1 walidacja jest najniżej po 3200 krokach (8,86), a po 6400 ma 9,54, choć trening dalej spada z 6,34 do 5,30. Na 4 z 5 startów walidacja jest najniżej przy 3200 krokach, na starcie 2 dopiero przy 6400. Pewne jest co innego: od 1600 kroków luka między tekstem odłożonym a treningiem rośnie z każdym punktem, na walidacji i na teście, na każdym z pięciu startów. Model coraz lepiej zna tekst treningowy niż nowy. Czy dalsze kroki już szkodzą, tego ta zabawka nie rozstrzyga: walidacja i test mają po ok. 500 znaków, a od 3200 do 6400 kroków test spada na 4 z 5 startów. Procedura zostaje ta sama: liczbę kroków wybierasz na walidacji, test oglądasz raz, na końcu.

Czy sieć w ogóle dogania zliczanie? Uczciwie sprawdza to test: na każdym starcie bierzesz krok z najniższą walidacją i raz liczysz perpleksję na teście. Sieć ma wtedy od 9,32 do 10,17, a model 3-gramowy 8,26: zliczanie wygrywa na każdym z pięciu startów. Na samej walidacji najlepszy punkt sieci bywa poniżej 3-gramu, ale tam wybierasz krok i porównujesz na tym samym tekście, więc sieć ma przewagę wyboru. Na 5775 znakach zliczanie wystarcza.

Mały GPT ma 4626 wag. Najmniejszy model z otwartej rodziny Pythia ma 70 mln parametrów, a największy 12 mld [3]. Ten najmniejszy jest więc ok. 15 tys. razy większy od zabawki. Liczb perpleksji z labu nie przenosimy na prawdziwe modele: inny tekst, inny tokenizator, inna skala.

Pozycje i maska

Bez kodowania pozycji uwaga bez maski widzi tylko zbiór słów (lekcja 12 kursu NN). Z maską jest inaczej: pozycja widzi tylko tekst przed sobą, a to zdradza, gdzie stoi. Duże modele bez kodowania pozycji wypadają podobnie do modeli z kodowaniem; autorzy przypuszczają, że maska pozwala tokenowi policzyć, ilu ma poprzedników [2]. W labie tak nie jest. Bez kodowania pozycji jeden blok wie, jaki znak stoi na bieżącej pozycji, ale nie wie, który znak stał tuż przed nim. Przestaw znaki przed pozycją, a jej przewidywanie się nie zmieni. Po 3200 krokach ma na walidacji od 10,41 do 10,99, a z kodowaniem od 8,63 do 9,47, na każdym z pięciu startów. Tyle co model, który zlicza tylko pary znaków: 10,59. Jeden blok to za mało, żeby z samej maski odtworzyć kolejność: liczbę poprzedników musiałby najpierw policzyć, a potem jeszcze jej użyć.

Częsty błąd

Prawda czy fałsz: „Model piszący tekst w treningu też idzie po jednym tokenie, więc trening jest wolny jak pisanie.” Fałsz. W treningu cały tekst już jest, a maska ukrywa przed każdą pozycją przyszłość, więc jedno przejście liczy stratę wszystkich 16 pozycji [1]. W labie 300 kroków to 2400 przejść i 38 400 przewidywań. Po jednym tokenie idzie tylko pisanie: 40 znaków to 40 przejść, licznik w widżecie to pokazuje. Pamięć KV w prawdziwych modelach oszczędza liczenie od nowa tego, co już było, ale kroków dalej jest tyle, ile nowych tokenów.

Quiz

Trzy pytania na sprawdzenie się. Wybierz odpowiedź albo rozwiń odpowiedź pod pytaniem. Z klawiatury: strzałki wybierają, Enter albo spacja zatwierdza.

1. Okno ma 16 znaków, a model ma maskę przyczynową. Ile przejść przez blok trzeba w treningu, żeby policzyć stratę dla wszystkich 16 pozycji?
Pokaż odpowiedź

Poprawna odpowiedź: 1 przejście

Maska ukrywa przed każdą pozycją dalsze znaki, więc jedno przejście daje 16 uczciwych przewidywań naraz.

2. Na starcie 1 walidacja ma po 1600 krokach 9,19, po 3200 krokach 8,86, a po 6400 krokach 9,54. Trening spada przez cały czas. Ile kroków wybierasz?
Pokaż odpowiedź

Poprawna odpowiedź: 3200 kroków

Wybór pada na walidacji: po 3200 krokach jest najniżej. Najniższy trening nie mówi nic o nowym tekście, a test ogląda się raz, po wyborze.

3. Jeden blok z maską uczy się 3200 kroków bez kodowania pozycji. Jak wypada na walidacji w porównaniu z kodowaniem pozycji?
Pokaż odpowiedź

Poprawna odpowiedź: Gorzej na każdym z pięciu startów, mniej więcej jak model zliczający pary znaków

Bez pozycji ma od 10,41 do 10,99, z pozycjami od 8,63 do 9,47. Model zliczający pary znaków ma 10,59.

Najważniejsze wnioski

  • Maska przyczynowa pozwala policzyć stratę wszystkich pozycji okna jednym przejściem. Po jednym tokenie idzie tylko pisanie.
  • Na 5775 znakach zliczanie trójek znaków wygrywa z małym transformerem na każdym z pięciu startów: po 300 krokach Adama na walidacji i na teście w kroku wybranym walidacją.
  • Liczbę kroków wybiera się na walidacji: na starcie 1 jest najniżej po 3200 krokach. Od 1600 kroków luka między tekstem odłożonym a treningiem rośnie na każdym starcie.
  • W labie, po 3200 krokach, jeden blok bez kodowania pozycji przewiduje mniej więcej jak model zliczający pary znaków. Duże modele bez kodowania pozycji wypadają podobnie do modeli z nim.

Źródła (sprawdzone 26.10.2026)

  1. arxiv.org/abs/1706.03762: Blok transformera i maska, która w dekoderze ukrywa przyszłe pozycje. (sprawdzone 26.10.2026)
  2. arxiv.org/abs/2203.16634: Modele z maską przyczynową bez kodowania pozycji są konkurencyjne; autorzy przypuszczają, że maska pozwala policzyć poprzedników. (sprawdzone 26.10.2026)
  3. arxiv.org/abs/2304.01373: Pythia: 16 otwartych modeli od 70 mln do 12 mld parametrów. (sprawdzone 26.10.2026)

Głębiej: wzór, kod, praktyka

Matematyka

Okno x₁ … x₁₆, cele x₂ … x₁₇. Wejście: h = E[x_t] + P[t] (bez kodowania pozycji samo E[x_t]).

  • Blok z normalizacją przed (pre-LN, jak GPT-2): h ← h + uwaga(LN(h)), potem h ← h + W₂ · ReLU(W₁ · LN(h) + c₁) + c₂, na końcu p = softmax(W_u · LN(h) + c_u).
  • Maska: S_tu = q_t · k_u / √8 dla u ≤ t, a dla u > t wartość −∞, więc po softmaksie waga 0.
  • Strata paczki: L = −(1 / (8 · 16)) Σ_okna Σ_t ln p_t(x_(t+1)). Perpleksja = exp(L) liczona na tekście, którego model nie widział w treningu.
  • Wagi: E 34 × 16, P 16 × 16, W_Q, W_K, W_V, W_O po 16 × 16, W₁ 16 × 64 + 64, W₂ 64 × 16 + 16, trzy LN po 2 × 16, W_u 16 × 34 + 34. Razem 544 + 256 + 1024 + 1088 + 1040 + 96 + 578 = 4626.
  • Adam: krok 0,01 · m̂ / (√v̂ + 10⁻⁸), β₁ = 0,9, β₂ = 0,999.
W kodzie (Python)

Dwie rzeczy z lekcji w numpy: jedna głowa uwagi z maską liczy 16 pozycji jednym przejściem tak samo jak 16 osobnych przejść, a perpleksja to exp ze średniej entropii krzyżowej:

import numpy as np

T, d = 16, 4
X = np.sin(np.arange(T * d).reshape(T, d))      # 16 positions, 4 numbers each (any fixed values)

def attend(X):                                 # one head with W_Q = W_K = W_V = I and the causal mask
    S = X @ X.T / np.sqrt(X.shape[1])
    S = S + np.triu(np.full(S.shape, -np.inf), 1)   # position t sees only positions 0…t
    A = np.exp(S - S.max(axis=1, keepdims=True))
    return (A / A.sum(axis=1, keepdims=True)) @ X

once = attend(X)                               # one pass over the window: all 16 positions
alone = np.array([attend(X[:t + 1])[t] for t in range(T)])   # 16 passes, each on the text up to t
print("one pass = 16 separate passes:", np.allclose(once, alone))
print("passes: training 16 positions =", 1, "| writing 16 characters =", T)

p_true = np.array([0.30, 0.05, 0.12, 0.20])    # probabilities the model gave the true next characters
print(f"perplexity = exp(mean cross-entropy) = {np.exp(-np.log(p_true).mean()):.2f}")
print(f"Pythia 70M / tiny GPT: {70_000_000 / 4626:.0f}x")

Wynik

one pass = 16 separate passes: True
passes: training 16 positions = 1 | writing 16 characters = 16
perplexity = exp(mean cross-entropy) = 7.26
Pythia 70M / tiny GPT: 15132x

Jedno przejście z maską daje to samo co 16 osobnych, bo żadna pozycja nie zagląda dalej. Perpleksja 7,26 znaczy: model zgaduje tak, jakby wybierał spośród ok. 7 znaków. Uruchomione w numpy 2.1.3.

Dla praktyka
  • Zanim wytrenujesz sieć, policz prosty punkt odniesienia, np. n-gram na tym samym podziale. Na małych danych często wygrywa.
  • Zapisuj punkt kontrolny z najniższą stratą walidacji, a nie ostatni. Strata treningu może dalej spadać, gdy model dopasowuje się już tylko do danych treningowych.
  • Do nauki są otwarte modele z punktami kontrolnymi z całego treningu, np. Pythia [3]: można zobaczyć, jak zmienia się model po kolejnych krokach.
  • Wynik testu pokazuj raz, na końcu. Jeśli wybierasz po nim liczbę kroków, przestaje być uczciwą oceną.

Więcej w Atlasie

Hasła encyklopedii o pojęciach z tej lekcji: