← NLP Recommended Papers
NLP · Recommended Papers · The Transformer

Attention Is All You Need

Paper: Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Łukasz Kaiser, and Illia Polosukhin. Read the paper.

Before this: vectors, matrix multiplication, softmax, and the weighted-context idea in additive attention.

A recurrent encoder passes information along a chain of states. Self-attention lets each position form a weighted combination of other positions directly. The Transformer organizes that operation into a sequence model with separate rules for reading an input and generating an output.

This companion builds a tiny, hand-set example: three positions, four coordinates, and two attention heads. You can reproduce every weight, change a future input, and see exactly when a causal mask blocks its influence. These teaching weights are not learned parameters from the paper.

What changes when the recurrent chain disappears?

Consider a translation whose source contains three tokens. In a recurrent encoder, the third hidden state depends on the second, which depends on the first. In a self-attention layer, all three positions can construct their queries, keys, and values from the same layer input. Their pairwise comparisons can be computed together.

That removes a dependency within this layer; it does not remove every sequential dependency. Layer two still needs layer one. During ordinary autoregressive generation, the next token is still unknown until the preceding token has been generated. The authors’ Google Research explanation describes the motivation and parallel training advantage.

Two streams, three different uses of attention

Source → encoder

  1. Embed each source positionAdd its position information.
  2. Source self-attentionEach source position can read every permitted source position.
  3. Residual + normalizationRetain the incoming representation and normalize its coordinates.
  4. Feed-forward transformationApply the same nonlinear function separately to each position, then another residual + normalization.
  5. Encoder memoryKeep one contextual vector per source position.

Previous targets → decoder

  1. Shift target inputs rightStart token, then the previously known target tokens; embed them and add position information.
  2. Causal self-attentionRead this input position and earlier target inputs only.
  3. Read encoder memoryDecoder queries compare with encoder keys and combine encoder values.
  4. Feed-forward transformationAttention and feed-forward sublayers each have their own residual + normalization.
  5. Predict a target tokenMap the decoder vector to vocabulary logits, then probabilities.
Embeddings and position information enter once at the bottom. The attention and feed-forward sublayers repeat in the stacks, with separate parameters per layer. Vocabulary prediction follows the final decoder layer. Source padding also needs a mask. Cross-attention reads source memory, so it is not restricted by the target’s causal triangle.

The original base configuration uses six encoder and six decoder layers, model width 512, eight heads, and feed-forward width 2048. Its residual sublayers use normalization after addition. Modern variants need not preserve those choices. Paper §3.

Queries choose weights; values supply the content

Let $X$ contain one input vector per row. A head has three learned projections:

$$Q=XW_Q,\qquad K=XW_K,\qquad V=XW_V.$$

A query is the vector used to ask what this position should read. Keys are the vectors it compares against. Values contain the coordinates that will actually be combined. All three come from $X$ in self-attention, but their projection matrices can differ. A high query–key score does not mean the key vector itself becomes the output.

For query row $i$ and key row $j$, form a score, normalize across allowed keys, and combine values:

$$s_{ij}=\frac{q_i^\top k_j}{\sqrt{d_k}},\qquad a_{ij}=\frac{\exp(s_{ij})}{\sum_{r\in\mathcal A_i}\exp(s_{ir})},\quad j\in\mathcal A_i.$$
$$o_i=\sum_{j\in\mathcal A_i}a_{ij}v_j.$$

Here $d_k$ is the number of query/key coordinates and $\mathcal A_i$ is the set of allowed keys. Forbidden weights are zero. The denominator is per query row: each row sums to one, while a column need not. In matrix notation:

$$\operatorname{softmax}_{\rm row}\!\left(\frac{QK^\top}{\sqrt{d_k}}+M\right)V.$$

Here $M$ is zero at permitted entries and negative infinity at forbidden ones.

