---
title: "Anatomia LLM: mechanizm uwagi"
date: 2026-06-12
description: "Serce Transformera: jak każdy token „rozgląda się” po pozostałych i bierze od nich to, czego potrzebuje, by doprecyzować swoje znaczenie. Od wąskiego gardła w starych sieciach tłumaczących, przez słynny wzór skalowanej uwagi i wielogłowość, po KV-cache, FlashAttention i ostrożne pytanie - co właściwie robią głowy uwagi, skoro „uwaga to jeszcze nie wyjaśnienie”."
tags: ["anatomia llm", "ai", "llm", "transformer", "deep-dive"]
---

## 🚀 Intro

W [poprzednim przystanku tej serii](/posty/llm-tokeny-embeddingi) - jednej z gałęzi [przeglądowego wpisu „Anatomia LLM"](/posty/anatomia-llm) - zamieniliśmy tekst w liczby: ciąg słów rozpadł się na tokeny, a każdy token dostał swój **wektor znaczenia** z trenowanej macierzy embeddingów. Skończyliśmy jednak na niepokojącej obserwacji: te wektory wciąż siedzą obok siebie **osobno**. Każdy niesie znaczenie słowa jakby „w próżni", w oderwaniu od sąsiadów. A przecież sens słowa zależy od kontekstu - „korek" znaczy co innego na autostradzie, a co innego przy butelce wina.

Mechanizm, który pozwala wektorom **„rozmawiać"** - patrzeć na siebie nawzajem i wymieniać się informacją - to **uwaga** (po angielsku *attention*). To serce Transformera i, bez większej przesady, jeden z najważniejszych pomysłów w całej historii uczenia maszynowego. Architektura, która stoi za ChatGPT, Claude'em czy Gemini, wzięła nawet nazwę od tytułu pracy, która ją rozsławiła: *Attention Is All You Need* - „uwaga to wszystko, czego potrzebujesz".

W tym wpisie prześledzimy uwagę od jej narodzin - jeszcze przed Transformerem, w sieciach tłumaczących - przez słynny wzór ze skalowaniem, aż po nowoczesne warianty, które dziś pozwalają modelom czytać setki tysięcy tokenów naraz. A na koniec zadamy pytanie, na które wciąż nie ma pełnej odpowiedzi: co właściwie te „głowy uwagi" *robią*? Bo i tutaj - w duchu całej serii - sam mechanizm okaże się prozaiczny, a to, co z niego wyrasta, znów zaskakująco trudne do końca zrozumienia.

> 💡 **Jak czytać ten tekst.** Główny wątek jest opisowy i samowystarczalny. Wzory chowam w rozwijanych blokach „dla dociekliwych" - jeśli lubisz matematykę, rozwiń; jeśli nie, pomiń bez straty dla zrozumienia. Wszystkie twierdzenia mają przypisy do prac źródłowych na końcu.


## 📋 TL;DR

- **Uwaga rozwiązała wąskie gardło.** Stare sieci tłumaczące ściskały całe zdanie źródłowe w jeden wektor stałej długości. Bahdanau, Cho i Bengio (2014) pozwolili modelowi zamiast tego „przeszukiwać" zdanie i brać z niego to, co akurat istotne - to był pierwszy mechanizm uwagi.
- **Serce: skalowany iloczyn skalarny.** Każdy token tworzy trzy wektory - **zapytanie** (Query), **klucz** (Key) i **wartość** (Value). Token porównuje swoje zapytanie z kluczami wszystkich pozostałych, a wynik (po przepuszczeniu przez softmax) decyduje, ile z czyjej wartości pobrać.
- **Dlaczego dzielimy przez $\sqrt{d_k}$** (czytaj „pierwiastek z de ka"). Bez tego skalowania iloczyny skalarne rosną z wymiarem i spychają softmax w obszar o niemal zerowych gradientach. Dzielenie przez pierwiastek wymiaru przywraca zdrowy zakres.
- **Maska przyczynowa.** W modelu generującym tekst token nie może „widzieć" przyszłości - blokuje się to **maską trójkątną**: zabronionym pozycjom dodaje się minus nieskończoność tuż przed softmaksem, więc po nim ich waga spada do zera.
- **Wiele głów naraz.** Zamiast jednej funkcji uwagi model uruchamia kilka-kilkadziesiąt równoległych **głów**, każda w mniejszej podprzestrzeni - i każda może wyłapywać inny rodzaj zależności.
- **Kwadratowy koszt.** Uwaga porównuje każdy token z każdym, więc koszt rośnie z **kwadratem** długości sekwencji. Stąd cała inżynieria długiego kontekstu: KV-cache, MQA/GQA, FlashAttention.
- **Co robią głowy? Ostrożnie.** Wagi uwagi bywają mylone z wyjaśnieniem decyzji modelu - a nie zawsze nim są (Jain i Wallace). Ale mechanistyczna interpretowalność znalazła konkretne obwody - **induction heads** - które mogą leżeć u podstaw uczenia w kontekście.

👉 **Pobaw się:** na stronie interaktywnej masz [sekcję mechanizmu uwagi](/llm/anatomia#uwaga) - zobacz na żywo, jak token rozkłada swoją uwagę na pozostałe słowa zdania.


## 🌅 Zanim powstał Transformer: skąd wzięła się uwaga

Uwaga nie pojawiła się od razu z Transformerem. Narodziła się wcześniej, jako łatka na konkretny, bolesny problem w tłumaczeniu maszynowym.

Wcześniejsze modele tłumaczące miały budowę **enkoder-dekoder**: enkoder czytał całe zdanie źródłowe i ściskał je w jeden wektor stałej długości (tzw. wektor kontekstu), a dekoder z tego jednego wektora produkował tłumaczenie. Słabość jest tu widoczna gołym okiem - cała treść zdania, choćby najdłuższego, musiała zmieścić się w jednym, z góry ustalonym ciągu liczb. To **wąskie gardło**: im dłuższe zdanie, tym więcej się gubiło.

Bahdanau, Cho i Bengio (2014) postawili tezę wprost - „użycie wektora o stałej długości stanowi wąskie gardło" - i zaproponowali coś sprytnego[^bahdanau]: niech dekoder, generując każde kolejne słowo, **automatycznie i miękko „przeszukuje"** zdanie źródłowe w poszukiwaniu fragmentów istotnych akurat teraz. Zamiast jednego streszczenia całości, model dostawał za każdym razem inną, ważoną mieszankę wszystkich słów wejściowych. To był pierwszy mechanizm uwagi (tzw. **uwaga addytywna** albo „uwaga Bahdanau"), w którym wagi dopasowania liczyła mała sieć z funkcją $\tanh$ (czytaj „tangens hiperboliczny").

Rok później Luong, Pham i Manning (2015) uprościli ten pomysł, pokazując **uwagę multiplikatywną** opartą na zwykłym iloczynie skalarnym dwóch wektorów[^luong]. To uproszczenie - porównywanie wektorów przez ich iloczyn skalarny - jest bezpośrednim przodkiem tego, co dziś robi każdy LLM. Warto jednak pamiętać: u Bahdanau i Luonga uwaga była wciąż tylko **dodatkiem** do sieci rekurencyjnej (czytającej tekst słowo po słowie). Dopiero Transformer odważył się wyrzucić rekurencję całkowicie i oprzeć wszystko na samej uwadze.

<details>
<summary>📐 Dla dociekliwych: trzy funkcje oceny Luonga</summary>

Luong i współpracownicy porównali trzy sposoby liczenia „dopasowania" między ukrytym stanem dekodera $h_t$ a stanem źródłowym $\bar h_s$:

$$\text{score}_{\text{dot}}(h_t,\bar h_s)=h_t^{\top}\bar h_s$$

$$\text{score}_{\text{general}}(h_t,\bar h_s)=h_t^{\top}W_a\,\bar h_s$$

$$\text{score}_{\text{concat}}(h_t,\bar h_s)=v_a^{\top}\tanh\!\big(W_a[h_t;\bar h_s]\big)$$

Symbol $\top$ (transpozycja) zamienia wektor kolumnowy w wierszowy, więc $h_t^{\top}\bar h_s$ to po prostu iloczyn skalarny - jedna liczba mówiąca, jak bardzo dwa wektory „wskazują w tę samą stronę". Wariant **dot** (czyste „iloczyn skalarny") jest najprostszy i to właśnie on stał się zalążkiem operacji $QK^{\top}$ w Transformerze. Wariant **concat** odpowiada z grubsza wcześniejszej uwadze addytywnej Bahdanau.

</details>


## 🎯 Serce mechanizmu: Query, Key, Value

Tu dochodzimy do sedna. W Transformerze każdy token wytwarza ze swojego wektora **trzy** osobne wektory, przepuszczając go przez trzy różne (trenowane) macierze. Najprościej zrozumieć je przez analogię do wyszukiwania w bibliotece:

- **Query** (zapytanie) - „czego ja, ten token, w tej chwili szukam?"
- **Key** (klucz) - „czym ja, ten token, się reklamuję; jaka jest moja etykieta?"
- **Value** (wartość) - „co faktycznie przekażę, jeśli ktoś mnie wybierze?"

Mechanizm działa jak miękkie wyszukiwanie. Token bierze swoje **zapytanie** i porównuje je z **kluczami** wszystkich tokenów w zdaniu (włącznie z sobą samym). Każde porównanie to iloczyn skalarny - jedna liczba mówiąca „jak bardzo do siebie pasujecie". Te liczby przechodzą przez **softmax**, który zamienia je w wagi sumujące się do jedynki - coś jak rozkład „ile procent mojej uwagi przeznaczam na każdy z pozostałych tokenów". Na końcu token pobiera **ważoną sumę wartości** wszystkich tokenów: dużo bierze od tych, z którymi pasował mocno, mało od reszty.

Efekt jest taki, że każdy token aktualizuje swój wektor, **domieszując** do niego informację od najistotniejszych sąsiadów. Słowo „korek" w zdaniu o autostradzie ściągnie do siebie informację od słów „droga" i „auto"; to samo „korek" obok „butelki" - od słów o winie. Uwaga to mechanizm, dzięki któremu znaczenie staje się **kontekstowe**.

Pozostaje jeszcze ten tajemniczy ułamek $\frac{1}{\sqrt{d_k}}$ w oryginalnym wzorze. Nie jest ozdobnikiem - rozwiązuje realny problem liczbowy. Gdy wektory zapytań i kluczy są długie (a w dużych modelach mają setki wymiarów), ich iloczyny skalarne robią się **bardzo duże** co do wartości bezwzględnej. A duże liczby na wejściu softmaksu mają zgubny efekt: softmax **nasyca się**, czyli niemal cała waga ląduje na jednym tokenie, a jego pochodne (gradienty) spadają do zera. Sieć przestaje się uczyć. Dzielenie przez $\sqrt{d_k}$ - pierwiastek z wymiaru pojedynczej głowy - precyzyjnie sprowadza te liczby z powrotem do zdrowego zakresu.

<details>
<summary>📐 Dla dociekliwych: wzór uwagi i skąd bierze się pierwiastek z wymiaru</summary>

Pełna definicja skalowanej uwagi iloczynowej (Vaswani i in., 2017):

$$\text{Attention}(Q,K,V)=\text{softmax}\!\left(\frac{QK^{\top}}{\sqrt{d_k}}\right)V$$

Tu $Q$, $K$, $V$ to macierze, w których każdy wiersz to odpowiednio zapytanie, klucz i wartość jednego tokenu. Iloczyn $QK^{\top}$ daje kwadratową macierz wszystkich par „zapytanie-klucz".

Skąd akurat $\sqrt{d_k}$? Załóżmy, że poszczególne składowe wektorów $q$ i $k$ są niezależne, mają średnią $0$ i wariancję $1$. Ich iloczyn skalarny to suma $d_k$ takich iloczynów:

$$q\cdot k=\sum_{i=1}^{d_k} q_i k_i,\qquad \mathbb{E}[q\cdot k]=0,\qquad \text{Var}(q\cdot k)=\sum_{i=1}^{d_k}\text{Var}(q_i k_i)=d_k$$

Symbol $\mathbb{E}$ to wartość oczekiwana („średnia"), $\text{Var}$ to wariancja („rozrzut"), a $\Sigma$ (sigma) oznacza sumowanie. Wariancja iloczynu rośnie więc **liniowo** z wymiarem $d_k$, a odchylenie standardowe (typowy rozrzut) to $\sqrt{d_k}$. Dzieląc cały iloczyn skalarny przez $\sqrt{d_k}$, sprowadzamy jego wariancję z powrotem do $1$ - i softmax pracuje w obszarze o zdrowych gradientach, zamiast się nasycać[^vaswani].

</details>


## 👁️ Na co wolno patrzeć: self-, cross- i uwaga przyczynowa

Uwaga przychodzi w kilku odmianach, zależnie od tego, **kto na kogo patrzy**:

- **Self-attention** (uwaga własna) - $Q$, $K$ i $V$ pochodzą z **tej samej** sekwencji. Tokeny patrzą na siebie nawzajem. To podstawowy tryb w modelach językowych.
- **Cross-attention** (uwaga skrośna) - zapytania pochodzą z jednej sekwencji, a klucze i wartości z drugiej. Tak działa np. dekoder zaglądający do enkodera w tłumaczeniu. To bezpośredni spadkobierca uwagi Bahdanau i Luonga.
- **Uwaga przyczynowa** (causal, „maskowana") - i tu rzecz absolutnie kluczowa dla modeli generujących tekst.

Model, który pisze tekst słowo po słowie, musi przewidzieć token $i+1$ wyłącznie na podstawie tego, co już zostało napisane - tokenów $\le i$. Gdyby podczas treningu mógł „podejrzeć" przyszłe tokeny, oszukiwałby: uczyłby się odpowiedzi, którą już widzi. To by całkowicie zepsuło naukę. Trzeba więc **zabronić** każdemu tokenowi patrzenia w przód.

Robi się to elegancko, **maską trójkątną**. Tuż przed softmaksem do wszystkich „zakazanych" pozycji (tych z przyszłości) dodaje się **minus nieskończoność**. Softmax z minus nieskończoności daje dokładnie zero - więc po wszystkim te pozycje mają wagę zerową, jakby ich nie było. Token może patrzeć tylko wstecz i na siebie. Ta z pozoru drobna sztuczka jest tym, co czyni model **autoregresyjnym** - zdolnym do generowania tekstu w jednym kierunku, od lewej do prawej.

<details>
<summary>📐 Dla dociekliwych: jak działa maska trójkątna</summary>

Do macierzy wyników dodaje się macierz maski $M$ tuż przed softmaksem:

$$\text{softmax}\!\left(\frac{QK^{\top}}{\sqrt{d_k}}+M\right)V,\qquad M_{ij}=\begin{cases}0 & \text{gdy } j\le i\\[2pt] -\infty & \text{gdy } j>i\end{cases}$$

Indeks $i$ to pozycja tokenu, który patrzy, a $j$ to pozycja tokenu, na który chce spojrzeć. Dla pozycji z przyszłości ($j>i$) wpis maski to $-\infty$ (minus nieskończoność). Ponieważ softmax liczy $e^{x}$, a $e^{-\infty}=0$, te pozycje dostają po normalizacji wagę dokładnie zero. Pozostałe ($j\le i$) dostają $0$, czyli nie są ruszane. Stąd nazwa „trójkątna" - dozwolone pola tworzą dolny trójkąt macierzy.

</details>


## 🧠 Wiele głów naraz

Pojedyncza uwaga ma jedną „perspektywę" - jeden sposób, w jaki porównuje tokeny. Ale język jest wielowymiarowy: jednocześnie ważna jest składnia, koreferencja (do czego odnosi się „on"), bliskość tematyczna, kolejność. Trudno, by jedna funkcja uwagi wyłapała to wszystko naraz.

Rozwiązanie to **uwaga wielogłowa** (multi-head attention). Zamiast jednej uwagi o pełnym wymiarze, Transformer uruchamia $h$ **głów** równolegle, każdą w mniejszej podprzestrzeni. Każda głowa ma własne macierze do produkcji zapytań, kluczy i wartości - więc każda może wyspecjalizować się w czymś innym. Wyniki wszystkich głów skleja się z powrotem i przepuszcza przez ostatnią macierz. Autorzy Transformera ujęli to tak: wiele głów „pozwala modelowi wspólnie uwzględniać informacje z różnych podprzestrzeni reprezentacji na różnych pozycjach"[^vaswani].

Co ważne, to nie zwiększa istotnie kosztu. Skoro każda z $h$ głów działa w wymiarze $h$ razy mniejszym, łączny rachunek jest zbliżony do kosztu jednej głowy o pełnym wymiarze. W bazowym Transformerze było $h=8$ głów, każda o wymiarze 64 (przy pełnym wymiarze modelu 512). W dzisiejszych dużych modelach głów bywa kilkadziesiąt.

<details>
<summary>📐 Dla dociekliwych: wzór uwagi wielogłowej</summary>

$$\text{MultiHead}(Q,K,V)=\text{Concat}(\text{head}_1,\dots,\text{head}_h)\,W^{O}$$

$$\text{head}_i=\text{Attention}\!\big(QW_i^{Q},\,KW_i^{K},\,VW_i^{V}\big)$$

Każda głowa $i$ ma własne macierze projekcji $W_i^{Q}, W_i^{K}, W_i^{V}$, które rzutują wejście do podprzestrzeni o wymiarze $d_k=d_{\text{model}}/h$ (czytaj „de model przez ha"). $\text{Concat}$ skleja wyniki wszystkich głów z powrotem w jeden wektor pełnego wymiaru, a wspólna macierz $W^{O}$ miesza je w finalne wyjście. W modelu bazowym: $d_{\text{model}}=512$, $h=8$, więc $d_k=d_v=64$[^vaswani].

</details>


## ⏳ Kwadratowy koszt i problem długiego kontekstu

Wszystko to ma swoją cenę - i to dosłownie. Skoro każdy token porównuje swoje zapytanie z kluczem **każdego** innego tokenu, to dla sekwencji długości $n$ trzeba policzyć macierz $n \times n$ porównań. Koszt rośnie więc z **kwadratem** długości sekwencji. Podwojenie długości kontekstu to czterokrotny wzrost rachunku; dziesięciokrotne wydłużenie - stukrotny.

To jest **główne ograniczenie** Transformera i powód, dla którego „długi kontekst" przez lata był luksusem. Pamiętasz z poprzedniego wpisu, dlaczego nie tniemy tekstu na pojedyncze znaki? Właśnie dlatego - dłuższe sekwencje rozbijają się o ten kwadratowy koszt. Cała linijka badań i inżynierii ostatnich lat to walka z tą kwadratowością.

<details>
<summary>📐 Dla dociekliwych: skąd kwadratowy koszt i czym jest KV-cache</summary>

Macierz wyników $QK^{\top}$ ma rozmiar $n \times n$ (każdy token z każdym), a jej policzenie i przechowanie kosztuje $O(n^2 \cdot d)$ w czasie i pamięci, gdzie $d$ to wymiar[^vaswani]. To kwadratowa zależność od długości $n$ - dominujący koszt przy długim kontekście.

**KV-cache.** Przy generowaniu tekstu token po tokenie zauważamy, że klucze i wartości ($K$, $V$) już wygenerowanych pozycji **się nie zmieniają**. Nie ma więc sensu liczyć ich na nowo w każdym kroku - buforuje się je (to właśnie „cache kluczy i wartości"). Cena: ten bufor rośnie liniowo z długością sekwencji $\times$ liczba warstw $\times$ liczba głów, a jego wielokrotne wczytywanie z pamięci staje się nowym wąskim gardłem - tym razem **przepustowości pamięci**, nie liczenia[^shazeer].

</details>


## ⚡ Nowoczesne warianty: jak ujarzmiono długi kontekst

Z kwadratowym kosztem i obciążeniem pamięci walczy dziś kilka pomysłów. Część z nich jest **dokładna** (dają identyczny wynik, tylko liczą go sprytniej), część - **przybliżona** (zmieniają wynik, by było taniej).

**Multi-Query Attention (MQA), Shazeer 2019.** Skoro to wczytywanie wielkich buforów kluczy i wartości boli najbardziej, Shazeer zaproponował, by wszystkie głowy zapytań **współdzieliły jedną** parę kluczy i wartości[^shazeer]. KV-cache kurczy się drastycznie, dekodowanie przyspiesza - przy „tylko niewielkim spadku jakości".

**Grouped-Query Attention (GQA), Ainslie i in. 2023.** Złoty środek między pełną wielogłowością a MQA: głowy zapytań dzieli się na $G$ grup, a każda grupa współdzieli jedną parę klucz-wartość[^ainslie]. GQA „osiąga jakość bliską" pełnej uwadze wielogłowej „przy szybkości porównywalnej z MQA", a do tego pozwala doszkolić istniejący model do tej formy za zaledwie **5%** kosztu pierwotnego treningu. Stąd jego popularność: Llama 2 używa GQA w największych wariantach (34B i 70B), a Llama 3 - we **wszystkich** rozmiarach, z kontekstem rozciągniętym do **128 tysięcy** tokenów[^llama2][^llama3].

**FlashAttention (Dao i in. 2022).** Tu pomysł jest inny - nie upraszczamy matematyki, tylko mądrzej zarządzamy pamięcią. FlashAttention liczy **dokładnie tę samą** uwagę (wynik identyczny co do bitu), ale tak organizuje obliczenia w pamięci GPU (technika „kafelkowania"), że nigdy nie materializuje całej macierzy $n \times n$[^dao]. Efekt: realne przyspieszenie i zużycie pamięci **liniowe** względem długości sekwencji zamiast kwadratowego. **FlashAttention-2** (Dao 2023) dorzucił kolejne ok. dwukrotne przyspieszenie dzięki lepszemu podziałowi pracy[^dao2]. To jeden z cichych bohaterów epoki długiego kontekstu - bez niego dzisiejsze okna na setki tysięcy tokenów byłyby znacznie droższe.

**Uwaga rzadka i liniowa.** Inne podejścia zmieniają samą matematykę uwagi, by uciec od kwadratu. **Longformer** łączy lokalne okno uwagi z rzadką uwagą globalną i skaluje się liniowo[^longformer]; **Performer** aproksymuje pełną uwagę softmax w czasie i pamięci liniowej[^performer]. W odróżnieniu od FlashAttention te metody dają wynik **przybliżony**, nie dokładny - co bywa wystarczające, ale nie zawsze.


## 🔍 Co naprawdę robią głowy uwagi

Skoro już wiemy, *jak* uwaga liczy, naturalne jest pytanie: co tak naprawdę robią poszczególne głowy? Kuszące jest popularne wyobrażenie - „ta głowa pilnuje składni, tamta śledzi koreferencję" - ale tu trzeba sporo ostrożności. To obszar, w którym łatwo o nadinterpretację.

**Po pierwsze, ostrzeżenie.** Jain i Wallace (2019) w pracy o znamiennym tytule *Attention is not Explanation* („uwaga to nie wyjaśnienie") pokazali, że wagi uwagi „w dużej mierze nie" dostarczają wiarygodnych wyjaśnień decyzji modelu[^jain]. Bywają nieskorelowane z innymi miarami ważności, a co gorsza - da się skonstruować **zupełnie różne** rozkłady uwagi dające **te same** predykcje. Innymi słowy: to, że głowa mocno „patrzy" na jakieś słowo, nie dowodzi jeszcze, że to słowo było przyczyną odpowiedzi. (Sprawa jest sporna - istnieje polemika *Attention is not not Explanation* Wiegreffego i Pintera, 2019[^wiegreffe] - ale sam fakt sporu uczy pokory.)

**Po drugie, coś zdumiewająco konkretnego.** Nurt **mechanistycznej interpretowalności** - próby rozłożenia sieci na zrozumiałe „obwody" - zidentyfikował szczególny typ głowy: **induction head** (głowę indukcyjną). Olsson i współpracownicy z Anthropic (2022) opisali głowę, która realizuje proste dopełnianie wzorca[^olsson]: widząc wcześniej sekwencję `[A][B]`, gdy znów napotka `[A]`, przewiduje `[B]`. Działa to przez „dopasowanie prefiksu" i „kopiowanie" - głowa szuka, gdzie poprzednio wystąpił bieżący token, i podsuwa to, co następowało po nim.

Co czyni to ważnym: autorzy stawiają **hipotezę** (i podkreślają, że to hipoteza), że induction heads mogą stanowić mechanizm „większości całego uczenia w kontekście" w dużych modelach - czyli tej niezwykłej zdolności, dzięki której model uczy się nowego zadania z kilku przykładów podanych w samym prompcie, bez żadnego dotrenowywania. Na poparcie pokazują m.in. nagłą **zmianę fazową** we wczesnym treningu: w pewnym momencie zdolność do uczenia w kontekście pojawia się gwałtownie, dokładnie wtedy, gdy w sieci formują się te obwody. To staranna analiza empiryczna z jawnie zaznaczoną niepewnością - nie pełne wyjaśnienie wszystkich głów uwagi, ale realny przyczółek zrozumienia.


## 🌗 Uczenie, którego nikt nie zaprogramował

Zatrzymajmy się tu na chwilę, bo właśnie dotknęliśmy czegoś, co spina całą tę serię. Cały mechanizm uwagi, który rozłożyliśmy na części, jest - jak wszystko w tej anatomii - prozaiczny: kilka mnożeń macierzy, jeden softmax, maska trójkątna. Inżynier rozumie każdy z tych kroków. A jednak z ich powtórzenia w głębokim stosie warstw **wyłania się** zdolność, której nikt wprost nie zaprojektował - **uczenie w kontekście**. Nie ma w kodzie linijki „naucz się z przykładów w prompcie". Jest tylko nacisk z poprzednich wpisów - „przewiduj następny token jak najlepiej" - a z niego, gdzieś w środku treningu, samoistnie krystalizują się obwody, które potrafią coś, co wygląda jak rozumowanie przez analogię.

I nie jest to emergencja rozmyta. Jak pokazaliśmy wyżej, uczenie w kontekście pojawia się niemal **skokowo** - w policzalnej chwili treningu, gdy formują się induction heads. Tym bardziej kusi, by z map uwagi odczytywać, *co model rozumie*. Dlatego ważyłem tu słowa: mapa uwagi pokazuje, gdzie model patrzy, ale nie jest jeszcze wyjaśnieniem, dlaczego rozstrzyga tak, a nie inaczej. To rozróżnienie - „gdzie patrzy" kontra „dlaczego tak decyduje" - jest osią ostrożności, którą trzymałem przez cały wpis.

Zostaje pytanie trudniejsze: skąd to się bierze - że ślepy nacisk na trafność kolejnego tokena rodzi obwód, który *uczy się w locie*? Ono wykracza poza samą uwagę, a może i poza tę architekturę. Wektory, które w [poprzednim wpisie](/posty/llm-tokeny-embeddingi) leżały osobno, tutaj zaczęły ze sobą „rozmawiać" - i z tej rozmowy wyłoniło się zachowanie, którego w planie nie było. Dokąd ten trop prowadzi, idę osobno, w [eseju o rezonansie człowiek-LLM](/posty/rezonans-czlowiek-llm-kwantowe-lustro).


## 🎯 Co dalej

Mamy serce Transformera. Wiemy już, jak token tworzy **zapytanie, klucz i wartość**, jak porównuje się z innymi przez skalowany iloczyn skalarny, dlaczego dzielimy przez $\sqrt{d_k}$, jak maska trójkątna pilnuje, by model nie podglądał przyszłości, i po co uruchamiamy wiele głów naraz. Wiemy też, skąd bierze się kwadratowy koszt i jak inżynieria - KV-cache, GQA, FlashAttention - rozsuwa granice długiego kontekstu.

Ale uwaga sama nie jest jeszcze całym modelem. To jeden klocek - bardzo ważny, lecz klocek. Token, który zebrał informację od sąsiadów, musi ją jeszcze **przetworzyć**; trzeba poukładać te warstwy w głęboki stos tak, by trening w ogóle się zbiegał; trzeba zdecydować, jak z finalnych wektorów wyłonić konkretne słowo. W następnym przystanku serii składamy **pełny blok Transformera**: warstwę przetwarzającą (FFN), połączenia rezydualne i normalizację, które pozwalają budować stosy z dziesiątek warstw, oraz to, jak na samym końcu model zamienia liczby z powrotem w tekst.

Jeśli wolisz teraz **dotknąć** zamiast czytać dalej, [interaktywna strona „Anatomia LLM"](/llm/anatomia#uwaga) pozwala zobaczyć, jak token rozkłada swoją uwagę na pozostałe słowa zdania. A jeśli ciągnie cię to, co naprawdę *wyłania się* z opisanego tu mechanizmu - i dlaczego proste reguły rodzą zdolności, których nikt nie zaprogramował - [pisałem o tym osobno](/posty/rezonans-czlowiek-llm-kwantowe-lustro).


[^bahdanau]: D. Bahdanau, K. Cho, Y. Bengio (2014). *Neural Machine Translation by Jointly Learning to Align and Translate*. ICLR 2015. arXiv:1409.0473. <https://arxiv.org/abs/1409.0473>
[^luong]: M.-T. Luong, H. Pham, C. D. Manning (2015). *Effective Approaches to Attention-based Neural Machine Translation*. EMNLP. arXiv:1508.04025. <https://arxiv.org/abs/1508.04025>
[^vaswani]: A. Vaswani et al. (2017). *Attention Is All You Need* (skalowana uwaga iloczynowa, $\sqrt{d_k}$, multi-head, złożoność $O(n^2 d)$). NeurIPS. arXiv:1706.03762. <https://arxiv.org/abs/1706.03762>
[^shazeer]: N. Shazeer (2019). *Fast Transformer Decoding: One Write-Head is All You Need* (MQA, KV-cache, wąskie gardło przepustowości pamięci). arXiv:1911.02150. <https://arxiv.org/abs/1911.02150>
[^ainslie]: J. Ainslie et al. (2023). *GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints*. EMNLP. arXiv:2305.13245. <https://arxiv.org/abs/2305.13245>
[^dao]: T. Dao et al. (2022). *FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness*. NeurIPS. arXiv:2205.14135. <https://arxiv.org/abs/2205.14135>
[^dao2]: T. Dao (2023). *FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning*. arXiv:2307.08691. <https://arxiv.org/abs/2307.08691>
[^longformer]: I. Beltagy, M. E. Peters, A. Cohan (2020). *Longformer: The Long-Document Transformer* (uwaga rzadka, skalowanie liniowe). arXiv:2004.05150. <https://arxiv.org/abs/2004.05150>
[^performer]: K. Choromanski et al. (2021). *Rethinking Attention with Performers* (aproksymacja FAVOR+, złożoność liniowa). ICLR. arXiv:2009.14794. <https://arxiv.org/abs/2009.14794>
[^llama2]: H. Touvron et al. (2023). *Llama 2: Open Foundation and Fine-Tuned Chat Models* (GQA w wariantach 34B/70B, kontekst 4096). arXiv:2307.09288. <https://arxiv.org/abs/2307.09288>
[^llama3]: A. Grattafiori et al. (2024). *The Llama 3 Herd of Models* (GQA we wszystkich rozmiarach, kontekst do 128K). arXiv:2407.21783. <https://arxiv.org/abs/2407.21783>
[^jain]: S. Jain, B. C. Wallace (2019). *Attention is not Explanation*. NAACL. arXiv:1902.10186. <https://arxiv.org/abs/1902.10186>
[^wiegreffe]: S. Wiegreffe, Y. Pinter (2019). *Attention is not not Explanation* (polemika z Jain i Wallace). EMNLP. arXiv:1908.04626. <https://arxiv.org/abs/1908.04626>
[^olsson]: C. Olsson et al. (2022). *In-Context Learning and Induction Heads*. Anthropic / Transformer Circuits Thread. <https://transformer-circuits.pub/2022/in-context-learning-and-induction-heads/index.html>