English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

gość
1 / ?
powrót do lekcji

Uwaga Plus MLP, Powtarzane

Struktura Bloku Transformera Pre-Norm


Dwie Podwarstwy

Blok transformera zawiera dokładnie dwie podwarstwy, z których każda działa na sekwencji tokenów o kształcie [batch, seq_len, d_model]:


1. Podwarstwa uwagi wielogłowicowej. Tokeny patrzą na siebie nawzajem. Aktywność 68 omówiła to szczegółowo. Kształt wyjściowy odpowiada kształtowi wejściowemu.

2. Podwarstwa MLP feed-forward. Każdy token przekształca się niezależnie poprzez dwuwarstwowy perceptron. Brak przepływu informacji między tokenami. Kształt wyjściowy odpowiada kształtowi wejściowemu.


Obie podwarstwy zachowują kształt [batch, seq_len, d_model]. To zachowanie pozwala na układanie bloków w stos: wyjście warstwy N zasila wejście warstwy N+1 bez akrobacji z kształtem.


Co wnosi każda podwarstwa

Attention przenosi informacje między pozycjami: token w pozycji 17 może pobrać informacje z pozycji 1 do 16. MLP przekształca informacje w obrębie każdej pozycji: reprezentacja tokena jest kształtowana przez wyuczone nieliniowe funkcje, ale nigdy nie widzi swoich sąsiadów.


Układanie bloków na przemian wykonuje te dwie operacje. Warstwa 1 attention miesza pozycje. Warstwa 1 MLP zmienia kształt dla każdej pozycji. Warstwa 2 attention miesza ponownie, teraz nad zmienionymi reprezentacjami. Ta na przemian rośnie siła wyrazu wraz z głębokością.


Stos ANDREA


Wariantn_layern_headd_modelmlp_dim
ANDREA-12M6123841536
ANDREA-120M12127683072
ANDREA-480M162415366144

Zauważ mlp_dim = 4 × d_model w całej rodzinie. To proporcja zachowuje się w niemal każdym nowoczesnym transformerze. Sekcja 3 wyjaśnia dlaczego.

Nazwanie podwarstw

Blok transformera zawiera dwie podwarstwy. Nazwij je w kolejności, & dla każdej z nich podaj, czy przesuwa informacje między pozycjami (token-to-token) czy transformuje informacje w obrębie pojedynczej pozycji (niezależnie dla każdego tokena). Jedno zdanie na podwarstwę.

Dlaczego połączenia pomijające są ważne

Wzorzec resztkowy

Każda podwarstwa owija swoje obliczenia w połączenie resztkowe. Wyjście dodaje z powrotem wejście:


x = x + Attention(LayerNorm(x))     # podwarstwa uwagi
x = x + MLP(LayerNorm(x))           # podwarstwa MLP

W każdej podwarstwie funkcja Attention(...) lub MLP(...) produkuje deltę. Blok nie zastępuje wejścia; dodaje wyuczoną korektę.


Dlaczego to ma znaczenie

Trzy powody, dla których połączenia resztowe dominują w głębokich architekturach:


1. Przepływ gradientu. Podczas propagacji wstecznej, dodawanie daje gradientom bezpośrednią ścieżkę od wyjścia z powrotem do wejścia, omijając podwarstwę. Stos 12 warstw bez resztkowych połączeń straciłby sygnał gradientu na długo przed dotarciem do osadzeń; z resztkami, wielkość gradientu pozostaje użyteczna przez setki warstw.


2. Inicjalizacja tożsamościowa. Podczas inicjalizacji, wagi podwarstwy produkują małe wyjścia. Połączenie resztkowe oznacza, że warstwa N początkowo przechodzi prawie niezmieniona. Trening uczy się delt progresywnie od działającego punktu startowego.


3. Uczenie kompozycyjne. Każdy blok uczy się udoskonalenia, nie zastąpienia. Warstwa 1 może dodać informacje pozycyjne. Warstwa 2 może dodać strukturę syntaktyczną. Warstwa 7 może dodać relacje semantyczne. Strumień resztkowy akumuluje.


Normalizacja warstw

Przed każdą podwarstwą, LayerNorm przeskalowuje reprezentację każdego tokenu do zera średniej i wariancji jednostkowej, a następnie stosuje wyuczone wzmocnienie i bias na funkcję:


y = gamma * (x - mean(x)) / sqrt(var(x) + epsilon) + beta

Średnia & wariancja są obliczane wzdłuż wymiaru d_model, oddzielnie dla każdego tokenu. Dwa wyuczone wektory (gamma, beta, każdy o kształcie [d_model]) przywracają ekspresyjną skalę. Normalizacja utrzymuje aktywacje w numerycznie stabilnym zakresie; bez niej małe niestabilności treningowe lawinują do gradientów NaN.

Pre-Norm vs Post-Norm

