Sequence-to-Sequence Models
Imagine building a machine translator. The input is an English sentence of arbitrary length. The output is a French sentence of a possibly different arbitrary length. Classic classifiers assign a fixed-size output to a fixed-size input. They cannot naturally handle this mismatch. Sequence-to-sequence (seq2seq) modeling solves exactly this problem. It maps an input sequence to an output sequence. This works without assuming they are the same length or aligned position-by-position. The idea, introduced for neural machine translation, turned out to be far more general. Summarization, speech recognition, question answering, code generation, and dialogue systems all reduce to the same abstract task. Consume a sequence, produce a sequence. Before seq2seq, these problems required hand-built pipelines. These pipelines had separate alignment, translation, and reordering models. A single trainable encoder-decoder network replaced that entire pipeline. It learned everything end-to-end from paired examples. The big picture is deceptively simple. An encoder, typically a recurrent network, reads the input sequence. It compresses the input into a fixed-size vector. This is a "thought vector" or context vector. It is meant to summarize everything relevant about the input. A decoder, another recurrent network, then generates the output sequence one token at a time. It is conditioned on that context vector and on its own previously generated tokens. Training uses paired input-output sequences and standard maximum-likelihood objectives. There is no need for explicit alignment supervision. This article builds the seq2seq framework from first principles. It covers the encoder-decoder split, the mechanics of teacher forcing during training, and the mechanics of autoregressive decoding at inference. It also covers the classic bottleneck that this architecture exposes. The resolution of this bottleneck motivates the Attention Mechanism in NLP and modern The Encoder-Decoder Architecture designs. We build on Recurrent Models for NLP. We assume familiarity with RNNs, hidden states, and backpropagation through time.
- Seq2seq maps variable-length input sequences to variable-length output sequences using two coupled networks.
- The encoder reads the whole input and compresses it into a single fixed-size context vector.
- The decoder generates output tokens one at a time, conditioned on the context vector and prior outputs.
- Training uses teacher forcing (feeding true previous tokens) and cross-entropy loss over the vocabulary at each step.
- Inference uses greedy or beam search decoding since the true previous tokens are unavailable.
- The fixed-size bottleneck limits performance on long sequences, motivating attention mechanisms.
Seq2seq models decouple input length from output length by compressing the input into a fixed-size vector that a separate decoder network unrolls into the output sequence, one token at a time.
The idea
A sequence-to-sequence model learns a conditional distribution over output sequences given input sequences , where and need not be equal and need not correspond position-by-position. This distinguishes seq2seq from sequence labeling tasks (like part-of-speech tagging), where each input token gets exactly one aligned output label. The architecture that realizes this is the encoder-decoder pair. The encoder is a recurrent network (originally an LSTM or GRU) that processes the input tokens one at a time, updating a hidden state at each step. After consuming the last input token, the encoder's final hidden state — the context vector — is taken as a compressed summary of the entire input sequence. Crucially, has a fixed dimensionality regardless of : a 50-word sentence and a 5-word sentence are both squeezed into the same size vector. The decoder is a separate recurrent network that generates the output sequence autoregressively: it predicts conditioned on , then predicts conditioned on and , and so on, until it emits a special end-of-sequence token. Formally, the decoder factors the joint output distribution using the chain rule:
Each factor is computed by a softmax over the vocabulary, taking as input the decoder's current hidden state, which itself depends on the previous output token and the running decoder state initialized from . This factorization is exact by the chain rule of probability — no independence assumption is smuggled in, since each term conditions on all previous outputs. The key architectural commitment of the vanilla seq2seq model is that all information the decoder ever receives about the input must pass through the single vector . This is both the elegance and the weakness of the design, discussed under complexity and pitfalls below.
How it works
Training phase. Given a paired dataset of sequences, the encoder processes to produce . The decoder is then run in teacher-forcing mode: at each decoding step , instead of feeding back its own (possibly wrong) prediction from step , it is fed the true token from the training pair. This stabilizes training because errors do not compound — the decoder always sees a "clean" history — and it allows the whole sequence to be processed as one parallelizable forward pass with a single backward pass for gradient computation (backpropagation through time, across both networks). The loss is the sum (or average) of per-token cross-entropy losses:
summed over training pairs and minimized by gradient descent, exactly as in standard Recurrent Models for NLP language modeling, but now conditioned on an external context vector .
Inference phase. At test time, the true output sequence is unknown, so teacher forcing is impossible. Decoding proceeds autoregressively: generate a token, feed it back as input to generate the next token, and repeat until an end-of-sequence marker is produced or a maximum length is reached. Two common strategies:
- Greedy decoding: at each step, pick the single highest-probability token. Fast, decoder calls, but can commit to locally optimal but globally suboptimal choices.
- Beam search: maintain the highest-scoring partial sequences ("beams") at each step, expanding each by all vocabulary tokens and pruning back to the top . This better approximates the sequence with highest total log-probability, at the computational cost.
``` function TRAIN_SEQ2SEQ(dataset, encoder, decoder, epochs, learning_rate): for epoch in 1..epochs: for (x, y) in dataset: # x = x_1..x_n, y = y_1..y_m
# ---- Encode ---- h = encoder.init_hidden() for t in 1..n: h = encoder.step(x[t], h) c = h # final hidden state = context vector
# ---- Decode with teacher forcing ---- h_dec = c loss = 0 prev_token = START_TOKEN for t in 1..m: logits, h_dec = decoder.step(prev_token, h_dec) probs = softmax(logits) loss += -log(probs[y[t]]) prev_token = y[t] # feed TRUE token, not prediction gradients = backprop(loss, encoder.params + decoder.params) update(encoder.params, decoder.params, gradients, learning_rate) function GREEDY_DECODE(x, encoder, decoder, max_len): h = encoder.init_hidden() for t in 1..length(x): h = encoder.step(x[t], h) c = h h_dec = c output = [] prev_token = START_TOKEN for t in 1..max_len: logits, h_dec = decoder.step(prev_token, h_dec) prev_token = argmax(softmax(logits)) if prev_token == END_TOKEN: break output.append(prev_token) return output function BEAM_SEARCH_DECODE(x, encoder, decoder, max_len, k): h = encoder.init_hidden() for t in 1..length(x): h = encoder.step(x[t], h) c = h beams = [ (score=0.0, tokens=[START_TOKEN], hidden=c) ] completed = [] for t in 1..max_len: candidates = [] for (score, tokens, h_dec) in beams: if tokens[-1] == END_TOKEN: completed.append((score, tokens, h_dec)) continue logits, h_new = decoder.step(tokens[-1], h_dec) logp = log_softmax(logits) for token in vocabulary: candidates.append((score + logp[token], tokens + [token], h_new)) beams = top_k(candidates, k) # keep k highest-scoring partials if all beams end in END_TOKEN: break completed.extend(beams) return argmax_by_score(completed) # or length-normalized score ```
Complexity & correctness
Time complexity. Let be input length, output length, hidden dimension, and vocabulary size. Encoding is time (each RNN step costs for the matrix multiplications inside the recurrence). Decoding during training (teacher forcing) is , where the term is the cost of the output softmax at each step. Both phases are linear in sequence length, and the two RNNs run sequentially, so total training time per example is . At inference, greedy decoding costs the same . Beam search with beam width multiplies the decoder cost by , giving , since at each of the steps we expand beams and score continuations for each.
Space complexity. Storing hidden states for backpropagation through time requires space for a single example (one hidden vector per timestep must be retained for the backward pass), plus for the model parameters themselves, independent of sequence length. Beam search adds space to track hypotheses' hidden states.
Why teacher forcing is correct as a training procedure. The maximum-likelihood objective factorizes exactly via the chain rule shown above — this is not an approximation, it is an algebraic identity for any joint distribution over a sequence. Teacher forcing implements maximum likelihood by plugging in the ground-truth prefix at every step, so the gradient of the loss with respect to parameters exactly matches the gradient of the true log-likelihood objective evaluated on the training pair. The mismatch this introduces is only at inference time: the model is trained conditioned on true prefixes but must generate conditioned on its own (possibly imperfect) prefixes, an issue known as exposure bias. This does not make training incorrect — it correctly optimizes likelihood under teacher forcing — but it does mean training loss is not a perfectly faithful proxy for generation quality, a known and studied gap.
Why greedy/beam decoding is a reasonable approximation. Exact inference would require computing
which is intractable to search exhaustively (exponential in , since the number of possible sequences is ). Beam search is a bounded-width approximate dynamic-programming-style search: because the RNN decoder's state is not Markovian over a small fixed window (it depends on the whole generated prefix), true dynamic programming with polynomial states is not directly available, so we resort to keeping only the best partial hypotheses at each depth — a standard heuristic that provably contains the greedy solution as the special case , and that empirically improves log-likelihood of the returned sequence monotonically in up to diminishing returns.
The bottleneck problem — an honest tradeoff. The context vector has fixed dimensionality , independent of . As grows, must represent proportionally more information in the same number of dimensions, so information loss becomes unavoidable for long inputs. Empirically, translation quality (measured by BLEU score) degrades sharply for sentences beyond roughly 20–30 tokens in the original architecture. This is not a bug fixable by better optimization; it is a structural property of forcing all input information through one vector, and it is precisely the limitation that the Attention Mechanism in NLP is designed to remove by letting the decoder access all encoder hidden states, not just the last one.
Worked example
Consider a toy translation task: English "the cat sat" → French "le chat assis" (a simplified gloss, ignoring real French grammar, for pedagogical tracing). Vocabulary indices: `the=1, cat=2, sat=3, =0` (input side); `le=1, chat=2, assis=3, =0` (output side). Hidden dimension for hand-traceability.
Encoding pass (illustrative hidden-state values, not from a real trained model):
| step | input token | hidden state |
|---|---|---|
| 1 | the | |
| 2 | cat | |
| 3 | sat |
Context vector . Note: tokens 1 and 2 ("the", "cat") no longer exist as separate accessible states for the decoder — only their residue inside remains.
Decoding pass with teacher forcing (training):
| step | decoder input | true target | logits (toy) | predicted probs (softmax, rounded) | loss term |
|---|---|---|---|---|---|
| 1 | START | le | |||
| 2 | le (true) | chat | |||
| 3 | chat (true) | assis | |||
| 4 | assis (true) | EOS |
Total sequence loss , backpropagated through both decoder and encoder.
Decoding pass at inference (greedy, no teacher forcing): suppose the decoder's step-1 prediction were wrong — say it predicted "chat" instead of "le" (probability mass slightly favoring the wrong token due to an undertrained model). Because there is no ground truth to correct it, step 2 now conditions on the wrong token "chat" as if it were the first output word, and the error can propagate through the rest of the sequence. This is exposure bias made concrete: the training procedure never showed the decoder what to do after its own mistake, only after the correct prefix.
Beam search trace (k=2) for the same first step: keep the top two candidates "le" (score ) and "chat" (score ). Expanding both one more step and re-pruning to the top 2 by cumulative score is what lets beam search recover from a locally tempting but globally wrong first guess, something greedy (k=1) cannot do.
Common pitfalls & traps
| Pitfall | Why it happens | Consequence |
|---|---|---|
| Treating as unlimited-capacity memory | Assuming the RNN hidden state scales with input length | Severe quality drop on long sequences (the bottleneck) |
| Forgetting teacher forcing at train time only | Confusing training-time and inference-time decoder inputs | Model trained on ground truth but evaluated with self-generated (buggy) prefixes — train/inference mismatch |
| Using greedy decoding and expecting optimal output | Greedy is a local, per-step argmax, not a global search | Locally plausible but globally poor translations; repetition loops |
| No `` token or unbounded decoding loop | Missing stopping criterion in the decoder loop | Infinite or excessively long generation at inference |
| Reversing/ignoring input order without justification | Some implementations reverse the source sentence to shorten dependency paths to recent decoder-relevant words | Silent quality differences between "reversed" and "forward" encoder variants if not controlled for |
| Ignoring exposure bias when reporting training loss | Loss computed only under teacher forcing | Training loss can look excellent while generation quality is mediocre |
Pioneers & history
The encoder-decoder framework for sequences was crystallized by researchers extending recurrent language modeling to conditional generation, most prominently in the neural machine translation literature of the early 2010s, building on decades of work on recurrent networks and sequence learning.
Origins · 1 minIlya Sutskever and how this was discovered
Where this matters
Seq2seq established the template underlying essentially all modern text generation systems, even after the underlying encoder and decoder were reengineered from RNNs to Transformers. Neural machine translation systems in production (used in large-scale translation services) are seq2seq models at their core, conditioning an output-language decoder on a source-language encoding. Automatic speech recognition systems frame "audio in, transcript out" as sequence-to-sequence, with the encoder consuming acoustic features and the decoder producing text tokens. Text summarization, image captioning (encoder over image features, decoder over words), and code-generation assistants all reuse the same encode-then-autoregressively-decode template. Even the largest modern language models, though architecturally Transformer-based rather than recurrent, inherit the autoregressive decoding discipline pioneered in the seq2seq framework: generate one token at a time, conditioned on everything generated so far. Studying seq2seq is therefore the natural bridge from Recurrent Models for NLP to the attention-augmented and fully attention-based architectures — The Encoder-Decoder Architecture and the Attention Mechanism in NLP — that dominate contemporary NLP.
Ask the tutor: How does the attention mechanism modify the encoder-decoder pipeline to remove the fixed-size bottleneck?
Do seq2seq models require the input and output sequences to have the same length?
No — that is precisely the problem seq2seq solves. The encoder consumes the entire input sequence, of length , and compresses it into a fixed-size context vector regardless of . The decoder then generates an output sequence of length , stopping only when it emits an end-of-sequence token, with no constraint that equal . This is what makes seq2seq suitable for machine translation, where source and target sentences routinely differ in word count and word order, unlike sequence-labeling tasks that require one output per input token.
What is the difference between the encoder RNN and the decoder RNN?
The encoder RNN reads the input sequence and updates its hidden state at each step without producing any output token; its job ends by handing off a final hidden state (the context vector) to the decoder. The decoder RNN, initialized from that context vector, produces one output token per step and feeds each generated (or, during training, ground-truth) token back in as the next input. They are typically separate networks with separate parameters, though some implementations tie certain weights, such as embedding matrices, between the two.
Why can't we just use one long RNN instead of splitting into encoder and decoder?
A single RNN reading input and immediately emitting output token-by-token would force strict positional alignment between input and output positions, which fails whenever sentences reorder words (as translation frequently does) or have different lengths. Splitting into encoder and decoder decouples "understanding the whole input" from "generating the whole output," letting the model first build a complete summary before committing to any output decisions, and letting output length vary independently of input length.
What loss function trains a seq2seq model, and why is cross-entropy the natural choice?
Cross-entropy loss on the decoder's per-step softmax output is standard, summed across all output timesteps. This is the natural choice because the model defines a probability distribution over the next token at each step, and cross-entropy is exactly the negative log-likelihood of the true token under that distribution. Minimizing summed cross-entropy over a training set is equivalent to maximum likelihood estimation of the sequence model's parameters, which is the standard, statistically well-justified training objective for any autoregressive generative model.
Is beam search guaranteed to find the highest-probability output sequence?
No. Beam search is a heuristic approximate search, not an exact algorithm; it can miss the true highest-probability sequence because pruning to the top partial hypotheses at each step can discard a partial sequence that would have led to the global optimum, even though it looked suboptimal early on. Larger beam widths reduce this risk (and recover exhaustive search as ) at proportionally higher computational cost, and empirically returns diminish quickly, with very large beams sometimes even hurting quality due to length or repetition artifacts.
How does the vanilla seq2seq bottleneck get fixed in practice?
The dominant fix is attention: instead of forcing the decoder to rely solely on the final encoder hidden state, attention lets the decoder compute, at every output step, a weighted combination of all encoder hidden states, with weights learned to focus on the most relevant input positions for that output step. This removes the fixed-size information bottleneck entirely, since the "memory" available to the decoder now scales with input length rather than being squeezed into one vector. This idea is developed fully under the Attention Mechanism in NLP and is a core ingredient of The Encoder-Decoder Architecture used in modern Transformer-based systems.
Are seq2seq models with RNNs still used today, or have they been replaced?
Pure RNN-based seq2seq models have largely been superseded in large-scale production systems by Transformer-based encoder-decoder or decoder-only architectures, which parallelize training far better and handle long-range dependencies more effectively via self-attention. However, the conceptual framework — an encoder producing a representation, a decoder autoregressively generating output conditioned on it — persists essentially unchanged in Transformer seq2seq systems, and understanding the RNN version remains the clearest way to learn the core ideas before tackling attention and Transformers.