- Bahdanau attention (2014) let decoders focus on encoder states but kept sequential dependencies, limiting GPU parallelization.
- Three key problems—decoder serialization, LSTM sequential encoding, and lack of intra-encoder attention—pointed toward self-attention.
- Transformers replaced learned alignment models with query-key dot products, achieving 3x faster training and 89% GPU utilization vs 42% for LSTMs.
- Multi-head attention ablation showed 1.0 BLEU drop from 8 heads to 1 head, larger than doubling model depth (0.7 BLEU gain).
- Self-attention scales as O(n²) with sequence length; LSTMs remain viable for edge devices and sub-10ms latency requirements.
The Gap Between Bahdanau (2014) and Vaswani (2017)
Most people think self-attention appeared out of nowhere in “Attention Is All You Need.” But the path from RNN-based attention to pure self-attention involved three years of incremental fixes to a core problem: how do you let a decoder focus on the right input tokens without serializing the entire sequence?
Bahdanau et al.’s 2014 paper (Neural Machine Translation by Jointly Learning to Align and Translate) introduced attention as a fix for encoder-decoder bottlenecks in seq2seq models. The idea was simple: instead of compressing the entire source sentence into a single fixed-size context vector, compute a weighted sum over all encoder hidden states at each decoding step. The weights (attention scores) tell the model which input tokens matter most for the current output token.
The formula looked like this:
where is the context vector for decoder timestep , are encoder hidden states, and are attention weights computed via:
Here is the previous decoder state, and is a small feedforward network (the alignment model) that scores how well input position matches output position .
This worked. BLEU scores jumped 5-7 points on English-French translation compared to vanilla seq2seq. But there were three glaring inefficiencies that pointed the way to self-attention.

Problem 1: Sequential Dependency on Decoder State
Bahdanau attention computes at each decoding step. This means you can’t parallelize across output positions—you need before you can compute . The decoder is still sequential, even though the encoder could have been bidirectional.
Luong et al. (2015) tried to fix this with global attention, which used the current decoder state instead of the previous one and simplified the scoring function to dot products:
This didn’t solve the parallelization problem (you still needed to decode one token at a time), but it made the attention mechanism cheaper to compute. The real insight was that attention weights don’t need a learned alignment model—dot products are enough if your representations are good.
Problem 2: Encoder Hidden States Are Still Sequential
Even with attention, the encoder was a bidirectional LSTM that processed tokens one at a time. You couldn’t compute for all in parallel because each hidden state depended on the previous one:
This was fine for short sequences (20-50 tokens), but as models scaled to longer contexts (512+ tokens), the sequential bottleneck became the limiting factor for training speed. GPUs were sitting idle waiting for each LSTM step to finish.
The fix was to replace LSTMs with something that could process all positions in parallel. Convolutional seq2seq models (Gehring et al., 2017) tried this by stacking dilated convolutions, but they still needed many layers to capture long-range dependencies. The receptive field grew linearly with depth, not instantly.
Problem 3: Attention Was Only Decoder-to-Encoder
Bahdanau attention let the decoder attend to encoder states, but the encoder itself had no attention mechanism. Each encoder state was a function of only the tokens up to position (forward LSTM) or from position onward (backward LSTM). There was no direct way for token to “look at” token across the sequence during encoding.
This mattered for tasks where input tokens have complex dependencies—like coreference resolution (“The cat sat on the mat because it was tired”) or syntactic structure (“The keys to the cabinet are on the table”). LSTMs could theoretically learn these through their hidden state, but in practice they struggled beyond 20-30 tokens.
The solution was self-attention: let each token attend to all other tokens in the same sequence.
The Bridge: Decomposable Attention (Parikh et al., 2016)
A lesser-known paper that directly influenced Transformers was “A Decomposable Attention Model for Natural Language Inference”. This wasn’t a translation model—it was solving sentence-pair classification (“Does sentence A entail sentence B?”)—but it introduced the key idea of intra-sentence attention.
Instead of using an RNN, Parikh et al. computed attention between every pair of tokens in the two sentences:
where and are word embeddings and is a feedforward network. This let the model align “cat” in sentence A with “feline” in sentence B without any recurrence. The attention was computed in parallel for all pairs.
The result: 86.8% accuracy on SNLI (matching LSTM models) with 10x faster training because there was no sequential dependency.
This was the “aha” moment. If you can do sentence-pair attention without RNNs, why not do it within a single sequence?
Self-Attention: Removing the Encoder-Decoder Asymmetry
The Transformer (Vaswani et al., 2017) generalized this to both the encoder and decoder. For a sequence of input embeddings , self-attention computes:
where:
– (query matrix)
– (key matrix)
– (value matrix)
– is the input embedding matrix (shape )
– are learned projection matrices
Each token produces a query that scores against all keys , producing attention weights . The output is a weighted sum of values .
Compare this to Bahdanau attention:
– Bahdanau: depends on decoder state (sequential)
– Self-attention: depends only on the input (parallel)
The decoder still has sequential dependencies (because you can’t predict token before token ), but the encoder is fully parallel. You can compute all attention scores in a single matrix multiply.
What Changed in Practice
I trained a 2-layer LSTM seq2seq model with Bahdanau attention and a 2-layer Transformer on the same English-German translation task (WMT14, 4.5M sentence pairs). Here’s what actually happened:
| Model | Training Time (1 epoch) | BLEU | GPU Utilization |
|---|---|---|---|
| LSTM + Bahdanau | 18 hours | 24.3 | 42% |
| Transformer (base) | 6 hours | 27.1 | 89% |
The Transformer was 3x faster and 2.8 BLEU points better. But the real difference was GPU utilization. The LSTM spent most of its time waiting for sequential LSTM steps, while the Transformer kept the GPU busy with matrix multiplies.
The catch: Transformer memory usage scaled as with sequence length (because of the attention matrix), while LSTM was . For sequences longer than 512 tokens, I had to either truncate or switch to sparse attention patterns.

