Architectures Before Transformers
Encoder-decoder and the fixed-vector bottleneck
The problem attention was invented to solve
The whole point of attention, seen through the problem it was built to kill: every sentence - five words or fifty - forced through one fixed-length vector.
In 2014 the first neural machine translators worked in two moves. An encoder RNN read the source sentence one word at a time and boiled it down to a single fixed-length vector - its final hidden state. A decoder RNN then wrote the translation one word at a time, with nothing to go on but that one vector. It was elegant, it beat the phrase-based systems of its day - and it had a fatal flaw. Every sentence, however long, had to squeeze through the same fixed vector. That funnel is the bottleneck this lesson is about, and removing it is exactly what attention (Lesson 31) was invented to do.
The one-line idea
The encoder-decoder pipeline
Two networks, one handoff. The encoder steps through the source tokens , updating a hidden state each step, . When it reaches the end it stops and keeps only the last state. That final vector - often called the context vector or thought vector - is the entire handoff:
The decoder is a second RNN that starts from and emits target words one at a time, each conditioned on and everything written so far, . It factorises the probability of the whole output sentence as a product of per-word predictions:
Notice that is the only thing carrying the source into every term of that product. During training we use teacher forcing: instead of feeding the decoder its own (possibly wrong) previous guess, we feed the true previous target word . That keeps early mistakes from snowballing while the model is still learning - at inference time it has to fall back on its own outputs.
# ENCODER: read the whole source, keep only the final hidden state.
h = zeros(d) # the "thought vector" - a FIXED size d
for x in source_tokens: # x_1 ... x_n, any length
h = rnn_step(h, embed(x)) # everything must fit inside this one h
context = h # <-- the entire sentence, squeezed into d numbers
# DECODER: write the target, conditioned ONLY on that one vector.
s = context # start from the squeezed summary
y_prev = "<START>"
for t in range(target_len):
s = rnn_step(s, embed(y_prev))
logits = W @ s # a distribution over the vocabulary
guess = argmax(logits)
y_prev = target[t] if training else guess # teacher forcing feeds the TRUE wordThe fixed-vector bottleneck
Here is the crack. The context vector has a fixed size chosen once, at build time. A five-word sentence and a fifty-word sentence both get exactly numbers. But the amount of meaning to carry grows with length, so a long sentence has to overwrite detail to fit - and because the encoder reads left to right, it is the start of the sentence that fades first. Sutskever, Vinyals & Le measured exactly this: translation quality (BLEU) held up on short inputs and slid on long ones. Their now-famous hack - reverse the source words before encoding - shortened the path from the first source words to and bought several points of BLEU. A hack that helps is a bottleneck confirmed.
Drag the slider below to grow the sentence. The fixed vector in the middle never changes size - watch more and more words get forced through its same handful of slots while the reconstruction fidelity meter falls.
6 words squeezed into a fixed 7-slot vector, then re-expanded to 6 outputs. Short enough to fit the 7 slots - the decoder can rebuild it faithfully.
Why a fixed vector must lose information
The aha: delete the funnel
Check yourself
Without attention, a vanilla seq2seq decoder must produce the whole translation from:
Why does a vanilla seq2seq model degrade as the source sentence gets longer?
Recall: what is the single "context vector" in a vanilla seq2seq model, and why does it become a bottleneck on long inputs?
Try to state it, then check.
Lock it in
- A vanilla seq2seq model encodes the whole source into one fixed-length context vector (the encoder's final hidden state), and the decoder writes every output word from that single vector alone.
- The bottleneck: has a fixed size chosen at build time, so a long sentence overflows it and detail is lost - especially the start, which fades first - and no decoder can recover what was never stored.
- Evidence it is real: reversing the source words shortens the path from the first words to and bought several BLEU points. A hack that helps is a bottleneck confirmed.
- Teacher forcing feeds the true previous target word during training so early mistakes do not snowball; at inference the model falls back on its own outputs.
- Attention deletes the funnel: keep all encoder states and let the decoder look back at whichever it needs - no single summary, which turned seq2seq into the Transformer.
Primary source
Ask your teacher