Subtelny, ale krytyczny wybór

Dwa sposoby podłączenia normalizacji warstw do podwarstwy resztkowej:


Post-norm (oryginalny artykuł z 2017 roku):

x = LayerNorm(x + Attention(x))

Normalizacja warstw następuje po dodaniu resztki. Sam strumień resztkowy jest normalizowany w każdej warstwie.


Pre-norm (nowoczesny standard, używany w ANDREA):

x = x + Attention(LayerNorm(x))

Normalizacja warstwowa znajduje się przed podwarstwą, wewnątrz gałęzi resztkowej. Strumień resztkowy pozostaje nienormalizowany; tylko wejście do podwarstwy jest przeskalowane.


Dlaczego Pre-Norm zwyciężył

Post-norm trenuje się słabo bez rozgrzewki LR i starannego strojenia hiperparametrów. Gradienty eksplodują we wczesnych warstwach, ponieważ każda normalizacja warstwowa miesza nagromadzony stan strumienia resztkowego. Oryginalny artykuł z 2017 roku używał post-norm z intensywnym strojeniem; kolejne prace (GPT-2, LLaMA, ANDREA) ustandaryzowały pre-norm.


Trening pre-norm jest stabilny. Strumień resztkowy akumuluje się czysto we wszystkich warstwach; tylko wejścia podwarstw są normalizowane dla stabilności numerycznej. Nowoczesne transformery domyślnie używają pre-norm, & ANDREA dziedziczy ten wybór.


Równanie Końcowego Bloku

Połączenie resztkowych połączeń, normalizacji warstw w pozycji pre-norm & obu podwarstw daje pełny blok ANDREA:


```python
def block_forward(x):
```
x = x + Attention(LayerNorm(x))   # podwarstwa uwagi
x = x + MLP(LayerNorm(x))         # podwarstwa MLP
return x

Dwie podwarstwy, dwa resztkowe dodatki, dwie normalizacje warstw (uwaga: każda podwarstwa ma własną normalizację warstw; ANDREA-120M ma 24 normalizacje warstw w 12 blokach plus jedną końcową na wyjściu, czyli łącznie 25). Powtórz 12 razy. To pień ANDREA-120M.

Dlaczego Pre-Norm Stabilizuje Trening

ANDREA używa pre-norm: `x = x + Attention(LayerNorm(x))`. Porównaj z post-norm: `x = LayerNorm(x + Attention(x))`. Podaj jeden powód z perspektywy przepływu gradientów, dlaczego pre-norm trenuje stabilniej niż post-norm w głębokich stosach. Odnieś się do resztkowego strumienia w odpowiedzi.

Dwie Warstwy Liniowe, Jedna Aktywacja

Trzy Operacje

Podwarstwa MLP to dwuwarstwowy perceptron z nieliniową aktywacją między warstwami:


def mlp_forward(x):
h = x · W_1 + b_1        # rozszerz: d_model → mlp_dim
h = GELU(h)              # nieliniowa aktywacja
y = h · W_2 + b_2        # skompresuj: mlp_dim → d_model
return y

Trzy operacje. Dwie liniowe, jedna nieliniowa. Pierwsza liniowa rozszerza szerokość; druga kurczy z powrotem.


Stosunek rozszerzenia 4×

Nowoczesne transformery ustawiają mlp_dim = 4 × d_model. ANDREA-120M:


d_model = 768
mlp_dim = 4 × 768 = 3072
Kształt W_1 = [768, 3072]      # ~2.36M parametrów
Kształt W_2 = [3072, 768]      # ~2.36M parametrów
Parametry MLP na blok = 4.72M (ignorując biasy)

Dwa MLP znajdują się między każdą parą podwarstw uwagi (jedno na blok). Dwanaście bloków × 4.72M ≈ 56.6M parametrów MLP łącznie w ANDREA-120M, mniej więcej połowa wszystkich parametrów.


Dlaczego 4×

Stosunek 4× wyłonił się empirycznie. Mniejsze stosunki zmniejszają pojemność modelu. Większe stosunki dają malejące zwroty na parametr. Przez dekady poszukiwań architektur, 4× się sprawdził; pojawia się w GPT, BERT, T5, LLaMA i ANDREA.


Najnowsze prace (PaLM, Chinchilla) wykazały, że mechanizmy bramkowania (SwiGLU) mogą używać rozszerzenia 8/3× z porównywalną pojemnością przy mniejszym koszcie; ANDREA pozostaje przy klasycznym GELU + 4× dla prostoty.

GELU: Płynna Aktywacja

Co Oblicza GELU

GELU (Gaussian Error Linear Unit) to standardowa aktywacja między warstwami MLP w nowoczesnych transformerach. Jej formuła:


GELU(x) = x · Φ(x)