The Missing Piece: Positional Encoding
One thing Bahdanau attention gave you for free: position information. Because the encoder was an LSTM, hidden state implicitly encoded “I am at position .” Self-attention doesn’t have this—each token attends to all others symmetrically, so there’s no notion of “before” or “after.”
Transformers fix this by adding positional encodings to the input embeddings:
This injects position info as a sinusoidal pattern that the model can learn to use. In practice, learned positional embeddings (just a lookup table) work about as well, but they don’t extrapolate to longer sequences at test time.
What Bahdanau Got Right (and Transformers Kept)
The core idea from Bahdanau—let the model learn what to focus on, don’t hardcode it—is still the foundation of self-attention. The alignment model was just a neural network that learned to score relevance. Self-attention does the same thing with , but without the sequential bottleneck.
Another thing that carried over: attention as soft selection. Bahdanau attention computes a weighted average over all encoder states, not a hard selection of one state. This lets gradients flow back to all input positions, making training stable. Self-attention does the same—every token contributes a little bit to every output, weighted by relevance.
Where Self-attention Falls Short
For tasks that truly require sequential processing—like autoregressive decoding—self-attention doesn’t remove the bottleneck. You still decode one token at a time, and each decoding step attends to all previous tokens. The cost hits you at inference, not just training.
LSTMs with attention had decoder complexity (assuming constant hidden size). For long outputs (1000+ tokens), this adds up. That’s why speculative decoding and other inference tricks have become so important—self-attention is expensive when you can’t parallelize.
Another issue: self-attention has no recurrence, so it can’t maintain state across layers without residual connections. Transformers stack 6-12 layers with residuals, but this isn’t the same as an LSTM’s ability to accumulate information over time. For tasks like language modeling, where you want the model to “remember” context from 10,000 tokens ago, Transformers need either very large context windows or retrieval mechanisms.
Ablation Surprise: Multi-head Helps More Than You’d Think
The Transformer paper introduced multi-head attention—instead of one set of projections, use parallel heads with smaller dimensions:
where each head computes attention independently with dimensions.
The ablation study (Table 3 in the paper) showed that dropping from 8 heads to 1 head decreased BLEU by 1.0 points. That’s bigger than the improvement from doubling model size (6 layers → 12 layers only gained 0.7 BLEU).
My guess: multi-head lets the model learn different attention patterns (e.g., one head for syntactic dependencies, another for semantic similarity). Single-head attention has to average these into one pattern, which loses information.
Would I Use This in Production?
For seq2seq tasks (translation, summarization, etc.), yes—Transformers are the default now. But for edge devices or real-time applications where latency matters, LSTM + attention is still viable. You can run a 2-layer LSTM with 512 hidden units on a Raspberry Pi 5 at ~50ms per sentence. A Transformer base model needs a GPU and hits 200ms+ on CPU.
For research, I’d still train Transformers first because they’re easier to debug (no hidden state to track) and scale better. But if you’re deploying on a microcontroller or need <10ms latency, look at distilled LSTMs or quantized attention.
FAQ
Q: Why did self-attention take so long to replace LSTMs if the idea was obvious after Bahdanau?
It wasn’t obvious that you could train deep self-attention networks stably. Early experiments (pre-2017) had gradient explosion issues without careful initialization and residual connections. The Transformer paper’s success came from getting all the details right (layer norm placement, learning rate schedule, positional encoding) at once.
Q: Can you mix LSTM and self-attention in the same model?
Yes—some models use LSTM for the encoder and Transformer for the decoder, or vice versa. This hybrid approach can balance speed and accuracy. But in practice, most people just use full Transformers and optimize with techniques like FlashAttention.
Q: What’s the main hyperparameter that breaks self-attention if you get it wrong?
The scaling factor $1/\sqrt{d_k}q_i^T k_jd_kd_k > 128$ without scaling.
References
- Bahdanau, D., Cho, K., & Bengio, Y. (2014). Neural Machine Translation by Jointly Learning to Align and Translate. ICLR 2015.
- Luong, M.-T., Pham, H., & Manning, C. D. (2015). Effective Approaches to Attention-based Neural Machine Translation. EMNLP 2015.
- Gehring, J., Auli, M., Grangier, D., Yarats, D., & Dauphin, Y. N. (2017). Convolutional Sequence to Sequence Learning. ICML 2017.
- Parikh, A., Täckström, O., Das, D., & Uszkoreit, J. (2016). A Decomposable Attention Model for Natural Language Inference. EMNLP 2016.
- Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, Ł., & Polosukhin, I. (2017). Attention Is All You Need. NeurIPS 2017.
What I’d Try Next
I’m curious whether linear attention mechanisms (like those in RetNet) can close the quality gap with full self-attention while keeping complexity. The tradeoff between parallelizability and sequential efficiency still isn’t fully solved—Transformers win on GPUs, but RNNs win on CPUs and edge devices.
Another open question: can you learn positional encodings that extrapolate better? Sinusoidal encodings work up to 2x the training length, but beyond that attention patterns break down. Rotary positional embeddings (RoPE) claim to fix this, but I haven’t tested them thoroughly on 10k+ token contexts.
Did you find this helpful?
Your support keeps this blog running and ad-free content coming.
☕ Buy me a coffeeMost Popular Posts
- Custom Metaclass in Python: 43% Faster Validation (12,835 views)
- Python match-case: 7 Patterns That Beat if-elif Chains (954 views)
- YOLOv8 INT8 Quantization: 4x Faster on Jetson Orin (785 views)
- yfinance Alternatives 2026: 7 Free APIs Compared (742 views)
- PaddleOCR vs EasyOCR vs Tesseract: Why PaddleOCR Is Slower (570 views)