Linear = Hash 函数——输出层碰撞是翻译的信息瓶颈
512 维 hidden 撞进 32K 维词汇表:碰撞率 K_lang ≈ 0.003,有效碰撞桶 ~170 个。Linear 不是模型最后一步投影——它是翻译信息从连续空间到离散词汇的 Hash 函数。
碰撞在哪里?
NMT 的输出流程三步:
① Transformer: 输入序列 → h_t ∈ ℝ^512 (hidden space)
② Linear: h_t → z = W·h_t + b (logits in ℝ^{32000})
③ Softmax: z → p ∈ Δ^{31999} (概率单纯形)
④ Decode: argmax / beam → token (离散词)
每个人都在关注 ③ 和 ④。但碰撞发生在 ②。
Linear = Hash Function
W 是一个
的矩阵。每一行
$$W_i \in \mathbb{R}^{512}$$是第 i 个 token 的嵌入向量(output embedding)。
$$W·h_t$$做的是内积:
$$z_i = \langle W_i, h_t \rangle + b_i$$把 512 维的 hidden 投影到 32K 维——32K 个内积。
这是 Hash 函数的标准定义: 把高维向量压缩到低维离散空间。
$$h_t \xrightarrow{W} z \xrightarrow{\text{argmax}} \text{token}$$参数 W 决定了 hidden 空间中哪些方向对应哪些 token。512 维的 hidden 无法精确表示 32K 个 token 的语义——碰撞是必然的。
碰撞率 = K_lang
32K 个 token 共享 512 个维度,内积
$$W_i·h_t$$受限于 hidden 的信息容量。有意义地区分的 token 数:
$$N_{\text{collision}} = K_{\text{lang}} \times |V| = 0.003 \times 32000 \approx 96$$BPE 词表下(8K):
$$N_{\text{collision}} = 0.003 \times 8000 \approx 24$$碰撞桶从 170 缩到 24——但每个桶承担的语义负载叠加了 7 倍。
| 词表类型 | |V| | K_lang×|V| | 每桶语义负载 |
|---|---|---|---|
| Word-level (IWSLT) | 56K | 170 | 轻 |
| BPE (IWSLT) | 8K | 24 | 重 |
IWSLT14 的 BPE 实验证实:8K 词表下,3 个 transformer 层不够深(B0, BLEU=10.66),但 6 层可以(B3, BLEU=11.70)。深度补偿了桶压缩。
梯度怎么从碰撞桶里提取信息?
CE loss 对
$$z_i$$的梯度是
$$p_i - y_i$$。对
$$W_i$$的梯度是:
$$\frac{\partial \mathcal{L}}{\partial W_i} = (p_i - y_i) \cdot h_t$$每个 token 的梯度向量与
$$h_t$$平行。梯度只沿 hidden 方向更新,而 hidden 本身是高维压缩——所有 32K 个 token 的梯度都投影到同一个 512 维空间上,再分配回各自的
$$W_i$$行。
y_i 为 1 的 token(真实标签)和 p_i 较大的 token(top-k collision set)得到显著梯度更新。其余大多数 token 的
,
$$(p_i - y_i) \approx 0$$,近乎 0 更新。
碰撞桶里的 token 共享 hidden 空间的方向信息。 Softmax 不做的事情是:它不分配方向——它只归一化大小。方向是 Linear 在投影时决定的。
回到我们实验的倒 U 曲线
A8-A12 的 K_lang 扫描结果就是对这个理论最好的验证:
A8(CE-only) BLEU=3.45 ← K_lang 全部分流失(无 collision 意识)
A9(k=50) BLEU=3.35 ← 桶太少,过拟合
A10(k=170) BLEU=3.63 ← K_lang 精确匹配碰撞桶数
A11(k=500) BLEU=3.09 ← 噪音开始回流
A12(k=56652) BLEU=3.35 ← 全表 softmax,无约束,信号消失
线性层的输出 z_i 的 top-k 选择(k = K_lang×|V| ≈ 170)不是随意选的——它是碰撞常数决定的。把 softmax 分母限制在碰撞桶内,梯度不再被稀释到无关 token 上。
碰撞是双向的——正反向 Hash 不对称
Linear 的碰撞不在单方向上。正向和反向的 Hash 路径是同一组参数,但经历不同的约束条件:
Token (DE) → Encoder → h_t → W·h_t + b → Token (EN)
↑ 碰撞发生在这里
向量回传 ← z_i = <W_i, h_t>
正向:释放
hidden 编码了一段包含多种语义的向量。Linear 把它释放到 32K 维词空间——每个 token 得到自己的内积分量。这个过程是稀疏的:一次翻译只输出一个 token,其他 31,999 个概率接近 0。
反向:碰撞
反向看同一个 W。在训练中,同一个 hidden 表示对应多个目标 token——不同的语言对同一个概念映射到同一个 hidden 空间。
以名词为例。名词的翻译大多是一一对应的:
德语 "Haus" → 英语 "house" 同一个概念
德语 "Buch" → 英语 "book" 同一个概念
当 “Haus” 和 “house” 分别用不同的 token ID 表示、但经过同一组 hidden → Linear 的重量时,梯度会把这两个 token 的
$$W_i$$推向同一个方向——因为它们的 hidden 表示在语义空间里是相同的位置。
但 W 只有 512 维。两个名词挤在一起、三个名词挤在一起……所有翻译中一一对应的名词,都把 W 的对应行推到 hidden 空间的同一个区域。碰撞就此发生。
反向碰撞不是坏事——它恰恰是翻译模型学会 “Haus = house” 的方式。但如果碰撞太重(桶太小),token 之间开始混淆;如果碰撞太轻(全表),梯度被稀释到无关 token 上。
翻译的全过程:
① 编码: 源语言 → hidden (压缩语义到连续空间)
② Hash: hidden → W·h_t (连续→离散投影,碰撞发生)
③ 释放: z → 概率 → token (稀疏表达在词空间)
碰撞不在第 ① 步(Transformer 本体),不在第 ③ 步(softmax 归一化),就在第 ② 步——Linear 把连续的 hidden 映射到离散的词汇空间。这是正反向不对称的核心。
结论
Linear(h_t) = logits_z 在代码里就一行。但它下面是:
翻译的整个信息瓶颈就在这里——不是在 Transformer 的 attention 层,不是 decoder 的交叉注意力,是编码器最后一层 linear 把 continuous hidden 投射到 discrete vocab 的那一步。
K_lang 不是一个调参经验值——它是这个 Hash 函数的理论碰撞常数。
过拟合 = 碰撞桶太散
从朴素的线性回归看过拟合:
$$\hat{y} = w_0 + w_1x + w_2x^2 + \dots + w_{10}x^{10}$$问题:
$$w_8, w_9, w_{10}$$这些高频项的参数变得太大——它们不是在学习信号,是在记忆每个训练点的位置。曲线扭来扭去,拟合了噪声。
NMT 里的过拟合本质上同一个东西,只是表现形式不同:
线性回归: 高频项系数太大 → 记住了噪声的多项式
NMT: 碰撞桶太散 → 每个训练句独占一个 hash 桶 → 记住了训练样本本身
证据来自 B 系列的深度和宽度对比:
| 实验 | 配置 | 参数 | BLEU | 现象 |
|---|---|---|---|---|
| B3 | d256/6L | 17M | 11.70 ✅ | 碰撞有效,泛化正常 |
| B2 | d512/6L | 56M | 8.18 | 参数太多,过拟合 |
| B4 | d512/3L | 56M | 8.57 | 参数多+浅度,双倍失败 |
B2 有 56M 参数——在 IWSLT 的 160K 句上,每个训练样本可以独占几乎一个 hash 桶。W 有足够维度同时记住每对的德语句子和英语翻译。高频词(“的”、“了”、“is”、“the”)的梯度主导了反向传播,低频但有语义的名词被淹没在参数冗余里。
B3 只有 17M 参数——因为碰撞被强制发生,“Haus” 和 “Gebäude” 必须共享参数。模型被迫去学习:“这两个德语词在语义上是相近的”,而不是死记 “Haus = house”。
K_lang 就是要保证碰撞桶够密、参数不能太大——让模型被迫去学语义共性,而不是死记训练样本。 这条线和线性回归里"控制多项式项数防止过拟合"完全平行。
MoE + 词频 = 按语言特征路由的碰撞桶
Hidden 不一定必须是一个矩阵。MoE(Mixture of Experts)早就把一个 FFN 拆成多个专家:
标准 Transformer: h → 一个 FFN → 输出
MoE Transformer: h → 路由 → 选专家 → 专家 FFN → 输出
h ─┬─→ 专家1 (第0-2层共享)
├─→ 专家2 (第3-4层共享) ← gating 网络根据 h 选
└─→ 专家3 (第5-6层共享)
已有工作(Shazeer et al. 2017, GShard, Switch Transformer)按 token 级别做路由:每个 token 被分配到一个专家 FFN。但没有人按语言特征来划分专家:
- 专家 A:短句(1-10 词)专用的 hidden 矩阵
- 专家 B:长句(30+ 词)专用的 hidden 矩阵
- 专家 C:高频词专用(“的”、“了”、“is”)
如果路由的 gating 信号不是从 h 学到的,而是从可观测的语言特征(句长、词频、TF-IDF)直接控制,MoE 就从"黑盒分配"变成了"语言学驱动的碰撞桶分配"。这等价于把 K_lang 的碰撞理论作为 MoE 架构的设计指南——每个专家就是一个碰撞桶簇。
这一思路至今未见发表。
May the Code be with us.
License: GPLv3
本文《SameTime WMT》系列采用 GNU 通用公共许可证第三版 (GNU General Public License v3.0) 协议进行开源发布与分发。