5. LLM Architecture
LLM Architecture
Celem tej piątej fazy jest bardzo prosty: Opracowanie architektury pełnego LLM. Połącz wszystko, zastosuj wszystkie warstwy i stwórz wszystkie funkcje do generowania tekstu lub przekształcania tekstu na identyfikatory i odwrotnie.
Ta architektura będzie używana zarówno do treningu, jak i przewidywania tekstu po jego wytrenowaniu.
Przykład architektury LLM z https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01_main-chapter-code/ch04.ipynb:
Wysokopoziomowa reprezentacja może być obserwowana w:
Input (Tokenized Text): Proces zaczyna się od tokenizowanego tekstu, który jest przekształcany w reprezentacje numeryczne.
Token Embedding and Positional Embedding Layer: Tokenizowany tekst przechodzi przez warstwę token embedding oraz warstwę positional embedding, która uchwyca pozycję tokenów w sekwencji, co jest kluczowe dla zrozumienia kolejności słów.
Transformer Blocks: Model zawiera 12 bloków transformatorowych, z których każdy ma wiele warstw. Te bloki powtarzają następującą sekwencję:
Masked Multi-Head Attention: Pozwala modelowi skupić się na różnych częściach tekstu wejściowego jednocześnie.
Layer Normalization: Krok normalizacji, aby ustabilizować i poprawić trening.
Feed Forward Layer: Odpowiada za przetwarzanie informacji z warstwy uwagi i dokonywanie prognoz dotyczących następnego tokena.
Dropout Layers: Te warstwy zapobiegają przeuczeniu, losowo eliminując jednostki podczas treningu.
Final Output Layer: Model generuje tensor o wymiarach 4x50,257, gdzie 50,257 reprezentuje rozmiar słownika. Każdy wiersz w tym tensorze odpowiada wektorowi, który model wykorzystuje do przewidywania następnego słowa w sekwencji.
Goal: Celem jest wzięcie tych osadzeń i przekształcenie ich z powrotem w tekst. Konkretnie, ostatni wiersz wyjścia jest używany do generowania następnego słowa, reprezentowanego jako "forward" w tym diagramie.
Code representation
Funkcja aktywacji GELU
Cel i Funkcjonalność
GELU (Gaussian Error Linear Unit): Funkcja aktywacji, która wprowadza nieliniowość do modelu.
Gładka Aktywacja: W przeciwieństwie do ReLU, która zeruje ujemne wejścia, GELU gładko mapuje wejścia na wyjścia, pozwalając na małe, różne od zera wartości dla ujemnych wejść.
Definicja Matematyczna:
Celem użycia tej funkcji po warstwach liniowych wewnątrz warstwy FeedForward jest przekształcenie danych liniowych w nieliniowe, aby umożliwić modelowi uczenie się złożonych, nieliniowych relacji.
Sieć Neuronowa FeedForward
Kształty zostały dodane jako komentarze, aby lepiej zrozumieć kształty macierzy:
Cel i Funkcjonalność
Sieć FeedForward na poziomie pozycji: Zastosowuje dwuwarstwową sieć w pełni połączoną do każdej pozycji osobno i identycznie.
Szczegóły warstwy:
Pierwsza warstwa liniowa: Zwiększa wymiarowość z
emb_dim
do4 * emb_dim
.Aktywacja GELU: Zastosowuje nieliniowość.
Druga warstwa liniowa: Redukuje wymiarowość z powrotem do
emb_dim
.
Jak widać, sieć Feed Forward używa 3 warstw. Pierwsza to warstwa liniowa, która pomnoży wymiary przez 4, używając wag liniowych (parametrów do trenowania wewnątrz modelu). Następnie funkcja GELU jest używana we wszystkich tych wymiarach, aby zastosować nieliniowe wariacje w celu uchwycenia bogatszych reprezentacji, a na końcu używana jest kolejna warstwa liniowa, aby wrócić do oryginalnego rozmiaru wymiarów.
Mechanizm Uwag Wielogłowych
To zostało już wyjaśnione w wcześniejszej sekcji.
Cel i Funkcjonalność
Wielogłowa Uwaga Własna: Pozwala modelowi skupić się na różnych pozycjach w sekwencji wejściowej podczas kodowania tokena.
Kluczowe komponenty:
Zapytania, Klucze, Wartości: Liniowe projekcje wejścia, używane do obliczania wyników uwagi.
Głowy: Wiele mechanizmów uwagi działających równolegle (
num_heads
), każdy z zredukowaną wymiarowością (head_dim
).Wyniki uwagi: Obliczane jako iloczyn skalarny zapytań i kluczy, skalowane i maskowane.
Maskowanie: Zastosowana jest maska przyczynowa, aby zapobiec modelowi zwracania uwagi na przyszłe tokeny (ważne dla modeli autoregresywnych, takich jak GPT).
Wagi uwagi: Softmax z maskowanych i skalowanych wyników uwagi.
Wektor kontekstu: Ważona suma wartości, zgodnie z wagami uwagi.
Projekcja wyjściowa: Warstwa liniowa do połączenia wyjść wszystkich głów.
Celem tej sieci jest znalezienie relacji między tokenami w tym samym kontekście. Ponadto tokeny są dzielone na różne głowy, aby zapobiec nadmiernemu dopasowaniu, chociaż ostateczne relacje znalezione na głowę są łączone na końcu tej sieci.
Ponadto, podczas treningu stosowana jest maska przyczynowa, aby późniejsze tokeny nie były brane pod uwagę przy poszukiwaniu specyficznych relacji do tokena, a także stosowany jest dropout, aby zapobiec nadmiernemu dopasowaniu.
Normalizacja Warstwy
Cel i Funkcjonalność
Normalizacja Warstw: Technika używana do normalizacji wejść wzdłuż cech (wymiary osadzenia) dla każdego pojedynczego przykładu w partii.
Składniki:
eps
: Mała stała (1e-5
) dodawana do wariancji, aby zapobiec dzieleniu przez zero podczas normalizacji.scale
ishift
: Uczące się parametry (nn.Parameter
), które pozwalają modelowi skalować i przesuwać znormalizowane wyjście. Są inicjowane odpowiednio do jedynek i zer.Proces Normalizacji:
Obliczanie Średniej (
mean
): Oblicza średnią z wejściax
wzdłuż wymiaru osadzenia (dim=-1
), zachowując wymiar do rozprzestrzeniania (keepdim=True
).Obliczanie Wariancji (
var
): Oblicza wariancjęx
wzdłuż wymiaru osadzenia, również zachowując wymiar. Parametrunbiased=False
zapewnia, że wariancja jest obliczana przy użyciu obciążonego estymatora (dzieląc przezN
zamiastN-1
), co jest odpowiednie przy normalizacji wzdłuż cech, a nie próbek.Normalizacja (
norm_x
): Odejmuje średnią odx
i dzieli przez pierwiastek kwadratowy z wariancji pluseps
.Skalowanie i Przesunięcie: Zastosowuje uczące się parametry
scale
ishift
do znormalizowanego wyjścia.
Celem jest zapewnienie średniej 0 z wariancją 1 we wszystkich wymiarach tego samego tokena. Celem tego jest stabilizacja treningu głębokich sieci neuronowych poprzez redukcję wewnętrznego przesunięcia kowariancji, które odnosi się do zmiany w rozkładzie aktywacji sieci z powodu aktualizacji parametrów podczas treningu.
Blok Transformera
Kształty zostały dodane jako komentarze, aby lepiej zrozumieć kształty macierzy:
Cel i Funkcjonalność
Kompozycja Warstw: Łączy wielogłową uwagę, sieć feedforward, normalizację warstw i połączenia resztkowe.
Normalizacja Warstw: Stosowana przed warstwami uwagi i feedforward dla stabilnego treningu.
Połączenia Resztkowe (Skróty): Dodają wejście warstwy do jej wyjścia, aby poprawić przepływ gradientu i umożliwić trening głębokich sieci.
Dropout: Stosowany po warstwach uwagi i feedforward w celu regularyzacji.
Funkcjonalność Krok po Kroku
Pierwsza Ścieżka Resztkowa (Self-Attention):
Wejście (
shortcut
): Zapisz oryginalne wejście dla połączenia resztkowego.Layer Norm (
norm1
): Normalizuj wejście.Wielogłowa Uwaga (
att
): Zastosuj self-attention.Dropout (
drop_shortcut
): Zastosuj dropout w celu regularyzacji.Dodaj Resztkę (
x + shortcut
): Połącz z oryginalnym wejściem.
Druga Ścieżka Resztkowa (FeedForward):
Wejście (
shortcut
): Zapisz zaktualizowane wejście dla następnego połączenia resztkowego.Layer Norm (
norm2
): Normalizuj wejście.Sieć FeedForward (
ff
): Zastosuj transformację feedforward.Dropout (
drop_shortcut
): Zastosuj dropout.Dodaj Resztkę (
x + shortcut
): Połącz z wejściem z pierwszej ścieżki resztkowej.
Blok transformera grupuje wszystkie sieci razem i stosuje pewne normalizacje oraz dropouty w celu poprawy stabilności treningu i wyników. Zauważ, że dropouty są stosowane po użyciu każdej sieci, podczas gdy normalizacja jest stosowana przed.
Ponadto, wykorzystuje również skróty, które polegają na dodawaniu wyjścia sieci do jej wejścia. Pomaga to zapobiegać problemowi znikającego gradientu, zapewniając, że początkowe warstwy przyczyniają się "tak samo" jak ostatnie.
GPTModel
Kształty zostały dodane jako komentarze, aby lepiej zrozumieć kształty macierzy:
Cel i Funkcjonalność
Warstwy Osadzeń:
Osadzenia Tokenów (
tok_emb
): Konwertuje indeksy tokenów na osadzenia. Przypomnienie, są to wagi przypisane do każdego wymiaru każdego tokena w słowniku.Osadzenia Pozycyjne (
pos_emb
): Dodaje informacje o pozycji do osadzeń, aby uchwycić kolejność tokenów. Przypomnienie, są to wagi przypisane do tokena zgodnie z jego pozycją w tekście.Dropout (
drop_emb
): Stosowane do osadzeń w celu regularyzacji.Bloki Transformera (
trf_blocks
): Stosn_layers
bloków transformera do przetwarzania osadzeń.Ostateczna Normalizacja (
final_norm
): Normalizacja warstwy przed warstwą wyjściową.Warstwa Wyjściowa (
out_head
): Projekcja ostatecznych ukrytych stanów do rozmiaru słownika w celu wygenerowania logitów do predykcji.
Celem tej klasy jest wykorzystanie wszystkich innych wspomnianych sieci do przewidywania następnego tokena w sekwencji, co jest fundamentalne dla zadań takich jak generowanie tekstu.
Zauważ, jak będzie używać tylu bloków transformera, ile wskazano i że każdy blok transformera używa jednej sieci z wieloma głowami uwagi, jednej sieci feed forward oraz kilku normalizacji. Więc jeśli używa się 12 bloków transformera, pomnóż to przez 12.
Ponadto, warstwa normalizacji jest dodawana przed wyjściem i na końcu stosowana jest ostateczna warstwa liniowa, aby uzyskać wyniki o odpowiednich wymiarach. Zauważ, jak każdy ostateczny wektor ma rozmiar używanego słownika. Dzieje się tak, ponieważ próbuje uzyskać prawdopodobieństwo dla każdego możliwego tokena w słowniku.
Liczba parametrów do wytrenowania
Mając zdefiniowaną strukturę GPT, możliwe jest ustalenie liczby parametrów do wytrenowania:
Krok po Kroku Obliczenia
1. Warstwy Osadzania: Osadzenie Tokenów i Osadzenie Pozycji
Warstwa:
nn.Embedding(vocab_size, emb_dim)
Parametry:
vocab_size * emb_dim
Warstwa:
nn.Embedding(context_length, emb_dim)
Parametry:
context_length * emb_dim
Całkowita liczba parametrów osadzenia
2. Bloki Transformera
Jest 12 bloków transformera, więc obliczymy parametry dla jednego bloku, a następnie pomnożymy przez 12.
Parametry na blok transformera
a. Uwaga wielogłowa
Składniki:
Warstwa liniowa zapytania (
W_query
):nn.Linear(emb_dim, emb_dim, bias=False)
Warstwa liniowa klucza (
W_key
):nn.Linear(emb_dim, emb_dim, bias=False)
Warstwa liniowa wartości (
W_value
):nn.Linear(emb_dim, emb_dim, bias=False)
Projekcja wyjściowa (
out_proj
):nn.Linear(emb_dim, emb_dim)
Obliczenia:
Każda z
W_query
,W_key
,W_value
:
Ponieważ są trzy takie warstwy:
Projekcja wyjściowa (
out_proj
):
Całkowite parametry uwagi wielogłowej:
b. Sieć FeedForward
Składniki:
Pierwsza warstwa liniowa:
nn.Linear(emb_dim, 4 * emb_dim)
Druga warstwa liniowa:
nn.Linear(4 * emb_dim, emb_dim)
Obliczenia:
Pierwsza warstwa liniowa:
Druga warstwa liniowa:
Całkowite parametry FeedForward:
c. Normalizacje warstw
Składniki:
Dwa wystąpienia
LayerNorm
na blok.Każde
LayerNorm
ma2 * emb_dim
parametrów (skala i przesunięcie).Obliczenia:
d. Całkowite parametry na blok transformera
Całkowita liczba parametrów dla wszystkich bloków transformatorów
3. Ostateczne Warstwy
a. Normalizacja Ostatecznej Warstwy
Parametry:
2 * emb_dim
(skala i przesunięcie)
b. Warstwa Projekcji Wyjścia (out_head
)
Warstwa:
nn.Linear(emb_dim, vocab_size, bias=False)
Parametry:
emb_dim * vocab_size
4. Podsumowanie wszystkich parametrów
Generowanie tekstu
Mając model, który przewiduje następny token, jak ten wcześniej, wystarczy wziąć wartości ostatniego tokena z wyjścia (ponieważ będą to wartości przewidywanego tokena), które będą wartością na wpis w słowniku, a następnie użyć funkcji softmax
, aby znormalizować wymiary do prawdopodobieństw, które sumują się do 1, a następnie uzyskać indeks największego wpisu, który będzie indeksem słowa w słowniku.
Kod z https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01_main-chapter-code/ch04.ipynb:
References
Last updated