One head with n queries and m keys
QuantityShapeMeaning
Qn × dₖOne question vector per query
Km × dₖOne comparison vector per key
QKᵀ and weightsn × mEvery query compared with every key
Vm × dᵥOne content vector per key
Outputn × dᵥWeighted content at each query

Self-attention has n = m because both sides are the same sequence. Cross-attention may have different source and target lengths. Batch and head dimensions sit outside these matrices; softmax must still operate along the key dimension.

An original three-position, two-head calculation

Take these inputs to one attention sublayer. Treat them as already supplied representations; this example does not train embeddings or add a separate position vector.

$$X=\begin{pmatrix}1&0&1&0\\0&1&0&1\\1&1&0&0\end{pmatrix}.$$

Head 1 uses coordinates 1–2 for its queries and keys, and 3–4 for its values. Head 2 does the reverse. Each head therefore has $d_k=d_v=2$. These projections select coordinates, a particularly transparent special case of a learned linear map.

See the exact projection matrices
$$P=\begin{pmatrix}1&0\\0&1\\0&0\\0&0\end{pmatrix},\qquad R=\begin{pmatrix}0&0\\0&0\\1&0\\0&1\end{pmatrix}.$$

Use $W_Q^{(1)}=W_K^{(1)}=P$, $W_V^{(1)}=R$; and $W_Q^{(2)}=W_K^{(2)}=R$, $W_V^{(2)}=P$. Concatenate the two head outputs in that order and set $W_O=I_4$. Biases and dropout are omitted. Within each head, Q and K use the same projection here; the two heads use different projections. Real heads do not require Q and K to share a projection.

At position 3, head 1’s query is [1, 1]. Its three dot products are [1, 1, 2]; after division by √2, the scores are [0.707107, 0.707107, 1.414214]. Subtracting the maximum before exponentiating leaves [−0.707107, −0.707107, 0], so the weights are approximately [0.248255, 0.248255, 0.503490].

The values are [1, 0], [0, 1], and [0, 0]. Despite receiving the largest weight, the third value contributes a zero vector. Thus head 1 returns [0.248255, 0.248255]. Head 2’s query is [0, 0], giving three equal scores, uniform weights, and the average of [1, 0], [0, 1], and [1, 1]: [2/3, 2/3].

Inspect the two heads, then change what they can read

Position 3 · causal mask · divided by √2 · original final row.

Head 1

Selected query: [1.000000, 1.000000]

Attention weights: Q rows → K columns
QueryK1K2K3
Q11.0000.0000.000
Q20.3300.6700.000
Q30.2480.2480.503

Allowed scores: [0.707107, 0.707107, 1.414214]

Key 1 · weight 0.248255Value [1.000000, 0.000000]
Weighted value [0.248255, 0.000000]
Key 2 · weight 0.248255Value [0.000000, 1.000000]
Weighted value [0.000000, 0.248255]
Key 3 · weight 0.503490Value [0.000000, 0.000000]
Weighted value [0.000000, 0.000000]

Head output: [0.248255, 0.248255]

Head 2

Selected query: [0.000000, 0.000000]

Attention weights: Q rows → K columns
QueryK1K2K3
Q11.0000.0000.000
Q20.3300.6700.000
Q30.3330.3330.333

Allowed scores: [0.000000, 0.000000, 0.000000]

Key 1 · weight 0.333333Value [1.000000, 0.000000]
Weighted value [0.333333, 0.000000]
Key 2 · weight 0.333333Value [0.000000, 1.000000]
Weighted value [0.000000, 0.333333]
Key 3 · weight 0.333333Value [1.000000, 1.000000]
Weighted value [0.333333, 0.333333]

Head output: [0.666667, 0.666667]

Concatenate → identity output projection
[0.248255, 0.248255, 0.666667, 0.666667]
Add input row
[1.248255, 1.248255, 0.666667, 0.666667]
Normalize its four coordinates
[0.999994, 0.999994, -0.999994, -0.999994]
Rows are query positions; columns are key positions. Darker cells have larger weights on a fixed 0–1 scale. Dashed gray cells are forbidden and contribute zero. The highlighted row supplies the displayed head output. Inputs and projections are hand-set; these are computed examples, not observed translation alignments.

