Home / Attention

The Attention Mechanism

A fixed-size context vector forgets. Attention lets the decoder look back at every input word and weigh them, one output word at a time.

Overview

Quick Context

The encoder–decoder models that came before attention worked like this: an RNN read the whole input sentence and squeezed it into a single fixed-length vector, and a second RNN generated the output from that vector alone.

The flaw is visible as soon as you say it out loud. Every sentence, whether five words or fifty, has to fit in the same number of floats. The encoder's final state is dominated by whatever it read last, and the beginning of a long sentence is simply gone by the time decoding starts. Translation quality fell off a cliff past about twenty words.

Decoding

1
2.00

inverse temperature on the softmax


force one fixed context vector, as seq2seq did before attention


Alignment

Line thickness and opacity are the attention weight. They always sum to 1.

Full Alignment Matrix

This Step

Attending Most To
Its Weight 0.00
Weights Sum 1.000
Focus (entropy) 0.00

Weights

The Attention Mechanism: A Practical Guide

The idea that removed the bottleneck, and then removed recurrence altogether.

The fix

Attention throws away the assumption that the decoder needs one summary. Instead, keep every encoder state, and at each output step let the decoder build a fresh context vector by weighting them:

  1. Score. Compare the decoder's current state against every encoder state. One number per input word — how relevant is this word, right now?
  2. Normalise. Push the scores through softmax so they are positive and sum to 1. These are the attention weights.
  3. Blend. Take the weighted average of the encoder states. That is the context vector for this step, and it is different for every output word.

Nothing is discarded and nothing is compressed. The decoder reaches back into the full input every single time it produces a word.

Why the weights are interpretable

Because they sum to 1 and are all positive, the weights read as a distribution of interest: "to produce this word, I looked 70% at cat and 20% at the". Plotting them for every output word against every input word gives the alignment matrix in the second panel, and on a translation task it recovers word alignment without ever having been told what alignment is.

That interpretability is genuinely useful, but treat it carefully — attention weights show where information was drawn from, which is not quite the same as showing why the model decided what it decided.

Looking at everything at once

A recurrent network reads a sentence one word at a time, carrying a fixed-size hidden state. By word fifty, everything about word one has been compressed into that state, competing with forty-nine other words for room. Long-range dependencies are lost by construction.

Attention removes the bottleneck. Every position looks directly at every other position and decides, per position, how much each one matters.

Concretely, for each word the mechanism computes a weight against every other word, then produces a weighted average of their representations. "It" in "The cat sat on the mat because it was warm" can attend strongly to "mat" — a direct connection, not a signal relayed through five intermediate states.

Two consequences follow immediately, and they are why transformers replaced recurrent networks:

Path length is constant. Any two positions are one step apart, regardless of distance. In an RNN the path is proportional to the gap, and gradients decay along it.

It parallelises. Every position's attention can be computed simultaneously, as one matrix multiplication. An RNN must process position t before t+1, so it cannot use a GPU's parallelism across the sequence.

Queries, keys and values

The mechanism is best read as a soft dictionary lookup.

  • The query is what this position is looking for.
  • The key is what each position offers as a label.
  • The value is what each position actually contributes if selected.

Compare the query against every key to get a score, turn the scores into weights, and take the weighted sum of the values:

Attention(Q, K, V) = softmax(QKᵀ / √dk) V

Reading it left to right: QKᵀ is every query dotted with every key, giving a score matrix. Dividing by √dₖ keeps those scores in a range where softmax is not saturated — without it, large dimensions produce huge dot products, the softmax becomes nearly one-hot, and gradients vanish. The softmax turns scores into weights summing to 1. Multiplying by V produces the output.

All three — Q, K and V — are linear projections of the input, with learned weight matrices. That is the only place parameters enter the mechanism.

A worked example, small enough to follow

Three tokens, and suppose token 2's query produces these dot products against the three keys: 4.0, 1.0, 2.0. Divide by √dₖ = 2: 2.0, 0.5, 1.0.

Softmax: e² = 7.39, e⁰·⁵ = 1.65, e¹ = 2.72; total 11.76. Weights: 0.63, 0.14, 0.23.

The output for token 2 is 0.63 × value₁ + 0.14 × value₂ + 0.23 × value₃ — mostly the first token's contribution, with some of the third.

Those weights are what get visualised as attention heatmaps. They are genuinely informative about what the model connected to what, and they are not an explanation of why — a caution worth keeping, since attention maps are frequently over-interpreted.

The bottleneck it was invented to remove

Attention was not invented for transformers. It was a patch on sequence-to-sequence translation, and understanding the problem it patched makes the mechanism obvious rather than arbitrary.

example_01.pyNumPy
Output

Things to try

  1. Walk the output. Set the Output Step slider to 1, then step it up one at a time. The bright connection moves across the source sentence as each output word is produced — the decoder is looking somewhere different every time.
  2. See the bottleneck it replaced. Tick Bottleneck Mode. Now every output step gets the same flat average of the input, exactly as a fixed context vector would give it. The weights stop moving, focus collapses, and the model has nothing left to distinguish one step from another.
  3. Sharpen the focus. Set the Sharpness slider to 4. The weights concentrate almost entirely on one source word and the entropy readout falls toward zero — this is a hard alignment.
  4. Blur it. Set the Sharpness slider to 0.2. The weights spread almost evenly and entropy rises toward its maximum. The context vector becomes a bland average, which is the bottleneck failure again, arrived at from a different direction.
  5. Watch the whole matrix. Look at the second panel while you change sharpness. The bright diagonal-ish band is the alignment the model has learned; blurring smears it into a uniform grey.

Scoring functions

