神经机器翻译(NMT)是理解整个现代序列建模的最佳切口——因为 Transformer 这个统治了今天所有大模型的架构,最初就是为机器翻译设计的。这篇文章顺着"seq2seq → 注意力 → Transformer"这条主线,把每一步到底解决了上一步什么瓶颈讲清楚。

起点:seq2seq 的编码-解码

翻译的本质是把一个变长序列映射成另一个变长序列,且长度不对齐、词序可能颠倒。最早的神经方案是 encoder-decoder:

用一个 RNN(通常是 LSTM/GRU)逐词读入源句,把整句压缩成一个固定长度的上下文向量 cc;再用另一个 RNN 以 cc 为初始状态,逐词生成目标句。生成是自回归的——每一步的输出依赖前面已生成的词:

P(yx)=t=1TP(yty<t,c)P(y \mid x) = \prod_{t=1}^{T} P(y_t \mid y_{<t}, c)

这个框架优雅,但有个致命瓶颈:整句信息被强行塞进一个固定维度的向量 cc。句子越长,这个瓶颈越窄,远处的信息在编码时就被稀释甚至遗忘。直觉上,让模型只看一眼源句的"摘要"就翻译一整段,显然不合理。

转折:注意力机制

注意力的想法朴素得惊人:解码每一个词时,让模型回头去看源句的所有位置,并按需加权,而不是只依赖一个压缩向量。

具体地,编码器保留每个源词的隐状态 {h1,...,hn}\{h_1,...,h_n\}(不再压成一个)。解码第 tt 步时,用当前解码状态 sts_t 去和每个 hih_i 算一个相关性打分 etie_{ti},softmax 成权重,加权求和得到这一步专属的上下文 ctc_t

αti=exp(eti)jexp(etj),ct=iαtihi\alpha_{ti} = \frac{\exp(e_{ti})}{\sum_j \exp(e_{tj})}, \qquad c_t = \sum_i \alpha_{ti}\, h_i

这一步的意义被严重低估:它不仅解决了长句瓶颈,还天然学出了软对齐——翻译某个目标词时,注意力权重会自动集中到对应的源词上,哪怕语序颠倒。这为后来 Transformer 把注意力推到极致埋下了伏笔。

但此时序列处理仍由 RNN 承担,而 RNN 有个无法回避的硬伤:时间步必须串行hth_t 依赖 ht1h_{t-1},没法并行,长序列训练慢,且长距离依赖要走很多步才能传过去,梯度容易衰减。

飞跃:Transformer——只要注意力

Transformer 做了一个激进决定:彻底扔掉 RNN,整个模型只用注意力和前馈网络。 既然注意力能让任意两个位置直接交互,何必还逐步传递?

自注意力的数学

核心是缩放点积注意力。把每个 token 的表示线性投影成 query、key、value 三组向量,打包成矩阵 Q,K,VQ, K, V

Attention(Q,K,V)=softmax(QKdk)V\text{Attention}(Q,K,V) = \text{softmax}\!\left(\frac{QK^\top}{\sqrt{d_k}}\right) V

QKQK^\top 是每个位置对每个位置的相关性矩阵,softmax 归一化后去加权 VV。除以 dk\sqrt{d_k} 是为了防止维度高时点积数值过大、把 softmax 推进饱和区导致梯度消失——这个看似不起眼的缩放,缺了训练就不稳。

关键收益:任意两个位置的交互都是一步直达,路径长度 O(1)O(1)(对比 RNN 的 O(n)O(n)),而且整个序列的注意力可以一次矩阵乘法并行算完。代价是计算和显存复杂度是 O(n2d)O(n^2 d)——序列长度的平方,这正是后来长上下文优化的主战场。

多头与位置编码

单一注意力只能表达一种"关注模式"。多头注意力Q,K,VQ,K,V 切成 hh 份,在各自的子空间并行做注意力再拼接,让模型同时关注语法、语义、共指等不同关系。

但注意力本身是置换不变的——打乱输入顺序,输出只是跟着换位置,模型分不出"猫追狗"和"狗追猫"。所以必须显式注入位置信息:位置编码(早期用固定的正弦函数,后来多用可学习或旋转位置编码 RoPE 等),把"第几个位置"编码进表示里。这是 Transformer 一个容易被忽略却不可或缺的部件。

训练与推理的不对称

1
2
3
4
5
6
7
8
9
10
训练(teacher forcing,可并行):
解码端一次喂入整个目标句(右移一位)
用因果掩码(causal mask)屏蔽未来 token,保证第 t 步看不到 t 之后
一次前向算出所有位置的 loss —— 全并行

推理(自回归,必须串行):
for t in 1..T:
基于已生成的 y_<t 预测 y_t
把 y_t 接回去,继续
(可缓存历史 key/value,即 KV cache,避免重复计算)

这是个常见踩坑:训练能并行是因为目标句已知、可用因果掩码一次算完;推理却只能一个词一个词吐,因为下一个词依赖上一个的真实输出。训练快、推理慢的根源就在这里,也是 KV cache 等推理优化的由来。

工程权衡与边界

  1. 子词切分。词表不可能覆盖所有词,更不可能覆盖所有语言形态。现代 NMT 普遍用 BPE / SentencePiece 把词切成子词单元,平衡词表大小与未登录词(OOV)问题。
  2. 解码策略。逐词取概率最大(greedy)容易陷入局部最优;束搜索(beam search)保留 top-kk 路径,质量更好但更慢,且束太大反而可能偏好过短译文,需要长度惩罚。
  3. O(n2)O(n^2) 的代价。自注意力的平方复杂度让长文档翻译昂贵,这是稀疏注意力、线性注意力等长序列方案的动机。
  4. 暴露偏差(exposure bias)。训练时解码端喂的是真实前缀,推理时喂的是模型自己生成的(可能有错)前缀,分布不一致,错误会累积。

小结

从 seq2seq 到 Transformer,是一条目标极其明确的演进:固定上下文向量的瓶颈催生了注意力,RNN 的串行瓶颈催生了纯注意力架构。Transformer 的胜利不在某个 trick,而在它用一个可并行、任意位置一步直达的机制,统一替代了循环结构。理解了它最初解决翻译问题的动机,也就理解了为什么这套架构后来能扩展成今天的大语言模型——因为序列建模的底层难题,是相通的。