Seq2Seq 与 Bahdanau Attention:一个向量为什么不够¶
2014 年,神经机器翻译出现了两项彼此时间重叠、共同改变条件生成的工作。Sequence to Sequence Learning with Neural Networks 在其 WMT 设置中展示了 LSTM encoder–decoder 可以把变长源序列映射为变长目标序列;Neural Machine Translation by Jointly Learning to Align and Translate 则针对 fixed-vector encoder–decoder 家族追问:为什么整个输入必须被压进一个固定向量?
它们不应被写成严格的“先有 Seq2Seq,后来才有人想到 attention”。Bahdanau 论文首次提交于 2014 年 9 月,与当年的 Seq2Seq 研究并行推进,后发表于 ICLR 2015。
Seq2Seq 建立了条件语言模型¶
encoder LSTM 读取 \(x_{1:T_x}\),把最终 recurrent state 抽象为 context \(c\);对 LSTM 而言它包含 hidden 与 cell state,decoder 由此开始生成:
这是重要的接口统一:翻译不再依赖短语表和独立对齐模块,encoder 与 decoder 通过最大似然端到端训练。原工作还把源句反转,缩短某些对应词之间的最小时间距离,改善优化。
反转是有效技巧,却没有改变信息瓶颈。源句无论多长,都只能通过固定维度 \(c\) 进入 decoder;细节之间还会竞争同一状态容量。
原论文的反转实验给出了这个优化效应的具体尺度:在其设置中,测试 perplexity 从 5.8 降至 4.7,单模型 beam-12 BLEU 从 25.9 提升到 30.6 左右。它支持“缩短部分最小时间滞后有助于训练”,不支持源序列反转是通用语言建模规则;语言对、词序和 encoder 接口改变后,结论需要重新测量。
训练时 decoder 读取真实上一目标词,推理时则读取自己的预测。beam search 只近似寻找高概率序列,还受长度、EOS 和词表影响。固定向量瓶颈与 exposure mismatch 是两类问题:attention 主要改前者,不自动消除后者。
Alignment 变成可微读取¶
Bahdanau attention 保留所有 encoder states \(h_1,\ldots,h_{T_x}\)。decoder 第 \(t\) 步根据上一状态 \(s_{t-1}\) 计算 additive score:
context 从固定 \(c\) 变为每一步不同的 \(c_t\)。模型可在生成目标词时回到最相关的源位置,而不必让最终 encoder state 无损保存一切。soft alignment 没有逐词标签,它由翻译 loss 共同学习。
原模型的 encoder 是双向 RNN,因此 annotation \(h_j\) 已经融合源位置左右上下文;decoder 则在目标时间上递归。于是 \(c_t\) 不是对原 token embedding 的简单加权,而是对上下文化 annotation 的读取。这个差别解释了为什么 attention heatmap 可以看似对齐词语,却不能直接解释每个 feature 的来源。
带 padding mask 的最小 additive attention¶
import torch
from torch import nn
class AdditiveAttention(nn.Module):
def __init__(self, d):
super().__init__()
self.query = nn.Linear(d, d, bias=False)
self.key = nn.Linear(d, d, bias=False)
self.score = nn.Linear(d, 1, bias=False)
def forward(self, state, memory, valid):
energy = self.score(torch.tanh(self.query(state)[:, None] + self.key(memory))).squeeze(-1)
energy = energy.masked_fill(~valid, torch.finfo(energy.dtype).min)
weight = energy.softmax(-1)
return torch.einsum("bt,btd->bd", weight, memory), weight
torch.manual_seed(0)
attn = AdditiveAttention(8)
state = torch.randn(2, 8, requires_grad=True)
memory = torch.randn(2, 5, 8, requires_grad=True)
valid = torch.tensor([[1, 1, 1, 0, 0], [1, 1, 1, 1, 0]], dtype=torch.bool)
context, weight = attn(state, memory, valid)
assert context.shape == (2, 8)
assert torch.allclose(weight.sum(-1), torch.ones(2), atol=1e-6)
assert torch.count_nonzero(weight[~valid]) == 0
context.square().mean().backward()
assert memory.grad is not None and torch.count_nonzero(memory.grad[~valid]) == 0
mask 后的 padding 不获得权重或梯度,固定了可变长度 batch 的关键语义。完整 NMT 还需要双向 encoder、teacher forcing、decoder recurrence、词表投影和 beam search;这些工程不应遮住“按 decoder 状态读取源端记忆”的核心。
还要处理全 padding row:有限最小值经过 softmax 可能产生均匀概率,-inf 则可能产生 NaN。数据管线应保证每个样本至少一个有效 memory position,或在 attention 中显式返回零 context 和 invalid 状态。
Alignment 图能看什么,不能看什么¶
\(\alpha_{tj}\) 可以画成 alignment heatmap,也经常呈现合理的词序对应。但它首先是生成计算中的权重,不是自动可靠的语言学标注或因果解释。多个位置可能共同提供信息,后续层也会重新混合表示;仅凭一张 attention 图不能证明模型为什么作出最终决定。
更合适的用途是诊断:检查 padding 泄漏、生成停滞、长句末端是否被忽略,以及词序变化后权重是否合理移动。若要把它当作语言学对齐,应与人工对齐和替代性干预共同验证。
从一次 cross-read 到每层 self-read¶
Bahdanau attention 已经包含 query、memory 与 weighted read 的核心。Transformer 做了三次推广:
- 用点积投影替代 additive scoring 的主要形式;
- 让序列内部也通过 self-attention 互相读取;
- 移除 recurrent encoder/decoder,使训练沿 token 维并行。
代价从“一个固定 context”转移为位置表示、平方关系和自回归 KV 状态。Attention Is All You Need 深读解释这次转折,从固定向量到内容寻址则把前后脉络放在同一条线上。
这组工作的证据边界¶
Seq2Seq 在当时的机器翻译设置中展示了大规模 LSTM encoder–decoder 的端到端可行性;Bahdanau attention 在其设置中展示了动态软对齐对 fixed-length bottleneck 与长句翻译的改善。它们没有证明:
- 最终状态对所有短序列都无用;
- attention 权重等同人类对齐;
- recurrence 从此没有价值;
- 后来的 scaled dot-product attention 与 additive attention 在所有条件下等价。
有限状态的前序见 LSTM,现代 cross-attention 在多模态和生成中的迁移见冻结模型之间怎样架桥与 RAG,实现层的 mask 细节见张量原语。