从 Bigram 到 MLP:神经语言模型的源头
Transformer 不是从天而降的。它是几十年来语言建模思路一步步演化的结果。 这一节我们走一遍这条路:从最朴素的 Bigram(数频率)→ Bengio 2003 的神经语言模型(MLP + embedding),看每一步加了什么、解决了什么问题。 理解了这条进化路径,Transformer 的设计动机会清晰很多。
① 起点:Bigram —— 不需要神经网络
最简单的语言模型只做一件事:数前一个字后面跟什么字的频率。这叫 Bigram(二元模型)。 给定语料,扫一遍,得到一个 的"转移表":每行是 P(下一个字 | 当前字)。生成时按概率采样即可。
听起来很 trivial?但它确实是能用的最小语言模型。下面这个玩具版用 30 字小语料训练,你可以看每个字的"下一个字概率分布",并采样生成:
这就是最简单的语言模型 —— 没有神经网络,没有训练,只数频率。 但你能感受到:"今 → 天"高频,"天 → 气"高频,生成的句子看起来"像那么回事",但缺乏长程依赖。
观察:「今」后面 100% 是「天」,「天」后面有多个选项(气、的)。整个"训练"过程就是上面那张概率表,根本没有 梯度、没有 loss。
② Bigram 的公式
③ 代码:自己训练一个 Bigram
不到 10 行 Python 就能"训完"。点「▶ 运行」看每个字符后面的概率分布:
np. 看自动提示,⌘/Ctrl + Enter运行。再看从中采样生成:
np. 看自动提示,⌘/Ctrl + Enter运行。④ Bigram 的三个致命问题
但 Bigram 在真实场景下惨不忍睹。原因有三:
- 只看前 1 个 token: P(下一个 | 上一个) 完全忽略更早的上文。「我昨天去公园然后吃了 ___」里的「___」对 Bigram 来说只看「了」 —— 根本不知道前面在说"去公园",可能采样出"了机器"。
- 没有泛化能力: 训练时见过「猫吃鱼」,没见过「狗吃鱼」?那 P(吃 | 狗) = 0,因为数没数到。「猫」和「狗」在 Bigram 表里是完全独立的两行, 没有任何机制让模型知道它们意思相近。
- 稀疏 + 爆炸: 升级到 Trigram(看前 2 个 token)需要 的表;4-gram 需要 。 V=50000 时 4-gram 表大小是 6 × 10¹⁸,根本存不下,而且绝大多数 cell 还是 0。
⑤ Bengio 2003 的突破:用神经网络替代查表
Yoshua Bengio 在 2003 年的论文《A Neural Probabilistic Language Model》提出了革命性的想法:用神经网络 + embedding 替代 N-gram 表。这就是后来一切的源头 —— word2vec、Transformer、GPT 都是这条路上的延伸。
核心结构非常直观:
- 把每个 token 映射到一个稠密向量 (这就是词表大小 V × d 的 embedding 矩阵)
- 把上下文窗口里的 ctx 个 token 的 embedding 拼接起来:
- 过一个 MLP(多层感知机):
- 输出层投影到词表大小:,再 softmax 得到下一个 token 概率
⑥ 代码:8 个矩阵,一个完整的 Bengio 模型
np. 看自动提示,⌘/Ctrl + Enter运行。这里我们没训练它(参数是随机初始化的),但结构就是这样。 训练就是让 W1, W2, b1, b2 + E 这五组参数往"让真值 token 概率最大"的方向走。 Karpathy 的 makemore 项目把这个过程完整实现了一遍,强烈推荐看:github.com/karpathy/makemore。
⑦ MLP 比 Bigram 强在哪
| 维度 | Bigram | MLP (Bengio 2003) |
|---|---|---|
| 能看多长上文 | 1 token | ctx 个(论文里 3) |
| token 之间能否共享语义 | 不能(每对独立) | 能(通过共享 embedding) |
| 参数量 | V² | V·d + ctx·d·h + h·V |
| 需要梯度下降训练 | 不需要(数频率) | 需要(SGD + 反向传播) |
| 泛化未见过的搭配 | P = 0(OOV 灾难) | 由相似 embedding 推断 |
⑧ 从 MLP 到 Transformer 的进化路径
Bengio MLP 也有自己的问题:
- 上下文窗口固定(论文里 ctx=3)。要看更长就要把权重矩阵的输入维度加大,参数量线性涨。
- 位置信息硬编码。"上文第 1 个 token"和"上文第 2 个 token"用的是 W1 的不同部分 — 信息没共享。
- 不能并行训练(其实可以,但 RNN 出现后大家都去搞 RNN 了)。
这些问题后来催生了几代模型:
- RNN/LSTM(2010s)—— 解决变长上下文,但训练串行、长程依赖差
- Attention(2014, 用于翻译)—— 让 RNN 能"看回头"
- Transformer(2017)—— 完全用 attention 替代 RNN,纯并行、长程依赖好、scaling 友好
- GPT / BERT / LLaMA(2018+)—— 在 Transformer 基础上 scale 到大规模数据 + 大规模参数
所以你正在学的 Transformer 不是"从头发明",而是"用 attention 替换 MLP 第一层"的演化。 理解 Bengio MLP,再看 Transformer Block 里的 attention,会发现它就是"自适应的、可变长的、共享权重的"第一层。
⑨ 小测验
⑩ 延伸阅读
- Bengio et al. 2003 — A Neural Probabilistic Language Model:22 页,启发后来一切的 milestone 论文。
- karpathy/makemore:Karpathy 一步步从 Bigram → Bengio MLP → WaveNet → Transformer 的字符级语言模型项目,4 期视频 + 完整代码。