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

un

gäst
1 / ?

Query, Key, Value

Tre Linjära Kartor från Samma Input

Efter inbäddning (aktivitet 4) bär varje position en 768-dimensionell vektor x_t. Attention börjar med att producera tre distinkta projektioner av x:


Q (query): vad vill denna position veta?


K (nyckel): vad erbjuder denna position till andra positioner?


V (värde): vilket innehåll levererar denna position om den uppmärksammas?


Varje projektion kommer från en inlärd viktmatris:


Q = x · W_Q     # W_Q form: (d_model, d_k)
K = x · W_K     # W_K form: (d_model, d_k)
V = x · W_V     # W_V form: (d_model, d_k)

Tre matriser, alla tränade via bakåtpropagering. En modell lär sig: på denna position, vilken query hämtar bäst användbart tidigare sammanhang? Vilken key annonserar denna positions innehåll väl? Vilket value levereras om det väljs?


Scaled dot-product attention


Ett biblioteksanalogiexempel

Tänk dig ett bibliotekskortregister. Du går in med ett ämne i åtanke (din query). Varje kort listar nyckelord (en key). När ditt ämne matchar ett korts nyckelord, tar du bokens innehåll (ett value). Attention gör detta för varje token parallellt: varje position frågar varje annan position, rankar överensstämmelse, & hämtar en viktad kombination av value-vektorer.


ANDREA-120M Dimensioner


MängdVärdeNoter
d_model768Vektorstorlek på varje position
n_head12Parallella uppmärksamhetsheadar
d_k64Dimension per head (= d_model / n_head)
T1024Kontextlängd

d_k = d_model / n_head = 768 / 12 = 64. Varje head ser en 64-dimensionell skiva av ett fullt 768-dimensionellt utrymme. Activity 6 (grow_a_language_model_multi_head) täcker en uppdelning per head i detalj.

Beräkna d_k

Beräkna d_k för två ANDREA-varianter. (a) ANDREA-12M: d_model = 384, n_head = 12. (b) ANDREA-480M: d_model = 1536, n_head = 24. Visa din formel d_k = d_model / n_head för varje.

Varför dividera med sqrt(d_k)

En poängmatris

När Q & K finns (varje form (T, d_k)), beräknar attention en poängmatris:


scores = Q · K^T     # shape: (T, T)

scores[i, j] = hur starkt position i:s query stämmer överens med position j:s key. Varje (i, j)-par får en score: 1024 × 1024 = 1 048 576 scores per attention head per forward pass.


Varför dividera

Priorsprodukter av två slumpmässiga d-dimensionella enhetsvektorer har en magnitud av ordningen sqrt(d). Utan skalning växer scores med d_k:


- d_k = 64: typiska skalära produkter i storleksordningen 8.

- d_k = 256: typiska skalära produkter i storleksordningen 16.

- d_k = 4096: typiska skalära produkter i storleksordningen 64.


Stora värden ger en spetsig softmax (en position dominerar, gradienter försvinner på annat håll). Träningen stannar av. Skalning fixar magnituden:


scaled_scores = (Q · K^T) / sqrt(d_k)

För ANDREA-120M är sqrt(d_k) = sqrt(64) = 8. Varje poäng delas med 8. Magnituderna förblir ungefär i enhetsskala oavsett d_k. Softmax förblir välbeteende. Gradienterna flyter.


Vaswanis ursprungliga motivering

Från Attention Is All You Need (2017): 'För stora värden av d_k växer punktprodukterna i magnitud, vilket trycker softmax-funktionen in i regioner där den har extremt små gradienter.' En sqrt(d_k)-divisor motverkar den tillväxten.


En Kodvy

Inne i microgpt_cuda.cu visas denna skalning som en literal division:


scores[i][j] = dot(Q[i], K[j]) * (1.0f / sqrtf(d_k));

En float-multiplikation per score. Billigt. Kritiskt.

Skalning vid d_model = 4096

Antag att ett forskningslag bygger ANDREA-2B med d_model = 4096 & n_head = 32. (a) Beräkna d_k. (b) Beräkna sqrt(d_k). (c) Förklara i en mening vad som skulle hända om ett lag glömde att dividera med sqrt(d_k) vid denna skala.

Varför Position i Inte Kan Se Position j > i

En Begränsning Född ur Generering

ANDREA genererar en token i taget. Vid inferens producerar position 0 en första token, sedan ser position 1 position 0:s utdata & producerar en andra token, & så vidare. En modell har aldrig tillgång till framtida tokens under generering.


