From Soft Alignment to Queries, Keys, and Values: Deriving the Transformer's Attention
The Q/K/V abstraction derived from first principles — why Bahdanau's feedforward alignment collapses to a dot product, how the Transformer formalizes queries, keys, and values as separate projections, why we scale by √d_k (with a complete variance proof), what multi-head attention adds, and a full 3-token self-attention numerical walkthrough
In the previous post, we derived Bahdanau attention from scratch: a feedforward compatibility function , softmax normalization, and a dynamic context vector . It worked. The model learned to align source and target words without any explicit supervision.
But the Transformer paper (Vaswani et al., 2017) replaced that feedforward compatibility function with something far simpler: a dot product. In doing so, it unlocked full parallelization, enabled self-attention, and produced the architecture that underpins every major language model today. In this post we derive why, starting from a single question: what is the simplest compatibility function that still works?
1. The Running Example
We keep one tiny sequence throughout:
Think of dimension 1 as encoding “noun-ness” and dimension 2 as encoding “verb-ness.” Token 1 is a pure noun, token 2 is a pure verb, and token 3 is equally both.
We will compute the full scaled dot-product self-attention mechanism on these three vectors by hand.
For readability we display the token vectors vertically, but from this point on we will stack them as rows of the matrix . So individual queries, keys, and values will also be treated as row vectors, and the scalar score between positions and will be written as .
2. Reconsidering the Compatibility Function
In Bahdanau attention, the compatibility score was
This score answered a good question: how compatible is decoder state with encoder annotation ?
But the Transformer wants something else in addition. It wants the score function to work for every pair of positions in parallel, and it wants the whole score matrix to be produced by matrix multiplication.
2.1 What Bahdanau’s Alignment Model Does
The additive alignment model mixes the two inputs inside a nonlinearity: . The query and the key are each projected into a shared hidden space, added, passed through , and then dotted with . That makes the compatibility function expressive, but it also means we cannot precompute a representation of the query alone and a representation of the key alone and then combine them with one large matrix multiply — the interaction happens before the final dot product with . This is not wrong. It is just much less GPU-friendly.
2.2 The Dot-Product Compatibility Function
Suppose we want a score function with the form
where depends only on token and depends only on token .
Then the full matrix of all pairwise scores is
with
This is exactly what modern GPUs are built to do: one matrix multiply computes all pairwise similarities.
2.3 A bilinear view
If the input token at position is the row vector , then the most general batched linear score looks like
for some learned matrix .
Now factor as
Then
Group the terms by associativity of matrix multiplication:
Define
and we get
That is the Transformer’s dot-product compatibility function.
So the dot product is not arbitrary. It is the simplest factorized bilinear score that gives us all pairwise similarities in one matrix multiply.
3. Queries, Keys, and Values
Once the compatibility function has been factorized, the three projections appear naturally.
3.1 Query
A query is what the current position is asking for. If token wants to find relevant information elsewhere in the sequence, its query is .
3.2 Key
A key is how a position advertises what kind of information it contains. At position , the key is . The query and key interact only to produce scores.
3.3 Value
A value is the actual content retrieved once a position is selected. At position , the value is .
3.4 Matrix form
Pack the full sequence into a matrix
Then the three projections are
3.5 Why keys and values are separated
This is the key conceptual difference from Bahdanau attention. In Bahdanau’s model, the encoder states served two roles at once: they were the things scored against, and they were also the things retrieved. In the Transformer, those roles are separated — keys decide how positions are matched, while values decide what content is actually mixed into the output. A token might be easy to find for one reason and useful to retrieve for another.
3.6 A concrete check: scores can stay the same while values change
This is the part that usually feels too abstract on first reading, so let us pin it down with the running example.
Keep the query and key projections equal to the identity:
so the score matrix is unchanged. But now choose a different value projection:
Then the transformed values are:
Notice what happened. The keys used for matching did not change, but the values returned after matching did change. So the attention weights can stay exactly the same while the retrieved content changes. That is the practical meaning of separating keys from values.
4. Deriving the Full Attention Formula
Once we have scores, the rest of the mechanism follows the same pattern as Bahdanau attention. We compute unnormalized scores, normalize them into weights, and then retrieve a weighted combination of values.
4.1 Score matrix
All pairwise scores are
Entry is
4.2 Row-wise softmax
For each query position , we apply softmax over all keys: . This gives a full attention weight matrix , where the softmax is applied row by row.
4.3 Weighted value retrieval
Now retrieve content by multiplying those weights by the values: . Entry-wise, this says . This is exactly the same weighted-memory-retrieval structure as Bahdanau attention, except that the weights came from a batched dot product instead of an additive feedforward score.
4.4 The scaling factor
The Transformer inserts one additional factor of , so the final formula becomes
We now derive why that scaling is needed.
5. Why Divide by ?
This is the part that confuses almost everyone. The scaling is not cosmetic. It is a variance correction.
5.1 Variance of a dot product
Assume the components of a query and key are independent standard normal variables, and for . We want the variance of .
First, the mean of one product term is , using independence and the multiplication rule for expectations of independent variables. Now the variance of one term:
The second term is zero, so
again by independence. Because each variable has variance 1 and mean 0, we have and , so . Now sum over all terms. Since the terms are independent, apply the additivity of variance for independent random variables:
So the unscaled dot product has variance
and therefore standard deviation
5.2 Why large variance hurts softmax
If is large, the dot products become large in magnitude. Large positive gaps in the score vector make softmax almost one-hot, and when that happens the softmax saturates and its gradients become tiny. Dividing by rescales the variance back to 1:
This uses the variance scaling rule:
5.3 Numerical check for our running example
In our running example:
so
If an unscaled score is 1, the scaled score becomes
If an unscaled score is 0.5, the scaled score becomes
The scores are compressed toward zero, which keeps the softmax less extreme.
6. Full Numerical Walkthrough: Self-Attention on Three Tokens
Now we run the whole mechanism start to finish.
To isolate attention itself, we take the simplest projections:
the identity matrix.
Then
for our running example.
6.1 Compute
Write the input matrix:
Then
By the definition of matrix multiplication, each entry is a row-column dot product. Row 1 against the three columns gives , then , and then . Row 2 gives , then , and then . Row 3 gives , then , and finally .
So
6.2 Apply the scaling
Divide by :
6.3 Softmax row 1
Row 1 is
Exponentiate:
Add them:
Normalize:
6.4 Softmax rows 2 and 3
Row 2 is
which is just a permutation of row 1, so
Row 3 has equal entries:
Equal inputs to softmax produce the uniform distribution, so
The full attention matrix is therefore
6.5 Multiply by the values
Since ,
Compute the first output vector:
So
By symmetry,
For token 3:
So
6.6 Interpretation
Token 1 started as a pure noun-like vector and after self-attention became . It kept mostly noun content but absorbed some verb content from the other tokens. That is the core role of self-attention: contextual mixing through learned, content-dependent weighted averages.
7. A Short Comparison: Unscaled vs Scaled
It is worth looking at the scaling effect directly on the running example rather than only through the variance proof.
7.1 Unscaled row 1
Without the scaling, row 1 would be
Exponentiate:
Normalize:
So
7.2 Scaled row 1
With scaling, we got
7.3 What changed
The scaled version is less sharp. The largest weight dropped from about to , and the smaller weights rose correspondingly.
For , the effect is mild. For realistic head sizes like or , the effect becomes much more important.
8. Multi-Head Attention
A single head gives one attention pattern. If we want the model to track several different relations at once, we run several heads in parallel.
8.1 Definition
Each head computes , and the results are concatenated and projected:
8.2 Parameter count
With heads and , the attention parameter count is , as we will re-derive in more detail later in the series. For , that gives parameters in the attention block. The main point of multi-head attention is not more total parameters — it is more parallel attention subspaces.
8.3 Why multiple heads help
A single head produces one attention distribution per token. If token 1 needs to look at token 2 for syntax and token 3 for semantics, one head has to blend those two requirements into one row of weights. Multiple heads let the model keep several attention patterns alive at once — one head can specialize in one relation, another head in another relation, and the output projection can recombine them afterward. This is not a proof that heads always specialize cleanly. It is the representational reason the design exists.
9. Self-Attention, Cross-Attention, and Masked Attention
9.1 Self-attention
In self-attention, queries, keys, and values all come from the same sequence: , , . This is what we computed above.
9.2 Cross-attention
In cross-attention, the queries come from one sequence and the keys/values come from another: , , . This is the Transformer version of Bahdanau-style encoder-decoder attention.
9.3 Masked self-attention
In decoder self-attention, a token must not look at future tokens, so we add a causal mask:
where forbidden entries of are .
9.4 Numerical check on row 2
Take token 2 in our running example. Its unmasked scaled scores were
If token 2 is not allowed to look at token 3, then we replace the third entry with :
Exponentiate:
Normalize:
So the masked attention row becomes
The mask does not merely discourage future attention. It sets the forbidden probability exactly to zero.
10. Why Self-Attention Changed the Path Length
A bidirectional RNN can eventually move information from token 1 to token 3, but it has to do so through intermediate recurrent steps.
In a three-token sequence, the path from token 1 to token 3 through a left-to-right RNN is:
That is two recurrent transitions between the endpoints.
In self-attention, token 3 can attend directly to token 1 in one layer because the score
is computed in the same matrix multiply as every other pair.
So the interaction path length between any two positions inside one self-attention layer is 1.
10.1 Numerical check
In our running example, token 3 attends to token 1 with score before scaling and after scaling. That direct token-3-to-token-1 interaction is present immediately in the score matrix — no recurrence is needed to transmit it across intermediate positions. This shorter path length is one of the reasons self-attention handles long-range interactions so well.
11. Positional Information
Self-attention has one major omission: the formula itself does not know token order.
11.1 Why order is missing
If we permute the rows of , then the rows of , , and are permuted in the same way, and the output rows are then permuted in the same way. That means the bare self-attention mechanism is permutation equivariant. This is good for set processing, but bad for language, where “dog bites man” and “man bites dog” must not mean the same thing.
11.2 Positional encodings
The Transformer solves this by adding a positional vector to each token embedding before attention:
The original paper uses sinusoidal positional encodings:
11.3 Why sinusoids are convenient
The sine and cosine features have a useful relative-position property because of the angle-addition identities:
These identities mean a fixed offset in position can be represented as a linear transformation of the sinusoidal features.
That is why the model can learn relative offsets even though the encoding is written in absolute positions.
11.4 Numerical check for the first sinusoidal pair
Take the first two positional dimensions, where the denominator is 1. Then the encoding pair is simply
At positions :
So even this first frequency pair already gives each position a distinct two-dimensional signature. Higher dimensions add slower oscillations, which let the model represent both fine local offsets and broader global position.
12. Bahdanau Attention and Transformer Attention as One Story
We can now place both mechanisms inside one unified retrieval template.
12.1 Bahdanau attention
In Bahdanau attention, the query is the decoder state , the key is the encoder annotation , the value is that same encoder annotation , and the score is produced by an additive feedforward compatibility function.
12.2 Transformer attention
In Transformer attention, the query is a learned projection of the current token, the key is a learned projection of a candidate memory token, the value is another learned projection of that candidate memory token, and the score is the scaled dot product.
12.3 The unified view
Both mechanisms compute
and then
So the Transformer does not abandon attention — it re-expresses the same retrieval idea in a form that is easier to batch, easier to parallelize, and better suited to self-attention over one sequence.
Summary
The Transformer’s attention formula comes from one simple design goal: factor the compatibility score so all pairwise interactions can be computed by matrix multiplication. That leads to queries and keys, softmax turns their dot products into weights, values carry the retrieved content, and the factor rescales the score variance so the softmax does not saturate.
In our three-token example, this produces scaled scores, attention weights, and contextualized outputs entirely by hand. The next post asks what happens when we stop thinking about three tokens and start thinking about 4K, 8K, or 128K tokens, where the same clean formula runs head-first into quadratic cost.
Previous: What Attention is Really Doing
Next: Why Vanilla Attention Breaks at Scale
Enjoyed this post?
Subscribe to get notified when I publish new posts. No spam, unsubscribe anytime.