Query, Key and Value — where they come from, what they mean, and why this single operation replaced twenty years of recurrent networks.
Read this sentence and answer quickly: "The trophy didn't fit in the suitcase because it was too big."
"It" is the trophy. You know that instantly. Now change one word: "…because it was too small." Now "it" is the suitcase. The pronoun's referent changed because of an adjective that sits seven words later.
To process that, the model needs the representation of "it" to be able to fetch information from any other position in the sentence, choosing dynamically where to look. Not at a fixed position, not at the previous word — anywhere, depending on the content.
Until 2017, this was done with recurrent networks: read word by word, carrying a "memory state" that is updated at each step. Two fatal weaknesses:
Attention solves both at once: each position looks directly at all the others, and all positions are computed at the same time.
Attention turns the problem of "remembering the past" (hard, sequential, lossy) into the problem of "searching the past" (easy, parallel, lossless). That trade is what unlocked scale, and scale is what produced everything that came after.
Forget matrices for a minute. Think of a search system. It has three roles:
| Role | Symbol | In the database | In the sentence |
|---|---|---|---|
| Query (question) | what you typed into the search | "I am the pronoun it, I am looking for a singular noun that could be my antecedent" | |
| Key (label) | the indexed label of each item | "I am trophy, noun, singular, physical object" | |
| Value (content) | the content returned when the item matches | the full meaning of trophy, which will be handed to whoever asked |
An ordinary database does hard lookup: the query matches exactly one key, and returns that value. Attention does soft lookup: the query is compared against all the keys, each one receives a compatibility score, the scores become percentages that add up to 100%, and the result is a weighted average of all the values.
"it" asks. "trophy" answers with 71% relevance, "suitcase" with 22%, "big" with 5%, the rest splits 2%. The new vector of "it" becomes 0.71×trophy + 0.22×suitcase + 0.05×big + … It stopped being an empty pronoun and became a pronoun that already carries what it refers to. That is, literally, the operation that happens.
This is the point that causes the most confusion, so let's go slowly. Q, K and V are not separate things that exist in the text. They are three different projections of the same input vector.
Each token arrives with its 768-dimensional vector
Why three? Because the roles are asymmetric. What a token wants to look for is not the same thing it wants to announce about itself, and neither of those is the information it wants to deliver when it gets chosen.
If we used the same vector for query and key, attention would be forced to be symmetric — if A looks a lot at B, B would have to look a lot at A. But language is not like that: a pronoun searches for its antecedent with urgency, and the noun has no reciprocal interest in the pronoun.
In GPT-2's real code the three matrices are fused into one, of size 768×2304 (= 3×768), called c_attn. A single multiplication is done and the result is then cut into three pieces. It is purely efficiency — one big matmul is faster than three small ones. Conceptually they are three matrices.
This is the Transformer equation. I will write it and then take it apart piece by piece.
Multiplying
This is where the quadratic cost is born. That matrix has
Why divide by the square root of the dimension? It is not aesthetics — it is a statistical necessity.
Suppose
And why does that matter so much? Because the next step is the softmax, which involves
A saturated softmax has practically zero gradient. The model stops learning. The division by √
The √temperature parameter you will use in generation (chapter 07). The same math, in two places in the model.
The resulting n×n matrix
One attention head of GPT-2 small, sentence of 5 tokens: h (5, 768) input (chapter 02) | |-- x W_Q (768,64) --> Q (5, 64) |-- x W_K (768,64) --> K (5, 64) |-- x W_V (768,64) --> V (5, 64) Q @ K.T -> (5, 5) raw scores / sqrt(64) -> (5, 5) scaled softmax(dim=-1) -> (5, 5) <-- THE ATTENTION MAP (rows sum to 1) @ V -> (5, 64) head output Note: d_k = 64 = 768 / 12 heads. Each head works in a narrow subspace. In chapter 04 the 12 are joined back into 768.
import torch, math import torch.nn.functional as F def atencao(Q, K, V): """Q,K,V: (n, d_k). Returns (n, d_k) and the map (n, n).""" d_k = Q.shape[-1] # 1) every query against every key -> (n, n) scores = Q @ K.transpose(-2, -1) # 2) stabilize the scale so the softmax does not saturate scores = scores / math.sqrt(d_k) # 3) each row becomes a distribution that sums to 1 A = F.softmax(scores, dim=-1) # 4) weighted average of the values return A @ V, A
Those are the four lines. Everything most impressive that GPT-2, RoBERTa, GPT-4 and Claude do is this operation, repeated with many heads, many layers and lots of data. The core idea fits in four lines.
.venv\Scripts\python.exe lab\03_attention.py
output_attentions=True) for the trophy sentence, and draws the map in ASCII with intensity.The rigorous result. The attention of the token "it" is bit-for-bit identical in the two sentences — maximum difference exactly 0.00. That is not a bug: "it" is at position 9 and "big"/"small" at 12. In a causal model, the past cannot be affected by the future. You have just experimentally proven the causality of chapter 04, and a RoBERTa would give a different result here. That is proof, not interpretation.
The uncomfortable result. When we look at the adjective (which sees the whole sentence), the hope was that "big" would link to the trophy and "small" to the suitcase. It does not happen. Both look more at the suitcase, and the difference is noise. The reason: ~66% of all attention is dumped on the first token — the so-called attention sink — and very little budget is left for the rest.
Another example that "worked" could have been chosen. This one stayed because it teaches the lesson that matters: attention maps are suggestive, not explanatory. Jain & Wallace published exactly this in 2019 ("Attention is not Explanation"), showing that attention weights can be altered considerably without changing the model's output. Attention shows where information may have flowed — not where it decided to. Reading these maps as if they were the model's explanation is a mistake, and a costly one.
The primary sources for the concepts in this chapter. The numbers in the text were measured in the lab; the ideas come from here.
Technical terms here carry their machine-learning meaning. The course glossary shows that meaning next to the others the same words have in IT.
One attention head can only look for one kind of relation at a time. And, as it stands, it lets every token see the future.
Chapter 04 solves both problems: multi-head and the causal mask.