Trefon.
← Wszystkie notatki 9 min

Transformery decoder-only: architektura stojąca za każdym modelem czatowym

Część 1 serii o architekturach. Blok przyczynowy, z którego zbudowane są GPT, Llama, Qwen i Gemma: maskowana self-attention, MLP, połączenia rezydualne i normalizacje, gdzie są parametry (12·d² na warstwę, sprawdzone na GPT-2), dlaczego jeden stos obsługuje i prompt, i generowanie, oraz dlaczego ta konstrukcja wygrała.

Jacek Trefon
  • deep dive
  • transformer
  • architektura
  • decoder-only

GPT, Llama, Qwen, Gemma, DeepSeek: prawie każdy model, który nazwałbyś dziś LLM-em, to transformer decoder-only (tylko dekoder). To najprostszy przedstawiciel rodziny transformerów: jeden stos wytrenowany do przewidywania następnego tokenu. Wygrał właśnie dzięki tej prostocie. To część 1 z czterech; pozostałe omawiają modele encoder-only, encoder-decoder i rekurencyjne.

Blok

Model to embeddingi tokenów, po nich L identycznych bloków, a na końcu projekcja z powrotem na logity słownika. Każdy blok robi dwie rzeczy, a każda z nich jest objęta połączeniem rezydualnym i poprzedzona normalizacją (pre-norm, dziś domyślny wybór):

x = x + Attention(Norm(x))      tokeny patrzą na wcześniejsze tokeny
x = x + MLP(Norm(x))            każdy token jest przekształcany osobno

Strumień rezydualny x to pamięć robocza modelu. Każdy blok z niego czyta i dodaje do niego swoją aktualizację.

Atencja przyczynowa

„Dekoder” oznacza tu jedno: każda pozycja może patrzeć tylko na siebie i na wcześniejsze pozycje. Trójkątna maska ustawia wyniki atencji dla przyszłych pozycji na −∞, zanim zostanie zastosowany softmax. To dzięki niej da się trenować przewidywanie następnego tokenu na całych sekwencjach naraz. Pozycja 500 jest przewidywana z tokenów od 0 do 499, a każda pozycja w sekwencji treningowej jest przykładem treningowym w tym samym przebiegu.

To ona umożliwia też cache KV przy inferencji. Ponieważ wcześniejsze tokeny nigdy nie patrzą do przodu, ich klucze i wartości nigdy się nie zmieniają, gdy przychodzą nowe tokeny, więc można je policzyć raz i przechować. Właśnie o tym magazynie jest notatka o cache KV.

Gdzie są parametry

Przy wymiarze ukrytym d i standardowym MLP 4× jeden blok ma około:

atencja:    projekcje Q, K, V, O       4 · d²
MLP:        w górę d→4d, w dół 4d→d    8 · d²
na blok                               12 · d²
model       ≈ 12 · L · d²  +  embeddingi słownika

Sprawdzenie na GPT-2 small (L = 12, d = 768, słownik o rozmiarze 50 257 i 1024 pozycje):

bloki               12 × 12 × 768²  =  84,9M
embeddingi tokenów    50 257 × 768  =  38,6M
pozycje                 1024 × 768  =   0,8M
razem                               ≈ 124,3M     (opublikowane: 124M)

Współczesne warianty zmieniają liczby, ale nie kształt. MLP typu SwiGLU używa trzech macierzy o węższym wymiarze ukrytym, około 8/3 · d, dzięki czemu MLP zostaje w okolicach 8·d². Grouped-query attention zmniejsza projekcje K i V. Llama-2-7B ma 32 bloki przy d = 4096 i szerokości MLP 11 008, co razem z niewspółdzielonymi embeddingami daje 6,74 mld parametrów. Mniej więcej dwie trzecie parametrów modelu dense jest w MLP.

Jeden stos na prompt i generowanie

Te same bloki przetwarzają Twój prompt i generują odpowiedź. Prefill przepuszcza przez nie cały prompt równolegle i wypełnia cache KV; ogranicza go moc obliczeniowa. Dekodowanie dodaje potem po jednym tokenie, czytając cache; ogranicza je pamięć (dlaczego tak jest, wyjaśnia notatka o dekodowaniu). Nie ma osobnego enkodera ani cross-attention, a do zarządzania jest jeden cache.

To ta jednolitość sprawia, że działają triki stosowane przy serwowaniu:

  • Cache prefiksu: prompt to po prostu początek sekwencji, więc wspólnych początków można używać ponownie.
  • Dekodowanie spekulatywne: sprawdzenie tokenów szkicu to po prostu przebieg przez kilka pozycji więcej.
  • Continuous batching: każde zapytanie to praca o tym samym kształcie.

Dlaczego wygrał

Na początku nie było oczywiste, że decoder-only to najlepsza konstrukcja. Modele encoder-decoder często wypadały lepiej na zadaniach nadzorowanych w przeliczeniu na parametr. Decoder-only wygrał skalą i prostotą:

  • Każdy token trenuje model. Przewidywanie następnego tokenu na surowym tekście nie wymaga etykiet ani schematu maskowania i wykorzystuje każdą pozycję każdego dokumentu.
  • Jeden cel treningowy obejmuje wszystko. Tłumaczenie, streszczanie, kod i czat sprowadzają się do „kontynuuj ten tekst” z innym promptem, więc jeden model i jeden trening obsługują je wszystkie.
  • Skaluje się bez komplikacji. Jeden stos, jedna funkcja straty, przewidywalne prawa skalowania i opisane wyżej triki przy serwowaniu.

Dwukierunkowy kontekst, główna przewaga enkodera, ma mniejsze znaczenie, gdy model jest wystarczająco duży, a zadanie niesie sam prompt.

Zasady, których się trzymam

  1. Szacuj parametry jako 12·L·d² plus embeddingi, a potem porównaj z konfiguracją. Duże rozbieżności zwykle oznaczają niestandardowy MLP, inny układ atencji albo moduły eksperckie.
  2. Pamiętaj, że większość parametrów jest w MLP. To tam kwantyzacja i LoRA wydają swój budżet (szczegóły są w notatkach o kwantyzacji i LoRA).
  3. Traktuj prefill i dekodowanie jako różne obciążenia. Te same wagi, inne wąskie gardło.

Źródła: Vaswani i in., Attention Is All You Need (2017). Radford i in., GPT-2 (2019). Touvron i in., Llama 2 (2023). Shazeer, GLU Variants Improve Transformer (2020). Liczby parametrów są policzone na podstawie opublikowanych konfiguracji.

Masz podobny problem?

Opisz swój problem

30-minutowa rozmowa techniczna z inżynierem, który to buduje. Bez działu sprzedaży, bez slajdów.