Part XI — Sequence Models: RNNs, LSTMs, Attention & The Transformer Block · Chapter 8

The attention mechanism

Hook

Even with gating, an RNN — short for Recurrent Neural Network — still processes a sequence strictly left to right, folding everything into one hidden state as it goes. Attention throws that constraint out: instead of compressing a sequence into one running summary, keep every token's vector around, and let a query look at all of them at once.

Intuition
the0.33cat0.33sat0.33query
query = (1.0, 1.0) — attention spread evenly across all three

Three tokens sit at fixed points; a query (the ×) is what's currently "looking." Drag it around. The token whose vector points in a similar direction to the query gets more weight — dragging toward "cat" pulls almost all the attention onto "cat," dragging to the middle spreads it evenly across all three.

Formalize

For a query qq and a set of token (key) vectors kik_i, attention computes a similarity score for each one, turns those scores into weights that sum to 11, and returns their weighted blend:

scorei=qkid,wi=softmax(score)i,context=iwiki\text{score}_i = \frac{q \cdot k_i}{\sqrt{d}}, \qquad w_i = \text{softmax}(\text{score})_i, \qquad \text{context} = \sum_i w_i\, k_i
  • qq — the query vector: what's currently "looking," trying to find relevant tokens.
  • kik_i — the key vector for token ii, one of the fixed set of tokens being attended to.
  • dd — the dimensionality of the query and key vectors, used to rescale the dot product.
  • scorei\text{score}_i — the raw, scaled similarity between the query and token ii's key.
  • wiw_i — the attention weight on token ii, the softmax-normalized score.
  • context — the weighted blend of all the key vectors: the actual output of attention.
  1. Why scale by the square root of d

    The d\sqrt{d} divides out the fact that dot products grow with dimension dd — without it, scores in a high-dimensional model would blow up and softmax would saturate into an almost one-hot distribution regardless of which token actually matches best.

Play
the0.77cat0.05sat0.19query
weights: the=0.77, cat=0.05, sat=0.19 — context = (1.72, 0.28)

Watch the context vector — the actual output of attention — as you drag the query. It's always some blend of "the," "cat," and "sat," and it moves smoothly as the weights shift. This is the payoff: instead of one RNN hidden state trying to remember an entire sequence, attention produces a fresh, query-specific blend of all of it, recomputed on demand.

Worked example

At query q=(2,0)q=(2,0) — aligned with "the" =(2,0)=(2,0):

  1. Raw dot products

    With "the"=(2,0)=(2,0), "cat"=(0,2)=(0,2), "sat"=(1,1)=(1,1):

    • "the": (2)(2)+(0)(0)=4(2)(2)+(0)(0)=4
    • "cat": (2)(0)+(0)(2)=0(2)(0)+(0)(2)=0
    • "sat": (2)(1)+(0)(1)=2(2)(1)+(0)(1)=2
  2. Scale by the square root of d

    Dividing each by 21.414\sqrt{2}\approx1.414:

    • "the": 4/1.4142.8284/1.414\approx2.828
    • "cat": 0/1.414=00/1.414=0
    • "sat": 2/1.4141.4142/1.414\approx1.414
  3. Softmax into weights

    Exponentiating each score and dividing by their sum 16.92+1+4.1122.0316.92+1+4.11\approx22.03:

    • "the": e2.82816.92e^{2.828}\approx16.92, so 16.92/22.030.76816.92/22.03\approx0.768
    • "cat": e0=1e^0=1, so 1/22.030.0451/22.03\approx0.045
    • "sat": e1.4144.11e^{1.414}\approx4.11, so 4.11/22.030.1874.11/22.03\approx0.187

    "The" dominates, but "sat" (whose vector partially overlaps) still gets a meaningful share, and "cat" (pointing in an unrelated direction) gets almost none.

Checkpoint

Drag the query until cat receives more than 0.7 of the total attention weight.

the0.33cat0.33sat0.33query
"cat" weight = 0.333
Drag the query to try it
Summary
context=isoftmax ⁣(qkid)iki\text{context} = \sum_i \text{softmax}\!\left(\frac{q \cdot k_i}{\sqrt{d}}\right)_i k_i

This chapter used one query looking at a fixed set of tokens — the original attention mechanism, first built to let a decoder look back at every encoder state instead of just the last one. The next chapter asks what happens when every token in a sequence gets to be a query looking at every other token, all at once, and why that needs more than one attention computation running in parallel.