RNN, LSTM & GRU: Attempts to Fix Long Context¶
Overview¶
Before attention, the entire field wrestled with one question: how does a model use information from far back in a sequence? Recurrent models (RNN β LSTM β GRU) were a long series of attempts to answer it. Each generation fixed one failure mode β vanishing gradients, memory capacity, direction β but all of them left two fundamental problems unsolved: sequential computation and compressed memory. Attention succeeded precisely where these attempts failed.
Timeline of attempts:
1986 RNN β can in principle, fails in practice (gradients)
1997 LSTM β fixes vanishing gradients with gates
2014 GRU β simpler LSTM, same limits
2014 Bi-RNN β fixes direction (for understanding tasks)
2015 Bahdanau attention β first "look back directly" fix (inside RNN!)
2017 Transformer β removes recurrence entirely β this chapter's subject
- The problem being fixed: Attention Mechanisms β The Problem: Why RNNs Fail at Long Context
- The two unsolved failures: no parallelism + fixed-capacity memory
- Key idea to remember: LSTMs made long-range memory possible; attention made it direct, parallel, and lossless
The Baseline: Plain RNN¶
How it works¶
h_t = tanh(W_x Β· x_t + W_h Β· h_{t-1} + b)
ββββββββββββββββββββββββββββββββββββββ
xβ β [hβ] β xβ β [hβ] β xβ β [hβ] β ... β [h_T]
β β β β
βββ hβ feeds ββββ hβ feeds ββββ ... βββ final h_T = "summary"
Each step: take the new input x_t, mix it with the previous
hidden state h_{t-1}, squash through tanh, pass it on.
The strengths (why recurrence was attractive)¶
β
Variable length: one formula for any sequence length
β
Parameter sharing: same W_x, W_h for every position (few params)
β
Sequential structure: order is built into the computation
β
Cheap: O(T) time, O(1) extra state per step
The fatal weaknesses¶
β Failure 1 β Vanishing (or exploding) gradients:
βL/βW β Ξ _{k} J(h_k) β product of many Jacobians
each step scales the gradient by ~βJβ (often < 1)
10 steps back β Γ0.9ΒΉβ° β 0.35
50 steps back β Γ0.9β΅β° β 0.005
100 steps back β Γ0.9ΒΉβ°β° β 0.00003
The network CANNOT learn long-range dependencies:
the gradient signal is dead before it reaches the distant past.
β Failure 2 β No parallelism:
h_t needs h_{t-1}; h_{t-1} needs h_{t-2}...
T steps = T serial GPU operations (a 1,000-token sentence is
1,000 sequential matmuls β the GPU sits idle between steps)
β Failure 3 β One-vector memory:
everything seen so far must fit in ONE fixed-size vector h_t
β old information gets overwritten by new information
β capacity is the bottleneck even when gradients survive
π‘ Key Insight: RNNs in principle can remember arbitrarily long (they're Turing-complete), but gradient math and fixed-size memory make it impractical. The LSTM was the first serious engineering fix.
Attempt 1: LSTM (1997) β Fix the Vanishing Gradient¶
Long Short-Term Memory (Hochreiter & Schmidhuber, 1997) attacked failure #1 head-on with a gated, additive memory path.
The cell state: a "constant error carousel"¶
The central trick is a separate memory, the cell state C_t, updated by addition instead of multiplication:
Gate formulas (β = element-wise multiply, Ο = sigmoid):
f_t = Ο(W_f Β· [h_{t-1}; x_t] + b_f) forget gate β what to DROP from memory
i_t = Ο(W_i Β· [h_{t-1}; x_t] + b_i) input gate β what to WRITE to memory
CΜ_t = tanh(W_c Β· [h_{t-1}; x_t] + b_c) candidate β proposed new content
C_t = f_t β C_{t-1} + i_t β CΜ_t cell update β additive!
o_t = Ο(W_o Β· [h_{t-1}; x_t] + b_o) output gate β what to REVEAL
h_t = o_t β tanh(C_t) hidden state
βββββββββββββββββββββββββ C_t-1 ββββββββββββββββββββββββββ
β βΌ
x_t ββββΌβββΊ Ο (forget f) ββββββ ββ multiply ββΊ C_t
h_t-1 ββΌβββΊ Ο (input i) βββββββΌβββΊ candidate CΜ βββΊ multiply
ββββΊ tanh (candidate) ββ β² β
ββββΊ Ο (output o) ββββββββββ΄βββΊ tanh βββΊ multiply ββΊ h_t
Why this fixes vanishing gradients¶
Plain RNN path: h_t = tanh(WΒ·[...]) β every step is a tanh multiply
gradient Γ (tanh' β€ 1) each step β decays
LSTM path: C_t = f_t β C_{t-1} + i_t β CΜ_t
gradient flows through C_{t-1} with multiplier β f_t
if f_t β 1 (gate OPEN) β gradient passes ~unchanged
This is the "Constant Error Carousel": the cell can carry a signal
back hundreds of steps because the path is ADDITIVE, not a chain of
squashing functions. Training a 100-step dependency becomes feasible.
Worked gate example (toy numbers)¶
Given: h_{t-1} = 0.2, x_t = 0.8, C_{t-1} = 1.0
Pre-activations (already computed by the weights):
forget: z_f = 0.5 β f = Ο(0.5) = 0.62 (keep 62% of old memory)
input: z_i = 1.0 β i = Ο(1.0) = 0.73 (write 73% of candidate)
candidate: z_c = β0.3 β CΜ = tanh(β0.3) = β0.29
output: z_o = 0.2 β o = Ο(0.2) = 0.55
Cell update:
C_t = fΒ·C_{t-1} + iΒ·CΜ
= 0.62Β·1.0 + 0.73Β·(β0.29)
= 0.62 β 0.21 = 0.41
Hidden state:
h_t = oΒ·tanh(C_t) = 0.55Β·tanh(0.41) = 0.55Β·0.39 β 0.21
Interpretation: the LSTM kept most of its old memory (0.62 factor),
wrote a little negative candidate, and output a bounded view of it.
What LSTMs still couldn't fix¶
β Sequential computation remains: C_t still depends on C_{t-1}
β training is T serial steps (slow, GPU-starved)
β Fixed-capacity memory remains: one cell vector per position;
keeping "cat" for 16 steps means it still shares the cell with
everything else β information is mixed, not addressable
β Long-range is *possible* but *fragile*:
- forget gate is rarely fully open: f β 0.6β0.9 in practice
- old content decays: 0.9ΒΉβΆ β 0.19, 0.8ΒΉβΆ β 0.03 of the signal
- gates are a *learned* trade-off: keeping everything hurts
(the LSTM learns to forget to fit new material)
β No direct "pointer" to a distant token β to use token #5's content
at token #100, it must survive 95 compressions intact
Attempt 2: GRU (2014) β Simplify the LSTM¶
Gated Recurrent Unit (Cho et al., 2014) merged the forget and input gates into one update gate and dropped the separate cell state.
z_t = Ο(W_zΒ·[h_{t-1}; x_t]) update gate (how much to change)
r_t = Ο(W_rΒ·[h_{t-1}; x_t]) reset gate (how much old info to use)
hΜ_t = tanh(W_hΒ·[r_t β h_{t-1}; x_t]) candidate
h_t = (1 β z_t) β h_{t-1} + z_t β hΜ_t blend old and new
2 gates, 3 weight matrices (vs LSTM's 3 gates, 4 matrices)
LSTM: 3 gates (f, i, o) + cell state C β 4 matrices
GRU: 2 gates (z, r), no separate cell β 3 matrices
Same core idea, fewer parameters:
- trains faster, needs less data
- performance β LSTM on most tasks (sometimes better, sometimes worse)
- still sequential, still fixed-memory, still decay-prone
Attempt 3: Bidirectional & Stacked RNNs β Fix Direction and Depth¶
Bidirectional RNNs (Schuster & Paliwal, 1997)¶
Forward pass: hβ β hβ β ... β h_T (left-to-right context)
Backward pass: hβ β hβ β ... β h_T (right-to-left context)
Concatenate: [h_forward; h_backward] (both directions available)
Fixed: understanding tasks benefit from FUTURE context
("bank" needs the word AFTER it to be disambiguated)
Still broken: sequential in both passes (2Γ slower), still compressed
Stacked (deep) RNNs¶
hΒΉ_t β hΒ²_t β hΒ³_t β ... (hierarchical abstractions per layer)
Fixed: more expressive features per position
Worsened: depth multiplies the vanishing-gradient problem;
needs skip-connections/gating to even train deep stacks
Attempt 4: Attention Inside RNNs (Bahdanau, 2015) β the patch that worked¶
The first attention mechanism was not a transformer β it was added to an LSTM encoderβdecoder to fix one specific problem: the decoder had to squeeze the whole source sentence into a single final vector.
The fix: let the decoder "look back" at every encoder state¶
Instead of: context = ONE vector (the last encoder state)
Now: c_t = Ξ£β±Ό Ξ±_tj Β· h_j β weighted sum of ALL encoder states
e_tj = vα΅ tanh(W_aΒ·[s_{t-1}; h_j]) (alignment score)
Ξ±_tj = softmax(e_tj) (attention weight over source)
c_t = Ξ£β±Ό Ξ±_tj Β· h_j (context vector β direct lookup!)
s_t = RNN(s_{t-1}, [y_{t-1}; c_t]) (decoder update)
Decoder generating "The cat":
step 1 ("The") β attends to: "Die"(0.55) "Katze"(0.10) ...
step 2 ("cat") β attends to: "Katze"(0.70) ...
The decoder READS the relevant source words directly β
no 95-step compression survival required.
Why this matters for the story¶
β
This is the exact mechanism this chapter studies β but inside an RNN
β
It proved "direct connection to the past" is the right fix
β The RNN core still serialized everything: attention fixed MEMORY,
not PARALLELISM β T steps were still T serial computations
The Transformer (Vaswani 2017) took the next and final step:
remove the RNN entirely β attention is the ONLY token-to-token
mechanism β everything is parallel.
Attempt 5: The Transformer (2017) β Remove Recurrence¶
Recurrent: h_t = f(h_{t-1}, x_t) (must finish tβ1 first)
Transformer: out = softmax(QΒ·Kα΅/βd)Β·V (all positions at once)
Fixes the two remaining failures in one stroke:
Parallelism: one big matmul, not T serial steps
Memory: every token is addressable at ANY distance with O(1) steps
β "its" reaches "cat" directly, no compression in between
New costs introduced:
O(nΒ²) compute/memory β see [06 Complexity & Cost](/02-llm-modeling/00-fundamentals/01-attention/06-complexity-&-cost/)
position-blind β see [05 Position Information](/02-llm-modeling/00-fundamentals/01-attention/05-position-information/)
The Scoreboard¶
| Attempt | Year | Fixed | Left broken |
|---|---|---|---|
| Plain RNN | 1986 | β | gradients, parallelism, memory capacity |
| LSTM | 1997 | vanishing gradients (gated additive cell) | parallelism, capacity, fragile long-range |
| GRU | 2014 | simpler/faster training | same as LSTM |
| Bi-RNN | 1997/2014 | direction (both contexts) | sequential Γ2, capacity |
| Bahdanau attention | 2015 | last-vector bottleneck (direct lookup) | sequential core remains |
| Transformer | 2017 | parallelism + direct memory | O(nΒ²) cost, position-blind |
The pattern: every recurrent attempt fixed ONE symptom.
Attention was the first fix that addressed the ROOT:
"stop compressing β give every token a direct wire to every other token."
Concrete Failure: The "its" Problem Through an LSTM¶
Sentence: "The cat, which was adopted from the shelter last winter,
finally settled into its new home."
Distance from "cat" to "its" β 16 tokens.
LSTM path:
- "cat" is stored in the cell at position 2
- every step, the forget gate multiplies the cell (f β 0.6β0.9)
- signal remaining after 16 steps: 0.9ΒΉβΆ β 0.19 (best case)
0.8ΒΉβΆ β 0.03 (typical)
- AND the cell also holds "shelter", "winter", "settled", "home"...
β "cat" must survive as one component among many, compressed
Attention path:
- at "its", the query matches the key of "cat" directly
- score β softmax weight β value flows in ONE step
- distance is irrelevant: 16 steps or 16,000, same mechanism
LSTM result: confused pronoun reference (shelter/home steal attention)
Transformer: "its" β "cat" with high weight (see [08 Interpretability](/02-llm-modeling/00-fundamentals/01-attention/08-interpretability/))
Why Attention Ultimately Won (Three Reasons)¶
1. DIRECT ACCESS β every token can read any other token with O(1)
steps; no information has to "survive" compression or decay
2. PARALLELISM β the whole sequence is processed as one matmul;
GPUs (which are massive parallel machines) finally get fed
3. SCALABILITY β training data Γ1000 (the LLM era) is only usable
because transformers train fast enough to exploit it;
LSTMs at GPT-3 scale would take decades of wall-clock time
LSTM/GRU are not obsolete β they still power:
- speech processing, some time-series models
- hybrid architectures, state-space models (Mamba) revisit their ideas
But for text, attention won outright.
Key Takeaways¶
π RNN β LSTM β GRU: a history of patching one failure at a time
π§ LSTM's gift: the gated additive cell (constant error carousel) tamed vanishing gradients
π§ The wall they all hit: sequential computation + fixed-capacity memory
π― Bahdanau (2015): attention was first an RNN patch β "look back directly"
ποΈ Transformer (2017): removed recurrence β parallel + addressable memory
βοΈ Trade-off: attention pays O(nΒ²) for what recurrence gave away for free (order, linear cost)
π§ Not useless today: LSTM ideas live on in Mamba/state-space models and sequence audio models
Related Notes¶
- 00 Attention Mechanisms β the chapter this note motivates
- 01 Query, Key & Value β where the "look back directly" idea matured
- 02 Scaled Dot Product Attention β the modern form of Bahdanau's context vector
- 03 Types Of Attention β why causal masking matters for generation (unlike bidirectional LSTM)
- 06 Complexity & Cost β the O(nΒ²) price attention pays for recurrence's failures
- 08 Interpretability β direct token access shown in attention weights