Skąd Biorą Się Skoki Gradientów
Spokojna Mini-Partia & Szokująca
Większość mini-partii produkuje gradienty o rozsądnych wartościach. Strata entropii krzyżowej dla modelu, który już mniej więcej pasuje do danych, utrzymuje się w wąskim paśmie; backprop przenosi ten sygnał z powrotem jako gradienty o podobnej wielkości.
Niektóre mini-partie nie. Trzy źródła skoków gradientów:
1. Przykłady odstające. Pojedyncza sekwencja z ekstremalnie rzadką kombinacją tokenów produkuje stratę daleko od średniej oraz gradient daleko od średniej.
2. Krawędziowe przypadki numeryczne. Bliski zeru mianownik softmax, layernorm produkujący NaN, przepełnienie FP16. Każdy z nich może produkować gradienty rzędu wielkości większe niż typowe.
3. Zmiany rozkładu. Przełączanie źródeł danych podczas jednego treningu szokuje model nowym rozkładem. Bandyt ANDREA przetasuje wagi źródeł co 7 do 42 kroków. Każde przełączenie to mała zmiana rozkładu.
ANDREA-120M v1: Kaskada pików
v1 nie miało klipowania gradientów. Przejścia źródeł co 7 do 42 kroków z bandyta karmiły model krótkimi burstami repo-docs (struktura list), potem gutenberg (długi proza), potem hermes3-general (Q&A). Każde przejście produkowało piki gradientów: każdy pik pchał wagi w degeneratywne atraktory w skali 120M.
Kluczowy fakt empiryczny. ANDREA-12M przetrwała tego samego bandytę bez klipingu. Mniejsze macierze wag pozostają odporne na wstrząsy gradientu; pojedyncza zła partia nie może wpędzić 12M parametrów w niekontrolowany atraktor tak, jak może to zrobić z 120M. Kliping ma większe znaczenie w miarę skalowania modelu.
Globalne klipowanie normy L2
Dwa wybory: Per-tensor czy globalne
Dwa sposoby ograniczania wielkości gradientów:
Klipowanie per-tensor. Klipuj każdy tensor gradientu niezależnie. Gradient osadzeń zostaje sklipowany do własnej normy; gradient uwagi do własnej normy. Proste, ale zniekształca względne skale: mały skok w jednym tensorze (teraz zerowy gradient) łączy się z ogromnym gradientem w innym (niezmienionym).
Globalne klipowanie normy L2. Traktuj wszystkie gradienty jako jeden wielki wektor. Oblicz całkowitą normę L2 dla wszystkich parametrów. Jeśli norma przekracza max_norm, skaluj każdy gradient tym samym czynnikiem. Zachowuje względne wielkości między tensorami.
ANDREA używa globalnego. Pascanu i inni (2013) wykazali empirycznie, że globalne obcinanie przewyższa per-tensorowe w treningu transformerów.
Matematyka
Oblicz globalną normę L2:
norm = sqrt(sum over all params of g_i^2)
Jeśli norm <= max_norm, gradienty przechodzą bez zmian. Jeśli norm > max_norm, skaluj każdy gradient przez max_norm / norm:
g_i_clipped = g_i * (max_norm / norm)
Po skalowaniu, nowa norma wynosi dokładnie max_norm. ANDREA używa max_norm = 1.0.
Obliczanie Czynnika Skalowania
Dlaczego obliczanie normy gradientu wymaga trzech jąder
Naiwny algorytm nie może działać na GPU
Pseudokod dla globalnego obliczania normy L2:
całkowita = 0
dla każdego parametru p:
dla każdego elementu g w p.grad:
całkowita += g * g
norm = sqrt(całkowita)
Na GPU ta naiwna pętla zawodzi z dwóch powodów:
1. Sekwencyjne akumulowanie. Pojedynczy akumulator total zmusza każdy wątek do czekania na każdy inny wątek, co niweczy równoległość GPU.
2. Heterogeniczne tensory. ANDREA-120M ma tensory o znacznie różnych kształtach: embedding (8449 x 768), attention QKV (768 x 768), layernorm (768). Jeden kernel nie może efektywnie iterować po wszystkich kształtach.
Trójkernelowy potok ANDREA
Podziel pracę na trzy jądra CUDA w pliku microgpt_cuda.cu:
Kernel 1: k_grad_norm_partial. Dla każdego tensora parametrów oblicz częściową sumę kwadratów. Każdy blok wątków redukuje fragment tensora; wyniki zapisywane są do małego bufora tymczasowego. Równoległość: jeden blok na fragment, setki bloków na wszystkie tensory.
Kernel 2: k_grad_norm_final. Zredukuj bufor tymczasowy do pojedynczej skali. Weź jego pierwiastek kwadratowy. Jeden mały kernel, uruchamia się w mikrosekundach.
Kernel 3: k_grad_scale. Jeśli norm > max_norm, oblicz scale = max_norm / norm i pomnóż każdy element gradientu przez scale. Jeden przebieg po każdym tensorze gradientu, żenująco równoległy.
Kolejność ma znaczenie: Pre-Adam
Rurociąg obcinania uruchamia się PRZED aktualizacjami AdamW m, v lub jakimkolwiek parametrem. Dlaczego?
Ograniczone gradienty zasilają wykładnicze średnie ruchome AdamW. Jeśli skok zostałby przepuszczony do m & v, zepsułby te bieżące średnie & spowolnił regenerację na wiele kroków po skoku. Ograniczenie przed Adamem utrzymuje efekt skoku ograniczony do pojedynczego złego kroku.
Dlaczego trzy kernele, a nie jeden?
Jak No-Clipping zabiło v1
Przejścia Źródła Bandita Co 7 do 42 Kroki
Bandit ANDREA działa w fazach. Każda faza trwa 7, 14, 21, 28 lub 42 kroki (wybrane losowo). Na granicy każdej fazy wagi źródeł się zmieniają: na przykład repo-docs skacze z 0.1 do 0.6, gutenberg spada z 0.4 do 0.1, hermes3-general rośnie z 0.5 do 0.7.
Każde przejście to wstrząs dystrybucyjny dla modelu. Strata gwałtownie wzrasta. Gradienty wzrastają wraz z nią: model, który minimalizował stratę na prozie w stylu gutenberg, teraz widzi struktury list w stylu repo-docs, a gradienty niosą sygnał korygujący o magnitudzie 10x lub 100x typowej.
Tryb Awarii v1
Bez klipingu te 10-100x skoki gradientu płynęły do średnich m & v AdamW. Wygładzanie AdamW powodowało, że efekt skoku utrzymywał się przez wiele kroków po faktycznie złym batchu. W połączeniu z brakiem weight decay (vanilla Adam w v1), aktualizacje wag napędzane skokami kumulowały się przez fazy, aż wagi dryfowały do degeneratywnego atraktora: logit jednego tokena dominował softmax, samplowany output to ten token, kontekst treningowy zawierał ten token, gradient wzmacniał ten token. Blokada powtórzeń.
Stabilność v2
v2 dodało kliping z max_norm = 1.0, obok AdamW & rozgrzewki LR. Efekt skoku na m & v jest ograniczony; wagi nie mogą dryfować szybciej niż lr max_norm = 0.0003 1.0 = 0.0003 na parametr na krok w szczycie. Przejścia fazowe nadal produkują skoki, ale te skoki są ograniczane zanim dotrą do optimizera.
Rezultat: v2 (po filtrze danych v2.5 & polerowaniu v3) osiągnęło faktyczne przywoływanie, spójność wieloparaografową & 9.5/10 zewnętrznych ocen na próbkach biologii & przetwarzania sygnałów.
Połączenie Pojemności-Krucheści
Ten sam bandyta. Te same dane. Te same hiperparametry z wyjątkiem klipowania. Dlaczego 12M przetrwało bez klipowania, podczas gdy 120M załamało się?
Dwa kumulujące się czynniki:
1. Większe macierze wag przechowują więcej atraktorów. Projekcja uwagi 768x768 ma 590K parametrów; nawet małe dryfty na parametr przesuwają zachowanie uwagi w znaczący sposób. Projekcja uwagi 384x384 ma 147K parametrów i pozostaje w bardziej ograniczonym podprzestrzeni.
2. Więcej warstw oznacza więcej multiplikatywnych interakcji. v3 ma 12 warstw transformatora (w porównaniu do 6 dla 12M). Szczyty propagują się przez 12 warstw kumulujących się nieliniowości; każda warstwa może wzmacniać dryft poprzedniej warstwy.
Kruchość kumuluje się wraz z pojemnością. Klipowanie staje się obowiązkowe powyżej pewnego progu skali; ANDREA ustawia ten próg gdzieś między 12M a 120M parametrów.
Diagnozowanie kaskady v1
Gdzie jeszcze stosuje się klipowanie?
Pokrewne Aktywności
Trzy powiązane aktywności łączą się z clippingiem:
- Aktywność 10: AdamW. Clipping chroni m i v w AdamW przed zanieczyszczeniem skokami. Bez clippingu, jedna zła partia psuje stan optymalizatora na 50+ kroków.
- Aktywność 11: LR warmup. Warmup tłumi lr; clipping tłumi g. Razem: w kroku 1, najgorsze aktualizacje parametrów to lr_after_warmup max_norm = 1.5e-7 1.0 = 1.5e-7, w porównaniu do 0.0003 * 50 = 0.015 bez żadnej ochrony. Redukcja o 100 000 razy w magnitudzie najgorszego wczesnego update'u.
- Aktywność 14: Wieloramienni bandyci. Długość fazy bandyty (7 do 42 kroków) jest krótka specjalnie po to, aby zapobiec dominacji jakiegokolwiek jednego źródła; klipowanie sprawia, że te częste przejścia są bezpieczne.
Klipowanie to najtańszy zysk stabilności w treningu transformatorów: 3 małe jądra CUDA, mikrosekundy na krok, decydujący wpływ na to, czy modele 120M+ zbiegają się, czy załamują.