Φ(x) to funkcja dystrybuucji skumulowanej standardowego rozkładu normalnego: prawdopodobieństwo, że standardowa zmienna losowa gaussowska spadnie na poziomie x lub poniżej. Obliczana numerycznie:


Φ(x) ≈ 0.5 × (1 + tanh(sqrt(2/π) × (x + 0.044715 × x³)))

Zachowanie w zależności od regionu

- Dla dużych dodatnich x: Φ(x) ≈ 1, więc GELU(x) ≈ x. Podobnie jak ReLU.

- Dla dużych ujemnych x: Φ(x) ≈ 0, więc GELU(x) ≈ 0. Podobnie jak ReLU.

- W pobliżu x = 0: Φ(x) ≈ 0.5, więc GELU(0) = 0 dokładnie. Płynne przejście przez początek.


W przeciwieństwie do ReLU, GELU przepuszcza niektóre ujemne wejścia, ważone przez Φ(x). Małe ujemne wejście nadal wnosi małe ujemne wyjście, tylko mniejsze niż pełne wejście.


Dlaczego GELU przewyższył ReLU

Empirycznie transformery trenowane z GELU osiągają niższą stratę niż transformery trenowane z ReLU przy tej samej liczbie parametrów. Gładkość wokół zera ma znaczenie: ostry próg ReLU przy zerze powoduje nieciągłości gradientu; gładka krzywa GELU zapewnia czystsze gradienty do propagacji wstecznej.


Silnik treningowy ANDREA microgpt_cuda.cu zawiera ręcznie napisane jądro GELU CUDA. Jądro używa powyższego przybliżenia tanh; nowoczesne GPU zawierają tanh jako operację jednorozkazową.

Obliczanie parametrów MLP

ANDREA-120M ma `d_model=768`, `mlp_dim=3072` i `n_layer=12`. Oblicz całkowitą liczbę parametrów w macierzach wag MLP (`W_1` i `W_2`) we wszystkich 12 blokach. Ignoruj biasy. Pokaż obliczenia. Następnie podaj, jaką część stanowi to z ~120M całkowitych parametrów ANDREA-120M (zaokrąglij do jednej cyfry dziesiętnej).

Dwanaście bloków składa się na ANDREA-120M

Od bloku do modelu

Pełny forward pass ANDREA-120M:


def model_forward(token_ids):
x = token_embed(token_ids) + position_embed(positions)
for block_idx in range(n_layer):       # 12 bloków
x = block_forward(x)               # attention + MLP z resztkami
x = LayerNorm(x)                       # norm finalna
logits = x · token_embed.T             # powiązane wagi dla projekcji wyjściowej
return logits

Sześć linii. Główna część znajduje się wewnątrz block_forward, wywoływanego dwanaście razy. Embeddings uruchamiają potok; powiązane unembedding (ta sama macierz używana do wyszukiwania wejścia, transponowana do projekcji wyjścia) kończy go.


Głębokość jako kompozycja

Każdy blok odczytuje strumień resztkowy, oblicza deltę i dodaje ją z powrotem. Po dwunastu przejściach strumień zawiera nagromadzone wkłady z każdego bloku. Wewnętrznie warstwy mają tendencję do specjalizacji:


- Wczesne warstwy (1-3): wzorce syntaktyczne, struktura pozycyjna

- Środkowe warstwy (4-8): relacje między słowami, granice fraz

- Późne warstwy (9-12): treść semantyczna, przywoływanie faktów


Ta specjalizacja wynika z ciśnienia treningowego, a nie z wyborów architektonicznych. Ten sam jednolity projekt bloku produkuje wyspecjalizowane warstwy po treningu na języku.


Całkowita liczba parametrów bloku


KomponentNa blokW 12 blokach
Projekcje uwagi (4×W)2,36M28,3M
Wagi MLP (W_1 + W_2)4,72M56,6M
Normalizacje warstw (gamma, beta)~3 tys. (pomijalne)~37 tys.
Łącznie na blok~7,1M~85M

85M parametrów w pniu. Dodaj ~13M w osadzeniach tokenów (8449 słownictwa × 768 d_model × 2 dla powiązanych wejścia/wyjścia) plus końcową normalizację warstw, & liczba parametrów ANDREA-120M wynosi około 120M. Projekt bloku stanowi dwie trzecie; osadzenia resztę.

Śledzenie jednego tokenu przez jeden blok

Wektor tokenu o wymiarze 768 wchodzi do bloku 7 modelu ANDREA-120M. Przejdź przez to, co dzieje się z nim wewnątrz bloku (w strukturze pre-norm). Wymień: obie normalizacje warstw, obie podwarstwy, obie dodatki resztkowe & ostateczny kształt. Podaj co najmniej jedno miejsce, gdzie strumień resztkowy pozostaje nietknięty & jedno miejsce, gdzie jest modyfikowany.