前置知识提示:读这篇前,建议了解:token、交叉熵、NLL(见第 1、2 篇)。
论文里的那个数字,到底是什么意思#
你一定见过这样的句子:「Our model achieves a perplexity of 15.3 on Penn Treebank.」这个 15.3 是高是低?模型在「困惑」什么?如果另一篇论文报告 PPL = 21.8,是不是一定比 15.3 差?
上一篇我们推导出了交叉熵——每个 token 位置上模型的平均 loss。交叉熵越低越好,但它的单位是 nats(或 bits),不太直觉。你很难感受「1.73 nats」到底好不好。
困惑度(Perplexity, PPL)做的事情很简单:把交叉熵翻译成一个更有直觉的数字——模型在每个位置平均在多少个 token 里犹豫。

图:PPL = 5.6 意味着模型在每个位置平均觉得有约 5.6 个 token 「差不多可能」——就像每道题都是 5.6 选 1
一步指数:从交叉熵到困惑度#
回忆上一篇的结论:对句子「今天天气真好。」,交叉熵 = 1.73(nats)。
想象一场考试。交叉熵是你的「平均罚分」——每道题平均被扣了 1.73 分。但如果有人问你「这场考试难不难」,你回答「平均扣了 1.73 分」,对方大概率一脸茫然。更直觉的回答是:「感觉每道题都像在 5–6 个选项里猜。」困惑度做的就是这个翻译。
数学上,困惑度就是交叉熵的指数:
$$ \text{PPL} = \exp(\text{CE}) = \exp\left(-\frac{1}{T} \sum_{t=1}^{T} \log P(x_t \mid x_{\lt t})\right) $$用大白话说:如果交叉熵用自然对数(单位 nats),困惑度就是 \(e^{CE}\);如果用以 2 为底的对数(单位 bits),就是 \(2^{CE}\)——两种算法结果相同。交叉熵越低,困惑度越低,模型越好。
用上一篇的例子走一遍:
$$ \text{PPL} = \exp(1.73) \approx 5.64 $$意思是:模型在预测「今天天气真好。」这句话时,平均每个位置觉得有大约 5.6 个 token「差不多可能」。不是说恰好有 5.6 个候选词——而是模型的不确定程度,等效于在 5.6 个均匀分布的选项里做选择。
几个锚点帮你校准直觉:
- PPL = 1:模型完全确定每个位置该出什么 token。现实中不可能——语言本身有随机性
- PPL = V(词表大小):在整个词表里均匀猜。词表有 V 个 token,均匀猜测的 PPL 就是 V——比如词表 50000,PPL = 50000
- PPL = 15–30:一些经典 benchmark 上常见的范围,但和 tokenizer 类型(word-level / BPE)、测试集强相关,不建议当作统一的好坏区间
- PPL = 5–10:非常强的模型,或者测试文本很规律(如代码、格式化文本)
import math
ce = 1.73 # 上一篇算出的交叉熵
ppl = math.exp(ce) # PPL = 5.64
# 如果用 log2(bits),需要换底
ce_bits = ce / math.log(2) # ≈ 2.50 bits-per-token
ppl_bits = 2 ** ce_bits # 还是 5.64——PPL 和底数无关注意最后一行:不管交叉熵用自然对数(nats)还是以 2 为底的对数(bits),算出来的 PPL 是一样的。 因为指数和对数互逆,底数在一步指数里被抵消了。PPL 是一个不依赖对数底数的量——这是它作为报告指标的一个好处。
PPL 的陷阱:为什么有时会骗人#
到这里你可能觉得,PPL 是一个干净的指标——越低越好,可以拿来比模型。但实际没这么简单。PPL 有两个经常被忽略的前提条件,一旦不满足,数字就会骗人。
陷阱一:tokenizer 不同,PPL 不可比#
交叉熵的公式里有一个关键的 \(T\)——token 的数量。同一句话,不同的 tokenizer 切出来的 token 数量可以差很多。
举个例子。「unbelievable」这个词,一种 tokenizer 可能把它切成 1 个 token(整词),另一种切成 3 个(un / believ / able)。如果模型 A 用 tokenizer A(切成 1 个),模型 B 用 tokenizer B(切成 3 个),那模型 B 的交叉熵是在 3 个位置上取平均,模型 A 是在 1 个位置上取平均——分母不同,交叉熵不可比,PPL 也不可比。
更极端的情况:如果一个 tokenizer 是字符级(character-level),把「hello」切成 5 个 token,每个 token 的预测都很容易(26 个字母里选),PPL 可能只有 3–4。但这不意味着模型更好——它只是在一个更简单的粒度上做预测。
这不是理论上的问题。GPT-2 和 LLaMA 用的 tokenizer 完全不同(BPE vs SentencePiece,词表大小也不同),直接比它们的 PPL 没有意义。
陷阱二:测试语料不同,PPL 不可比#
语言本身的「不确定程度」因文体而异。
- 法律合同:用词规范、结构固定,PPL 天然偏低
- 日常对话:随意、跳跃、俚语多,PPL 天然偏高
- 代码:语法严格、关键字有限,PPL 可以非常低
- 诗歌:刻意打破常规表达,PPL 偏高
一个模型在维基百科上 PPL = 20,在推特上 PPL = 45,不能说它在推特上表现差——推特本身就更难预测。
还有一个容易忽略的变量:评估时的上下文窗口长度。Transformer 评估长文本时,上下文越长,后续 token 的预测越容易,PPL 越低。同一个模型用 512 token 窗口和 2048 token 窗口评估,PPL 可以差不少——所以比较时窗口长度也必须对齐。
那问题来了:有没有一个更公平的指标?
Bits-per-byte:一个更公平的尺子#
解决 tokenizer 不可比的一个办法:把度量单位从「每 token」换成「每 byte」。
不管你用什么 tokenizer,最终文本都是由 byte 组成的。UTF-8 编码下,一个英文字母是 1 byte,一个中文字是 3 bytes,这是固定的、不依赖 tokenizer 的。
Bits-per-byte(BPB) 的计算方式是:把整段文本的总 loss(以 bits 为单位)除以这段文本的总 byte 数。
$$ \text{BPB} = \frac{\text{NLL}_{\text{total}} / \ln 2}{\text{byte count}} $$用大白话说:把模型对整段文本的总损失转成 bits,再除以文本本身的字节数。不管你怎么切 token,分母都是一样的字节数。
import math
total_nll = 8.63 # 整句话的 NLL(nats)
total_bytes = 21 # "今天天气真好。" 的 UTF-8 字节数
bpb = (total_nll / math.log(2)) / total_bytes # ≈ 0.593 bits/byteBPB 的好处是:不管你用什么 tokenizer(BPE、SentencePiece、字符级),分母都是同样的 byte 数。 所以不同模型的 BPB 可以直接比——前提是用同一个测试语料、同一个上下文窗口长度和同一套评估协议。BPB 消除了 tokenizer 差异,但语料和评估设置的差异仍然会影响结果。
GPT-4 Technical Report 中报告过内部代码库上的 next-word prediction loss(bits per word),但它不是 BPB 的标准用例。在需要跨 tokenizer 比较的语言建模评估中,BPB/BPC 更常被用作补充或替代指标——The Pile 就明确将 BPB 作为 preferred metric。
什么时候可以放心比 PPL#
说了这么多「不可比」,那 PPL 什么时候能比?条件很明确:
- 同一个 tokenizer + 同一个测试集 → PPL 可以直接比,越低越好
- tokenizer 不同 → 用 bits-per-byte
- 测试集不同 → 不可比,除非你的目的就是比较模型在不同领域的适应能力
还有一个容易踩的坑:PPL 是在测试集上算的,不是在训练集上。如果一个模型在训练集上 PPL 很低、在测试集上 PPL 很高,那是过拟合,不是好模型。

