Core

Bahdanau attention: the idea that changed everything

Replacing one fixed summary with a learned, differentiable lookup over every stored encoder state removed the bottleneck and the long gradient path at once — and defined the address-and-retrieve pattern every model in this course still runs.

Updated

01 · Concept

Concept

Lesson 3.4 ended with a diagnosis in two parts. One fixed vector cannot hold everything a long source contains, and even if it could, it is computed before the decoder knows which word it is about to produce. Widening it addressed neither. The 2015 answer changes the interface instead of its size, and the change is small enough to state in one sentence: stop throwing the encoder states away.

Let the encoder produce states h1,,hSh_1,\ldots,h_S, one per source position, and keep all of them. Before target step tt, with the decoder holding previous state st1s_{t-1}, a learned scorer produces one energy for every source position:

eti=vtanh(Wsst1+Whhi+b).e_{ti}=v^\top\tanh(W_s s_{t-1}+W_h h_i+b).

Both the decoder’s current need and the source position’s content are projected into a shared space, added, squashed, and scored. Nothing here is a similarity metric chosen in advance; the comparison itself is learned.

A softmax across the source positions turns those energies into weights:

αti=exp(eti)j=1Sexp(etj).\alpha_{ti}=\frac{\exp(e_{ti})}{\sum_{j=1}^{S}\exp(e_{tj})}.

For a fixed target step the weights are non-negative and sum to one, and a mask drives padded source positions to effectively zero. The context vector is then the weighted blend of what was stored:

ct=i=1Sαtihi.c_t=\sum_{i=1}^{S}\alpha_{ti}h_i.

The decoder combines ctc_t with its own state to predict the next token and update itself — and at the next position it computes fresh energies and a fresh context.

Work an example through by hand, because the arithmetic makes the behavior obvious. Take a three-position source and suppose the scorer produces energies e=(2.0,0.5,1.0)e=(2.0,\,0.5,\,-1.0) at some decoder step. Exponentiate: 7.3897.389, 1.6491.649, 0.3680.368, summing to 9.4069.406. Divide: the weights are approximately 0.7860.786, 0.1750.175, and 0.0390.039. So ct0.786h1+0.175h2+0.039h3c_t\approx0.786\,h_1+0.175\,h_2+0.039\,h_3 — this step is reading mostly from source position one, with a glance at position two. Now change one energy: raise the second from 0.50.5 to 2.52.5 and the weights become roughly 0.3710.371, 0.6110.611, 0.0180.018. A difference of two in the exponent moved the majority of the read from one position to another. Softmax is sharply sensitive to energy gaps, which is what lets the mechanism behave like a lookup while remaining perfectly differentiable.

Now count what this bought. The capacity problem is gone, because nothing must be compressed into a single fixed vector and the summary is tailored to the current step. And the credit-assignment problem is gone with it, which is the half people usually forget: source state hih_i now influences a late target loss through one weighted edge. Lesson 3.4 measured that path at roughly eighty-five recurrent transitions for a modest sentence pair, with a retention factor raised to the eighty-fifth power. Attention replaces the product with a single multiplication by αti\alpha_{ti}. Two distinct failures, one mechanism.

Here is the classic wrong turn, and it is the single most common attention bug ever written. You have a matrix of energies with target steps on one axis and source positions on the other, and you apply softmax to it. Along which axis? Normalize across target steps by mistake and the code runs, the shapes are identical, the loss decreases, and the model produces fluent output — because the decoder’s own language modelling can carry a great deal on its own. What you have built is not attention: each source position now distributes a fixed budget of one across the target steps, so a source word that matters to three output words has its influence diluted, and a target step’s weights no longer sum to anything meaningful. The correction is an assertion, not a code review: check that every unmasked row over source positions sums to one within numerical tolerance and that every padded position receives zero. Two lines, and they catch an error that a decreasing loss curve will hide indefinitely.

The full matrix of αti\alpha_{ti} values forms a soft alignment map, and plotting it was a genuine milestone — translation produces roughly diagonal patterns with jumps and spreads where phrases reorder, learned without any word-level alignment supervision. “Soft” means the model may blend positions and gradients flow through every nonzero weight.

One practical note before that. The design keeps the recurrent decoder, so generation is still sequential, and computing energies for every source position at every target step adds real work that grows with the product of the two lengths. That cost was worth paying to remove the bottleneck, and it is the same cost that reappears, magnified, when attention is applied not between two sequences but within one — which is where track 4 begins.

02 · Analogy

Analogy

A simultaneous interpreter keeps a row of source-language note cards on the desk. Before speaking each target word, she compares her current unfinished sentence with every card, puts a weight on each, and reads a weighted blend. Translating a name concentrates weight on its card; producing grammar may spread weight over several. The weights are soft and recomputed at every step. They expose an alignment, but do not prove which card causally determined the final wording.

03 · Teach it back

Teach it back

Derive Bahdanau attention from encoder states and decoder state through energies, weights, and context vector, and explain which two failures of lesson 3.4 it removes.

Minimum: 80 characters and 15 words. Your writing stays only in this browser.

Waiting for your explanation.

Compare with a model answer

The encoder keeps all its states rather than only the last. Before target step t a learned scorer produces one energy per source position from the decoder state and that position's encoder state; a softmax across source positions turns the energies into non-negative weights summing to one; the context vector is the weighted sum of encoder states, recomputed at every step. This removes the capacity failure, since no single fixed vector must hold everything and the summary is tailored to the current step, and it removes the credit-assignment failure, since a source state now reaches a late target loss through one attention edge instead of dozens of recurrent transitions.

04 · Check your understanding

Check your understanding

01Lesson 3.4 identified a gradient path of roughly source-length plus target-length transitions between an early source token and a late target loss. What does attention do to that path?
Answer and explanation

It adds a direct edge, so the source state reaches the loss through a single weighted connection rather than the whole recurrent chain — Removing the long product is why attention helped long sources so dramatically, quite apart from the capacity argument.

02Across which dimension is the softmax applied for one decoder step?
Answer and explanation

Across source positions, so the weights for that one target step sum to one — Normalizing across the wrong axis is the classic implementation bug: it still trains, and it still produces fluent-looking output, while the alignment is meaningless.

03What is the context vector?
Answer and explanation

A weighted sum of the stored encoder states, recomputed for every decoder step — Soft weights make the summary differentiable and let it be tailored to what the current step needs.

Complete the teach-back and answer the quiz correctly to finish this lesson.

◎ · Evidence marker

Sources

  1. Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio (2015). Neural Machine Translation by Jointly Learning to Align and Translate.
  2. Qwen Team (2026). Qwen3.8-27B Model Card.