AI Grimoire
Sheet
statusstale
difficultyintroductory
timeO(n·m·d)
memoryO(n·m)
described2014
revised3d ago

Additive Attention

Bahdanau’s original formulation, in which a small feed-forward network learns the similarity function instead of assuming an inner product.

Standing

StaleLoad-bearing for understanding how the field arrived here, and replaced in practice by something on this list. Worth reading, not worth reaching for.

Displaced entirely by dot-product scoring, and not because it was less expressive — it is more. It lost because a tanh in the middle of the score cannot be folded into a single matrix multiplication, and by 2017 that was the only property that mattered.

judged as of 2026-09 · what the labels mean

Theory

Attention was introduced without a dot product. Bahdanau et al. needed a score for each decoder-state/encoder-state pair and, rather than assuming the two should be compared by inner product, they learned the comparison.

eti=vtanh ⁣(Wsst1+Whhi),αti=exp(eti)jexp(etj)e_{ti} = v^{\top} \tanh\!\left( W_s s_{t-1} + W_h h_i \right), \qquad \alpha_{ti} = \frac{\exp(e_{ti})}{\sum_j \exp(e_{tj})}
eq. 1 — a one-hidden-layer MLP, scoring one pairBahdanau et al. §A.1.2

WsW_s and WhW_h map the two sides into a shared dad_a-dimensional space independently, so the decoder state and the encoder states may have different dimensions — something the dot product cannot do without an extra projection. The tanh and vv then reduce the pair to a scalar.

Why it lost

The nonlinearity sits between the two operands. That single fact is the whole story: it means the n×mn \times m score matrix cannot be written as a product of a QQ matrix and a KK matrix, so it cannot be one GEMM.

E=vtanh(SWsHWh)nm small opsversusE=QKdkone matmul\underbrace{E = v^{\top}\tanh(S W_s^{\top} \oplus H W_h^{\top})}_{n \cdot m \text{ small ops}} \qquad\text{versus}\qquad \underbrace{E = \frac{Q K^{\top}}{\sqrt{d_k}}}_{\text{one matmul}}
eq. 2 — the structural difference

Luong et al. compared the two directly and found the accuracy difference small and inconsistent — dot-product scoring was competitive on their tasks and sometimes better. Given comparable quality and an order-of-magnitude difference in how well the computation maps onto matrix hardware, the outcome was not close.

What it is still good for

Reading the original formulation makes the modern one look like a choice rather than a definition. The three requirements on a scoring function — depends on both sides, normalises to a distribution, differentiable — are satisfied by both, and seeing a second solution is what stops softmax(QK/dk)\softmax(QK^\top/\sqrt{d_k}) feeling like an incantation.

It also still appears in small models where nmn \cdot m is tiny and the extra expressivity is worth more than the GEMM: pointer networks, some retrieval rerankers, and a good deal of pre-2017 code that still works.

Implementation

python · torch ≥ 2.1
import torch
from torch import Tensor, nn


class AdditiveAttention(nn.Module):
    """Bahdanau scoring. d_s and d_h may differ — that is the point."""

    def __init__(self, d_s: int, d_h: int, d_attn: int) -> None:
        super().__init__()
        self.w_s = nn.Linear(d_s, d_attn, bias=False)
        self.w_h = nn.Linear(d_h, d_attn, bias=False)
        self.v = nn.Linear(d_attn, 1, bias=False)

    def forward(self, s: Tensor, h: Tensor, mask: Tensor | None = None) -> Tensor:
        # [B, N, 1, A] + [B, 1, M, A] -> [B, N, M, A]. This tensor is the cost:
        # d_attn times larger than the score matrix it collapses to.
        joint = self.w_s(s).unsqueeze(2) + self.w_h(h).unsqueeze(1)
        scores = self.v(joint.tanh()).squeeze(-1)

        if mask is not None:
            scores = scores.masked_fill(mask, torch.finfo(scores.dtype).min / 2)

        return scores.softmax(dim=-1) @ h

The unsqueeze-and-add broadcast materialises a [B,N,M,A][B, N, M, A] tensor — dad_a times the memory of the score matrix itself. At n=m=4096n = m = 4096 and da=64d_a = 64 that is 4 GB in fp32 for a single head of a single layer, which is the practical reason nobody runs this at transformer scale.

Related

References

[1]Bahdanau et al. — Neural Machine Translation by Jointly Learning to Align and Translate (2014)arXiv:1409.0473
[2]Luong et al. — Effective Approaches to Attention-based Neural Machine Translation (2015)arXiv:1508.04025
[3]Vaswani et al. — Attention Is All You Need (2017)arXiv:1706.03762