Träningen måste spegla detta. Om under träning position 5 kunde uppmärksamma position 6, skulle en modell lära sig en genväg: 'förutsäg token 6 genom att läsa token 6'. Vid inferens försvinner den genvägen (token 6 existerar inte ännu). En models tränings- kontra inferensbeteende skulle divergara katastrofalt.


En Mask

En kausal mask blockerar uppmärksamhet från valfri position i till valfri position j > i. Implementering: sätt scaled_scores[i][j] = -infinity överallt där j > i. Efter softmax blir de posterna exp(-inf) = 0. Masken nollställer uppmärksamhet till framtida positioner rent.


för i i range(T):
för j i range(T):
om j > i:
scaled_scores[i][j] = -1e9   # effektivt -inf

Efter softmax (radvis), summerar varje rad till 1, men endast positioner [0, i] bär sannolikhetsmassa. Position i blandar information endast från tidigare positioner.


Visualisera en mask

En poängmatris med form (T, T) med mask applicerad ser ut som en nedre-triangulär struktur:


scaled_scores efter mask, radvis softmax:

rad 0:  [1.0, 0,   0,   0,   ...]   # ser bara sig själv
rad 1:  [0.4, 0.6, 0,   0,   ...]   # ser positioner 0, 1
rad 2:  [0.2, 0.3, 0.5, 0,   ...]   # ser 0, 1, 2
rad 3:  [0.1, 0.2, 0.3, 0.4, ...]   # ser 0, 1, 2, 3
...

Strikt nedre-triangulär sannolikhetsfördelning per rad. Framtiden förblir osynlig.


Varför en Decoder-Only Transformer Behöver Detta

Decoder-only-modeller som ANDREA, GPT & LLaMA har alla ett gemensamt mål: förutsäg nästa token från det förflutna. En causal mask gör det målet tränbart parallellt: varje position beräknar sin egen nästa-token-förutsägelse på en gång, & ingen position fuskar genom att kika framåt.

Mask & Smak

Aktivitet 2 (intro) täckte tre transformer-smaker: encoder-only, encoder-decoder, decoder-only. (a) Vilken smak använder en causal mask? (b) Förklara i en mening varför en annan smak (encoder-only, som BERT) INTE skulle använda en causal mask. (c) Vilket mål tränar en omaskerad encoder på istället?

Från Poäng till Utmatning

Softmax: Sannolikheter från poäng

Maskerade, skalade poäng varierar fortfarande över reella tal. Softmax omvandlar varje rad till en sannolikhetsfördelning:


A[i][j] = exp(scaled_scores[i][j]) / sum_k exp(scaled_scores[i][k])

Tre egenskaper uppstår:


- A[i][j] >= 0 för alla (i, j).

- sum_j A[i][j] = 1 för varje rad i.

- Större råpoäng ger större sannolikheter (monoton).


Rad i:s sannolikhetsvektor berättar för en modell: hur mycket ska position i uppmärksamma varje tidigare position när dess utdata beräknas?


Viktad V-summa

En slutlig uppmärksamhetsutdata för position i:


output[i] = sum_j A[i][j] · V[j]

Varje värdevektor V[j] vägs med uppmärksamhetsprobabiliteten A[i][j], sedan summeras de. Position i:s utdata kombinerar värdevektorer från varje tidigare position, vägd efter relevans.


I matrisform, alla positioner på en gång:


Attention(Q, K, V) = softmax(mask(Q · K^T / sqrt(d_k))) · V

En rad. En hel uppmärksamhetsmekanism. Vaswani et al. skrev den raden 2017; transformatorer har inte förändrats fundamentalt sedan dess.


Form på utdata per huvud

Utdata från ett uppmärksamhets huvud: form (T, d_k). För ANDREA-120M: (1024, 64). Alla 12 huvuden beräknas parallellt; deras utdata konkateras till (1024, 768) & matas in i en slutlig linjär projektion (W_O), sedan vidare till en transformerblocks MLP.


Aktivitet 6 (grow_a_language_model_multi_head) täcker en multi-head-uppdelning. Aktivitet 7 (grow_a_language_model_transformer_block) täcker allt som omger uppmärksamhet: residualkopplingar, lager-normalisering, MLP.

Syntetisera en pipeline

Syntetisera en komplett uppmärksamhetspipeline med egna ord. Gå igenom vad som händer med en enskild position i (t.ex. position 5 i en sekvens) från invektor x_5 till uppmärksamhetsutdata[5]. Nämn fyra operationer i ordning: (1) projicera till Q/K/V, (2) beräkna skalade poäng mot alla positioner, (3) applicera kausal mask + softmax, (4) summera V-vektorer viktade med sannolikheter. Ett kort stycke.