Step 1 needs a way to compare two vectors. Two became standard:

  • Additive (Bahdanau, 2014): push both vectors through a small feed-forward layer. Flexible, works when the two have different sizes, but adds parameters and is slower.
  • Dot-product (Luong, 2015): just take the dot product. No parameters at all, and it is a matrix multiplication, which is exactly what accelerators are built for.

Dot-product won, and that decision is the reason transformers are fast. Its one wrinkle — that dot products grow with vector size and push softmax into saturation — is fixed by dividing by the square root of the dimension, the "scaled" in scaled dot-product attention.

What came next

Attention was invented as a patch for RNNs, and for three years that is what it was. Then came the observation that gave the paper Attention Is All You Need its title: if the decoder can reach any input position directly, the recurrence is no longer doing anything essential. Remove it, apply attention to the sequence against itself, and you get self-attention — which trains in parallel across all positions instead of stepping through them one at a time.

The next module generalises the three steps above into the query, key and value framing that every transformer is written in.

Where this goes wrong

  • Treating attention weights as explanation. They show where information came from, not why the output was chosen. Different weightings can produce the same prediction.
  • Forgetting the cost. Every output position scores against every input position, so the work grows with the product of the two lengths. On long sequences this quadratic term, not the model size, is what runs out of memory.
  • Expecting clean alignments everywhere. Attention is often diffuse, and heads in a real model frequently attend to punctuation or to the first token for reasons that have nothing to do with meaning.

Summing up

Attention replaces the single fixed context vector with a fresh weighted average of every encoder state, recomputed at each output step: score the decoder state against each input position, softmax the scores into weights that sum to 1, and blend. Because nothing is compressed, long sentences stop degrading, and because the weights are a proper distribution they can be read as an alignment. Dot-product scoring made it fast enough to be worth doing everywhere, and once the decoder could reach any position directly, recurrence turned out to be optional.

Self-attention, cross-attention, and masking

Self-attention has queries, keys and values all derived from the same sequence — a sentence relating its own words to each other. This is what encoder layers do.

Cross-attention takes queries from one sequence and keys and values from another. In translation, the decoder's queries attend to the encoder's representation of the source sentence. In multimodal models, text queries attend to image patches.

Causal (masked) attention prevents a position from seeing anything after it, by setting those scores to negative infinity before the softmax so their weights become zero. This is what makes a decoder able to generate: predicting token t must not depend on token t+1, or the task would be trivial at training time and impossible at inference.

TypeQueries fromKeys/values fromCan see ahead?
Encoder self-attentionThe sequenceThe same sequenceYes
Decoder self-attentionThe sequenceThe same sequenceNo — masked
Cross-attentionThe decoderThe encoderYes

Padding masks serve a different purpose: they zero out the attention paid to padding tokens added for batching. Forgetting them means the model attends to filler as if it were content, which quietly degrades results.

The cost, and what is being done about it

Attention compares every position with every other, so cost grows with the square of the sequence length. Doubling the context quadruples the compute and the memory for the score matrix.

At 512 tokens that is 262,144 pairs — trivial. At 100,000 tokens it is ten billion, which is why long context was the central engineering problem of the last few years.

The main responses:

  • FlashAttention computes exact attention without ever materialising the full score matrix, tiling the computation to fit in fast on-chip memory. Same result, several times faster, far less memory — now standard.
  • Sparse and local attention restrict each position to a window plus a few global positions (Longformer, BigBird).
  • Linear attention approximates the softmax to achieve linear scaling, at some quality cost.
  • Multi-query and grouped-query attention share key and value projections across heads, which mainly reduces the memory needed to cache them during generation.
  • KV caching stores the keys and values of previous tokens during generation so each new token costs one step rather than a full re-computation.

Questions people ask

Why divide by √dₖ? Dot products grow with dimension, and large values saturate the softmax into a near-one-hot distribution with tiny gradients. The scaling keeps them in a workable range.

Is attention the same as a weighted average? The output is one — but the weights are computed from the content itself, which is what makes it adaptive rather than fixed.

Does attention explain the model? It shows which positions were connected. That is not the same as why the prediction was made, and papers have shown attention weights can be altered substantially without changing the output.

How does attention know word order? It does not — the mechanism is permutation-invariant. Positional encodings are added to supply that information.

Why replace RNNs entirely? Constant path length between any two positions, and full parallelism across the sequence. Together those made much larger models trainable.

Can attention be used outside text? Yes — vision transformers attend across image patches, and it is used in graphs, audio and protein models.

Recap in one screen

  • Attention lets every position draw directly from every other, with weights computed from content.
  • Query, key, value: compare the query with all keys, softmax the scores, take the weighted sum of values.
  • Divide by √dₖ or the softmax saturates and gradients vanish.
  • Masking makes generation possible (causal) and batching correct (padding).
  • Cost is quadratic in sequence length, which is what FlashAttention, sparse attention and KV caching address.

Recall check

0 of 3

Say the answer out loud before you reveal it — recalling it is what makes it stick, and rereading it is not.

  1. What does this module say about “Quick Context”?

  2. What does this module say about “The fix”?

  3. What does this module say about “Why the weights are interpretable”?

Cheat sheet

The Attention Mechanism

The encoder–decoder models that came before attention worked like this: an RNN read the whole input sentence and squeezed it into a single fixed-length vector, and a second RNN generated the output from that vector alone.

NLP · vizlearn.in/natural_language_processing/attention_mechanism.html

About the author

Ashish Jangra builds and maintains VizLearn. Every module here is written and the visualisation behind it hand-built, so the numbers in a readout come from the same code that draws the picture. Corrections are genuinely welcome and get priority over everything else — if a page states something wrong, or an animation misrepresents what the algorithm does, get in touch.