Multi-head attention concatenates the two outputs and then applies an output projection. Our identity output projection leaves [0.248255, 0.248255, 0.666667, 0.666667]. Averaging the heads would instead give only two coordinates and erase their separate outputs. A learned $W_O$ can subsequently mix the concatenated coordinates; it does not make concatenation and averaging the same operation.

Test the causal rule by changing the future

Select position 2 and keep the causal mask. Its allowed keys are positions 1 and 2, so both heads give weights approximately [0.330238, 0.669762, 0]. Now change the final input row. The selected output must remain identical: that row is a forbidden key/value, and position 2’s query has not changed.

Switch to “All positions.” The same future change can now alter position 2’s output. That is appropriate for bidirectional encoding, but would leak future target information in an autoregressive decoder. Position 3 can change in either mode because the edited row is its own input, not its future.

A causal mask alone is insufficient if the target inputs are misaligned. For the desired targets A B END, teacher-forced decoder inputs should be START A B. Position 2 reads START and A to predict B. Feeding B at that same input position would reveal the answer even though the mask blocks positions after 2.

Why zeroing forbidden scores is wrong

Zero is a valid logit and contributes exp(0) = 1 to the denominator. A forbidden entry needs zero probability, which is achieved by excluding it from normalization or assigning a logit of negative infinity before softmax. Our code represents exclusion with None. A query with no permitted key is rejected rather than normalized into NaNs.

A padding mask answers a separate question: which stored positions are real tokens? Combine causal and padding restrictions deliberately. Boolean-mask conventions vary between APIs; inspect the chosen function’s documentation instead of assuming True always means “blocked.”

Scaling changes the distribution, not just the units

Disable scaling at position 3. Head 1 now uses [1, 1, 2], yielding [0.211942, 0.211942, 0.576117]. More weight goes to the largest score. Because its value is zero, each output coordinate decreases from 0.248255 to 0.211942. This connects a change in logits to an actual change in retrieved content.

A simple variance calculation explains the square-root factor. If each query/key coordinate is independent, centered, and has variance 1, then each product has variance 1 and the sum of $d_k$ products has variance $d_k$. Dividing by $\sqrt{d_k}$ returns variance 1 under those assumptions. Learned coordinates need not satisfy the assumptions exactly; scaling is not a guarantee that attention remains diffuse.

Subtracting the row maximum is different: softmax is unchanged by adding the same constant to every allowed score. It prevents overflow without changing the modeled probabilities. Dividing scores changes their differences and therefore changes those probabilities.

Attention is one sublayer, not the whole model

Our position-3 attention output is added to its incoming vector [1, 1, 0, 0]. The residual sum is [1.248255, 1.248255, 0.666667, 0.666667]. With normalization across its four coordinates, mean 0.957461, scale parameters γ = 1 and β = 0, and ε = 10⁻⁶, the normalized vector is approximately [0.999994, 0.999994, −0.999994, −0.999994].

This operation normalizes a position’s features, not all tokens in the sequence together. A constant vector becomes zero before the learned offset; the epsilon prevents division by zero. The LayerNorm definition specifies the mean, population-variance denominator, and learned affine terms.

The feed-forward sublayer then applies a shared nonlinear function to each row, for example $\operatorname{ReLU}(zW_1+b_1)W_2+b_2$. “Shared” means the same weights are used at every position, not that the positions have identical outputs. Attention mixes information between positions; this sublayer transforms each contextual vector’s coordinates. Another residual connection preserves a direct route around that transformation.

The toy stops after the first residual normalization. It does not include a feed-forward fit, cross-attention, vocabulary projection, or training. Those omissions make the arithmetic inspectable; they must not be mistaken for a complete Transformer implementation.

