下一个词的概率怎么算?
本课一问:下一个词的概率怎么算? 前文是「小王 喜欢」,下一个词是「猫」的概率是多少?是「学习」的概率又是多少?
这一课先不碰:文字怎么切成词(那是 C1 的事,这里先按空格切好);任何神经网络(从下一课开始)。这一课只用数数。
从已有出发
贯穿整门课的例句是「小明 把 苹果 给了 小王」(词已按空格切好,真实切分见 C1)。对语言模型来说,这句话就是一串「下一个词」:读到「小明 把 苹果 给了」,要给「小王」一个概率。它就在下面实验用的语料里,本课先用数数去算它。
下面是整门课要一步步搭出来的流水线。序章一个环节都还没学,所以全部是灰的——先看全貌:最右端的「softmax 概率」,就是模型对每个位置的下一个 token 给出的概率分布。一个 27B 参数的模型,输出也只是这一样东西。
所以「语言模型」的定义只有一句话:给前文,输出下一个词的概率。这一章回答两个问题:为什么终点是这个概率(本课与 L5),以及中间为什么是注意力(L2 到 L4)。每一代方法都在一个具体数字上失败,逼出下一代:
先把「一句话的概率」写清楚。它能严格地拆成逐词的条件概率连乘——这是概率的链式法则,不是近似:
先自己设计:最直接的办法是数数
先自己想:手里有一小段语料,怎么算 P(猫 ∣ 喜欢)?最直接的答案是数——「喜欢」后面出现过几次「猫」,除以「喜欢」后面一共出现过几次。下面这段语料每行一句,词之间用空格隔开(句首记作 <s>、句尾记作 </s>,也各算一次):
我 喜欢 机器 学习
我 喜欢 猫
小明 喜欢 猫
小明 把 苹果 给了 小王
小王 把 苹果 给了 小明
用它给测试句「小王 喜欢 猫」打分:
- ① 朴素方案
- ② 它在哪失败
- ③ 改进方案
每一步都按计数相除。句子里的词全在语料里出现过:
分子分母各加一点:P(w ∣ h) = (c(h, w) + k) / (c(h) + k·V),V = 12(10 个词 + 句尾 + 一个「词表外」位置)。没见过的组合不再是 0:
常见误解:「语料够大就不会有零概率。」 不会。词表有 V 个词,bigram 表就有 V² 个格子,trigram 表有 V³ 个。锚点模型 Qwen3.8 的词表 V = 248,320,trigram 表有 1.53×10¹⁶ 个格子;一份语料有多少个 token,最多就只能见到多少种三元组——即使拿 Qwen3 的全部预训练数据(36T token)来数,也最多填满 0.235%(下面的实验台现算)。剩下的格子不可能见过,最大似然全部给 0。我们自己的项目语料上有多少相邻 token 对从没见过,见实验台底部的项目实测(数字从项目数据现读)。
改进:平滑,然后撞上「相似的词不共享」
第一轮:平滑。 零概率的直接修法是「从见过的组合那里匀一点概率给没见过的」。最简单的是上面的加 k 平滑(k = 1 时叫 Laplace 平滑)。
平滑之后 loss 有限了,但看一眼上面「改进方案」一栏:「小王」后面所有没见过的 9 个词拿到完全相同的概率 1/14。「小王 喜欢」和「小王 学习」一样可能;而「小明 喜欢 猫」明明出现过,「小明」和「小王」都是人名这件事,计数模型一点都用不上——在它眼里每个词只是表格里的一行,行与行之间没有「像不像」。
更强的平滑确实存在:Kneser & Ney 1995 的回退平滑长期是 n-gram 语言模型里效果最好的做法之一 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条《Improved backing-off for M-gram language modeling》。它在语音识别语言模型上的实验中优于当时的回退方法;结论只在其实验设置下成立。 出处Kneser & Ney 1995 · ICASSP ↗需联网 。但它们都在「怎么匀」上做文章,解决不了「相似的词不共享统计」。
预告(C1 兑现):把每个词换成一个可学习的实数向量,让「小明」和「小王」的向量靠近,于是「小明 喜欢」的统计能迁移给「小王 喜欢」——这就是 Bengio et al. 2003 的神经概率语言模型,今天每个 LLM 的 Embedding 表都是它的直系后代。C1 的 Embedding 课会从头讲。
第二轮:窗口。 就算换成向量,「只看前 1 个词」的问题还在。改成看前 2 个、前 4 个词?计数表是 Vn 个格子,n 每加 1 就乘一次 V;锚点词表下 n = 3 已是 1.53×10¹⁶ 格。固定窗口的方法都会撞上这堵墙——下一课换一种思路:不存表格,只存一个固定大小的「状态」,一路往下传。
目标活下来了,函数换掉了。 今天的 LLM 仍然在算同一个量 P(下一个 token ∣ 前文),只是不再数数,而是用一个几百亿参数的函数去算它。n-gram 本身也没有消失,它降级成了数据工具:GPT-3 用 13-gram 重叠检测评测集是否混进了训练数据(arXiv 2005.14165 附录 C,C14 细讲);OLMo 2 用重复 n-gram 删除病态文档(arXiv 2501.00656);CCNet 用 n-gram 语言模型的困惑度给网页打分过滤(arXiv 1911.00359,C7 细讲)。
🔍 n-gram 从哪来
Shannon 1948 年的《A Mathematical Theory of Communication》§3 讨论「用统计过程逼近英语」:先按字母频率随机抽,再按双字母(digram)、三字母的转移概率抽,再换成按词频、按词与词的转移概率抽,得到的「二阶词近似」样本已经有几分像英语。极小真数字:改语料、改测试句、拨 k
计数表 c(前一个词, 下一个词)——行是前一个词,列是下一个词;「·」= 0 次
试三件事: ① 把测试句改成「小明 喜欢 猫」——每个词对都见过,loss 有限;再改回「小王 喜欢 猫」,看同一个位置变成 ∞。 ② 在语料里加一行「小王 喜欢 猫」,看计数表里那一格从红框变绿框。对计数模型来说,唯一的补救是「见过」。 ③ 把 k 从 0 拨到 1,再拨到 0.01:看「小王」那一行所有没见过的词始终拿同一个概率——k 只改变「匀多少」,不改变「一视同仁」。
常见误解:「平滑之后问题就解决了。」 平滑只保证 loss 有限。实验台里把 k 拨到 1,「小王」后面没见过的词全部拿到同一个概率:平滑会平均分,不会类比。它和训练过的小 Transformer 在同一个验证集上差多少,L5 的基线阶梯会用我们自己的项目数据排出来。
证据三问
| 问 | 本课的回答(以「平滑」为例) |
|---|---|
| ① 它解决什么问题? | 没见过的组合 P = 0,整句 loss = ∞ |
| ② 数学上为什么可能有效? | 把一部分概率挪给没见过的格子,每一项都大于 0,−ln 就有限;但「挪给谁」一视同仁,不知道谁像谁 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条加 k 后每个格子的概率至少 k/(c(h)+kV) > 0。 出处待补 |
| ③ 实验上为什么被选中? | 不同平滑在真实语料上比出来,Kneser-Ney 胜出;没有定理说它最优 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条在其语音识别语料上优于当时的回退方法。 出处Kneser & Ney 1995 ↗需联网 |
本课每条结论的证据等级:
| 结论 | 证据等级 | 依据 |
|---|---|---|
| 一句话的概率 = 逐词条件概率连乘 | 可证明 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条概率的链式法则,对任何分布都成立。 出处待补 | 概率论 |
| 只看前 1 个词是一个假设 | 理论动机 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条马尔可夫假设让概率能从计数估出来;语言里远距离依赖大量存在,所以它必然丢信息。 出处待补 | 建模选择 |
| bigram 的最大似然 = 计数相除 | 可证明 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条对每一行的多项分布求似然最大值,拉格朗日乘子法直接得出 c(h,w)/c(h)。 出处待补 | 最大似然推导 |
| 没见过的组合让整句 loss = ∞ | 可证明 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条连乘中一项为 0,整句概率为 0;−ln 0 = +∞。 出处待补 | 定义 |
| 语料再大也填不满三元组表 | 可证明 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条鸽笼原理:D 个 token 最多给出 D 种三元组,填充率 ≤ D / V³。 出处待补 | 计数 |
| 平滑能改善 n-gram 的效果 | 实验验证 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条在其语音识别语料上优于当时的回退方法。 出处Kneser & Ney 1995 ↗需联网 | Kneser & Ney 1995 |
一句话
语言模型只做一件事:给下一个词一个概率。数数能算出它,但没见过的组合概率为 0,loss 就是无穷大。
先停在这里:记住「数数能算概率,但没见过就是 0」即可,进 L2。
再深一层:展开上面「n-gram 从哪来」的 Dig;或在实验台底部看我们自己的语料上,验证集有多少相邻对训练集里从没出现过。
下一个缺口
平滑把 0 抹平了,可计数模型只看前 1 个词。「小明 把 苹果 给了 ___」——要猜出「小王」,至少得记得 4 个词之前的「小明」;加大窗口又会撞上 Vⁿ 的墙。怎么记住任意长的历史? → L2 · 怎么记住任意长的历史
另一个悬而未决的疑问——「小明」和「小王」像不像——将在 C1 的 Embedding 课兑现(C1 · 文字怎么变成数字)。
你可能会问
这一课还没有真实提问记录(问答会归档到 05-问答记录/)。先列几个最常见的:
- 为什么不直接用 trigram、5-gram? 表格是 Vⁿ 个格子,锚点词表下 trigram 已是 1.53×10¹⁶ 格,任何语料最多填满其中极小一部分——见上面的鸽笼上界。下一课换成「固定大小的状态」。
- 现在的大模型还用 n-gram 吗? 不用来做语言模型了,但用来洗数据和查评测污染(C7、C14)。
- loss 为什么用 −ln,不用 1 − P? −ln 让「连乘」变成「相加」,而且给真实答案的概率越接近 0 惩罚越重、趋于无穷——这正是本课看到的现象。交叉熵的来历可以看 3Blue1Brown《压缩即智能》Part 2(官方双语,BV1u7hQ6rEQB)。