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

un

gast
1 / ?
terug naar lessen

Query, Key, Value

Drie Lineaire Afbeeldingen van Zelfde Invoer

Na embedding (activiteit 4) draagt elke positie een 768-dimensionale vector x_t. Attention begint met het produceren van drie verschillende projecties van x:


Q (query): wat wil deze positie weten?


K (key): wat biedt deze positie aan andere posities?


V (value): welke inhoud levert deze positie als deze wordt bezocht?


Elke projectie komt uit een geleerde gewichtsmatrix:


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

Drie matrices, allemaal getraind via backpropagation. Een model leert: op deze positie, welke query haalt de nuttigste voorbije context het beste op? Welke key adverteert de inhoud van deze positie goed? Welke waarde wordt geleverd als deze wordt geselecteerd?


Scaled dot-product attention


Bibliotheekanalogie

Stel je een bibliotheekkaartcatalogus voor. Je loopt naar binnen met een onderwerp in gedachten (je query). Elke kaart somt trefwoorden op (een key). Wanneer je onderwerp overeenkomt met de trefwoorden op een kaart, pak je de inhoud van een boek (een value). Attention doet dit voor elk token parallel: elke positie queryt elke andere positie, rangschikt de afstemming, & haalt een gewogen combinatie van value-vectoren op.


ANDREA-120M Dimensies


HoeveelheidWaardeOpmerkingen
d_model768Vectorgrootte op elke positie
n_head12Parallelle attention heads
d_k64Afmeting per head (= d_model / n_head)
T1024Contextlengte

d_k = d_model / n_head = 768 / 12 = 64. Elke head ziet een 64-dimensionale slice van een volledige 768-dimensionale ruimte. Activity 6 (grow_a_language_model_multi_head) behandelt een per-head splitsing in detail.

Bereken d_k

Bereken d_k voor twee ANDREA-varianten. (a) ANDREA-12M: d_model = 384, n_head = 12. (b) ANDREA-480M: d_model = 1536, n_head = 24. Toon je formule d_k = d_model / n_head voor elk.

Waarom delen door sqrt(d_k)

Een Score Matrix

Zodra Q & K bestaan (elk met vorm (T, d_k)), berekent attention een score matrix:


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

scores[i, j] = hoe sterk de query van positie i uitgelijnd is met de key van positie j. Elk (i, j)-paar krijgt één score: 1024 × 1024 = 1.048.576 scores per attention head per forward pass.


Waarom delen

Dot products van twee willekeurige d-dimensionale eenheidsvectoren hebben een grootte van orde sqrt(d). Zonder schaling groeien de scores mee met d_k:


- d_k = 64: typische dot products van orde 8.

- d_k = 256: typische dot products van orde 16.

- d_k = 4096: typische dot products van orde 64.


Grote scores produceren een piekige softmax (één positie domineert, gradients verdwijnen elders). Training stagneert. Scaling corrigeert een grootte:


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

Voor ANDREA-120M is sqrt(d_k) = sqrt(64) = 8. Elke score wordt gedeeld door 8. Magnitudes blijven ruwweg op unit-schaal ongeacht d_k. Softmax blijft goed gedragen. Gradienten stromen.


Vaswani's Originele Rechtvaardiging

Uit Attention Is All You Need (2017): 'Voor grote waarden van d_k worden de dot products groot in magnitude, waardoor de softmax-functie in regio's wordt geduwd waar deze extreem kleine gradienten heeft.' Een deler sqrt(d_k) werkt dit groeiproces tegen.


Een Codeweergave

In microgpt_cuda.cu verschijnt deze schaling als een letterlijke deling:


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

Eén float vermenigvuldiging per score. Goedkoop. Cruciaal.

Schaal bij d_model = 4096

Stel dat een onderzoeksteam ANDREA-2B bouwt met d_model = 4096 & n_head = 32. (a) Bereken d_k. (b) Bereken sqrt(d_k). (c) Leg in één zin uit wat er zou gebeuren als een team vergat te delen door sqrt(d_k) op deze schaal.

Waarom Positie i Positie j > i Niet Kan Zien

Een Beperking Geboren uit Generatie

ANDREA genereert één token tegelijk. Bij inferentie produceert positie 0 een eerste token, dan ziet positie 1 de output van positie 0 & produceert een tweede token, & zo verder. Een model heeft nooit toegang tot toekomstige tokens tijdens generatie.


Training moet dit weerspiegelen. Als tijdens training positie 5 aandacht kan geven aan positie 6, leert een model een shortcut: 'voorspel token 6 door token 6 te lezen'. Bij inferentie verdwijnt die shortcut (token 6 bestaat nog niet). Het gedrag van een model tijdens training-versus-inferentie zou catastrofaal divergeren.


Een Masker

Een causaal masker blokkeert aandacht van elke positie i naar elke positie j > i. Implementatie: stel scaled_scores[i][j] = -oneindig in waar j > i. Na softmax worden die waarden exp(-inf) = 0. Masker zet aandacht naar toekomstige posities netjes op nul.