图:同一句话被不同 tokenizer 切成不同数量的 token,导致交叉熵的分母 T 不同——PPL 数字无法直接比较
读完这篇,你拿到了什么#
我们从上一篇的交叉熵出发,走了三步:
- PPL = exp(CE):一步指数,把「平均罚分」翻译成「在多少个选项里犹豫」
- PPL 的陷阱:tokenizer 不同、语料不同时,PPL 数字不能直接比
- Bits-per-byte:一个消除 tokenizer 差异的更公平指标
从「模型训练时最小化什么」(交叉熵)到「对外报告模型有多好」(PPL / BPB),这条链路现在完整了。但 PPL 告诉你的只是模型在「预测下一个 token」这件事上有多好——它不直接告诉你模型能不能写出好的摘要、能不能准确回答问题。从 PPL 到真实任务的表现之间还有很长的路。
下一篇我们进入一个新的话题:当词表有 50000 个 token 时,模型怎么从一个向量算出这 50000 个概率?答案是 Softmax——一个把任意实数变成概率分布的函数,简单到只有一行公式,但藏着不少值得拆的细节。
参考资料 / 推荐阅读#
- Jurafsky, D. & Martin, J. H. Speech and Language Processing, Chapter 3: N-gram Language Models(§3.3 PPL 的定义与直觉)
- Gao, L. et al. (2020). The Pile: An 800GB Dataset of Diverse Text for Language Modeling. arXiv:2101.00027(使用 BPB 作为评估指标的代表性工作)
- OpenAI (2023). GPT-4 Technical Report. arXiv:2303.08774(报告了内部代码库上的 next-word prediction loss)