Why position information is needed

Without position information or an order-dependent mask, permuting the input rows permutes the self-attention output rows in the same way. Pairwise dot products and weighted sums have no independent notion of “first” or “third.” This is useful symmetry for a set, but insufficient to represent arbitrary word order.

The paper adds sinusoidal position vectors. For each frequency pair, advancing position rotates a sine/cosine pair by a fixed angle; that is a property of the representation, not a promise that learned translation behavior extrapolates to any sequence length. The cyclical-encoding example develops the same paired-coordinate geometry. A causal mask supplies an ordering restriction too, but it is not the same mechanism as adding positional features.

Parallel work still has a cost

With n positions and total model width d, projections take on the order of nd² arithmetic operations. Computing dense query–key comparisons and mixing values takes on the order of n²d across heads when their widths sum to d. A straightforward implementation stores h matrices of size n × n for h heads.

For n = 1,024 and eight heads, that is 8,388,608 attention entries: 16 MiB if each stored entry uses two bytes, before gradients or other activations. Doubling n quadruples that entry count. Implementations can avoid materializing the whole matrix, but “parallel” alone does not remove the pairwise work.

During teacher forcing, every shifted target input is already available, so causal rows can be computed in parallel. At generation time, the next input token depends on the latest prediction. Keeping previous keys and values avoids recomputing their projections; it does not make unknown future tokens available.

Read the reported results in their original setting

Reported WMT 2014 test BLEU; original NeurIPS proceedings, Table 2
ModelEnglish→GermanEnglish→French
Transformer base27.338.1
Transformer big28.441.0

These are machine-translation results under the paper’s data, tokenization, training, checkpoint, and decoding setup. They are not accuracy percentages or results from this toy. The larger model’s gains were 1.1 and 2.9 BLEU points over the base model in that table. Original proceedings, Table 2.

Version matters: the later arXiv v7 Table 2 gives 41.8 for big English→French, while its nearby prose still says 41.0. The table above follows the original conference PDF so the source version is explicit.

The useful reading question is what the comparison demonstrates: the proposed encoder–decoder could train and translate competitively without a recurrent sequence operator. It does not establish that every task benefits equally, that all heads learn distinct linguistic roles, or that attention weights alone identify a causal explanation.

Reproduce and challenge the calculation

Download the complete standard-library Python example and all 24 computed states. The script records every projected vector, allowed score, weight, head output, residual sum, and normalized vector. The following is the standalone masked normalization at its core:

Run a stable softmax with explicit forbidden keys
import math

def masked_softmax(scores):
    # None marks a forbidden key, not a numerical score of zero.
    allowed = [score for score in scores if score is not None]
    if not allowed:
        raise ValueError("No permitted key for this query")
    maximum = max(allowed)
    numerator = [0.0 if s is None else math.exp(s - maximum)
                 for s in scores]
    denominator = sum(numerator)
    return [n / denominator for n in numerator]

weights = masked_softmax([0.0, 1 / math.sqrt(2), None])
assert abs(sum(weights) - 1) < 1e-12
assert weights[2] == 0
print(weights)  # [0.3302384507, 0.6697615493, 0.0]

Useful checks go beyond a row sum of one. Change a forbidden future row and compare an earlier output. Verify that reversing the head-concatenation order changes the coordinates unless the output projection changes accordingly. Check that a constant offset leaves softmax unchanged while scaling does not. Finally, compare head outputs, not only their heatmaps: the values determine what information is carried forward.

Where to go next

Additive attention explains learned alignment while retaining a recurrent decoder. This chapter replaces the sequence operator and separates three attention roles. BERT and GPT-2 then make different choices about permitted context and training tasks; they should not be read as interchangeable applications of one mask.

For a broader implementation-oriented explanation, continue to the Transformer and pretraining textbook chapter. When reading any implementation, write down its input shift, mask convention, normalization order, dimensions, and output units before matching it to a paper diagram.

References