for i in range(T):
for j in range(T):
if j > i:
scaled_scores[i][j] = -1e9   # effectief -inf

Na softmax (rijgewijs) somt elke rij op tot 1, maar alleen de elementen [0, i] dragen waarschijnlijkheidsmassa. Positie i mixt informatie alleen van eerdere posities.


Een mask visualiseren

Een score-matrix vorm (T, T) met mask toegepast ziet eruit als een lager-driehoekige structuur:


scaled_scores na mask, row-wise softmax:

rij 0:  [1.0, 0,   0,   0,   ...]   # ziet alleen zichzelf
rij 1:  [0.4, 0.6, 0,   0,   ...]   # ziet posities 0, 1
rij 2:  [0.2, 0.3, 0.5, 0,   ...]   # ziet 0, 1, 2
rij 3:  [0.1, 0.2, 0.3, 0.4, ...]   # ziet 0, 1, 2, 3
...

Strikt lager-driehoekige waarschijnlijkheidsverdeling per rij. Toekomst blijft onzichtbaar.


Waarom een Decoder-Only Transformer Dit Nodig Heeft

Decoder-only modellen zoals ANDREA, GPT en LLaMA hebben allemaal één doel: voorspel het volgende token vanuit het verleden. Een causale masker maakt dat doel parallel trainbaar: elke positie berekent tegelijkertijd zijn eigen volgende-tokenvoorspelling, en geen positie kijkt vooruit door te spieken.

Masker & Smaak

Activiteit 2 (intro) behandelde drie transformer-smaken: encoder-only, encoder-decoder, decoder-only. (a) Welke smaak gebruikt een causaal masker? (b) Leg in één zin uit waarom een andere smaak (encoder-only, zoals BERT) GEEN causaal masker zou gebruiken. (c) Welk doel traint een ongemaskeerde encoder in plaats daarvan?

Van Scores naar Output

Softmax: Scores naar Waarschijnlijkheden

Gemaskeerde, geschaalde scores variëren nog steeds over reële getallen. Softmax zet elke rij om in een waarschijnlijkheidsverdeling:


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

Drie eigenschappen zijn het resultaat:

Explanation of Translation Choices

Key Decisions: - Technical terms preserved: "Softmax", "probability distribution" → "waarschijnlijkheidsverdeling", math notation unchanged - Precise terminology: "Masked, scaled scores" → "Gemaskeerde, geschaalde scores" (standard ML Dutch terms) - Natural flow: "Scores to Probabilities" → "Scores naar Waarschijnlijkheden" - Exact preservation: All code blocks, math formulas, formatting, and placeholders untouched Dutch ML Terminology Used: | English | Dutch | |---------|-------| | probability distribution | waarschijnlijkheidsverdeling | | real numbers | reële getallen | | result | resultaat |


- A[i][j] >= 0 voor alle (i, j).

- sum_j A[i][j] = 1 voor elke rij i.

- Grotere ruwe scores produceren grotere waarschijnlijkheden (monotoon).


De waarschijnlijkheidsvector van rij i vertelt een model: hoeveel moet positie i aandacht besteden aan elke vorige positie bij het berekenen van de uitvoer?


Gewogen V Som

Een finale attention-uitvoer voor positie i:


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

Elke waarde-vector V[j] wordt gewogen door de attention-waarschijnlijkheid A[i][j], en vervolgens opgeteld. De uitvoer van positie i combineert waarde-vectoren van elke voorgaande positie, gewogen naar relevantie.


In matrixvorm, alle posities tegelijk:


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

Eén regel. Een hele attention-mechanisme. Vaswani et al. schreven die regel in 2017; transformers zijn sindsdien fundamenteel niet veranderd.


Vorm van de Uitvoer per Head

Uitvoer van één attention head: vorm (T, d_k). Voor ANDREA-120M: (1024, 64). Alle 12 heads berekenen parallel; hun uitvoer wordt geconcateneerd tot (1024, 768) & gevoed in een finale lineaire projectie (W_O), daarna naar de MLP van een transformer block.


Activiteit 6 (grow_a_language_model_multi_head) behandelt een multi-head splitsing. Activiteit 7 (grow_a_language_model_transformer_block) behandelt alles wat attention omringt: residuale verbindingen, layer norm, MLP.

Synthetiseer een Pipeline

Synthetiseer een volledige attention pipeline in je eigen woorden. Loop door wat er gebeurt met een enkele positie i (bijv. positie 5 in een sequentie) van invoervector x_5 tot attention output[5]. Noem vier operaties in volgorde: (1) projecteer naar Q/K/V, (2) bereken geschaalde scores tegen alle posities, (3) pas causale masker + softmax toe, (4) som V-vectoren gewogen door waarschijnlijkheden. Eén korte paragraaf.