困惑度:你的模型等效于几面骰子
交叉熵是个好量,但「2.3」这个数字没有实感。换个单位就有了:把它变成骰子的面数。这个换算叫困惑度,是整个语言模型领域的通用刻度。
一台字符级模型,只看前 4 个字符就预测下一个,训练语料只有 2053 个字符。在它没见过的文本上,它的困惑度大概是多少?(完全瞎猜是 27 面)
一个换算
困惑度的定义只有一行:
困惑度 (perplexity) = 2 ^ 交叉熵 # 如果用自然对数算的交叉熵,就是 e^交叉熵。换底而已。
它的价值全在读法上:
「这个模型每预测一步,犹豫的程度相当于在几个等可能的选项里抓阄。」
困惑度 = 8,意思是:虽然它面前有几万个候选词,但它的把握程度相当于面对一个八面均匀骰子。
这个换算之所以有用,是因为它把一个对数尺度的量变回了线性的、可以数的东西。人对「8 个选项」有直觉,对「3 比特」没有。
下面这张表是当场训练当场评测的——语料 2053 字符,评测在它没见过的 222 字符上:
读这张表
| 模型 | 交叉熵 | 困惑度 | 它知道什么 |
|---|---|---|---|
| 完全瞎猜 | 4.755 | 27.0 面 | 只知道有 27 种字符 |
| 0 阶(只看字频) | 4.048 | 16.5 面 | e 比 z 常见 |
| 1 阶(看前 1 个字符) | 3.013 | 8.07 面 | q 后面是 u |
| 2 阶 | 2.087 | 4.25 面 | th 后面多半是 e |
| 3 阶 | 1.587 | 3.00 面 | tion、the、ing |
| 4 阶 | 1.425 | 2.68 面 | 整个词的形状 |
从 27 面到 2.68 面。而这台模型一共只读过两千个字符。
三件事值得注意。
一、第一刀砍得最深,但每一刀都还在砍
从「瞎猜」到「只看字频」,砍掉了 0.7 比特;从 0 阶到 1 阶,又砍掉 1.04 比特;1 阶到 2 阶再砍 0.93。
每往前多看一个字符,都还能再榨出接近一个比特。这就是「语言里绝大部分是冗余」的量化版本——第 3 章香农那个实验说英语只有 1 比特左右,这张表在往那个方向走。
二、困惑度减半 = 交叉熵降 1 比特
这是这个刻度最重要的性质,也是最容易搞错的:
困惑度 16 → 8 交叉熵降 1 比特 困惑度 8 → 4 交叉熵降 1 比特 困惑度 4 → 2 交叉熵降 1 比特 # 困惑度是【指数】刻度。 # 从 100 降到 50,和从 4 降到 2,是同样大的进步。 # 而从 100 降到 90,几乎什么都没发生(少了 0.15 比特)。
要谈进步,看交叉熵(线性的),或者看压缩后的字节数(也是线性的)。看困惑度的相对变化会系统性地高估低困惑度区间的进步,低估高困惑度区间的进步。
另一个更常见的坑上一章已经提过,这里再强调一次:不同分词方式的困惑度不可比。字符级模型的 ppl=3 和词级模型的 ppl=50 完全没法比大小——因为「一步」的含义不一样。
要比较,必须换算成每字符比特数(bits per character,bpc)或者每字节比特数(bpb)。这就是为什么严肃的压缩基准(比如 Hutter Prize)用的是字节数,不是困惑度——字节数是唯一一个跨模型、跨分词、跨语言都可比的量。
三、这些是「留出集」上的数字
demo 里那张表评测的是模型没见过的文本。如果在训练文本上评测,4 阶模型的交叉熵是 0.654——好得多,也毫无意义。
为什么毫无意义,第 13 章会用一张三条曲线的图讲清楚。这里先记住一句:在训练数据上报的困惑度,是没有任何信息量的数字。
怎么读现实中的困惑度数字
下面这些是量级参考,不是精确值——不同论文的语料、分词、评测协议都不同,跨来源比较要非常小心。
- 1990 年代的三元词模型(在英文新闻上):词级困惑度大约在两三百的量级。这是几十年里语音识别和机器翻译的主力。
- 2019 年 GPT-2:在 WikiText-103 上词级困惑度大约十几到二十几,视模型规模而定。
- 现代大模型:在通用英文文本上已经进入个位数区间,字符级折算后大约在 0.6–0.8 bpb 上下。
- 人类(香农 1951 的估计):英文约 0.6–1.3 比特每字符。
最后两行放在一起看很有意思:在「预测下一个字符」这个特定任务上,现在最好的模型已经进入了香农当年测出的人类区间。
但要非常小心地理解这句话。它不意味着「模型的语言能力达到人类水平」。它只意味着:在这个特定的、可以用比特度量的任务上,两者的数字重合了。香农当年测的是人在没有任何工具、只凭记忆逐字符猜测时的表现;而模型是在海量语料上训练、可以精确调用统计规律的。两个数字相等,不代表背后的东西相同。
顺带说一句:Hutter Prize 这个比赛(压缩 1 GB 的维基百科文本)多年来的记录一直在往下走,近年的最好成绩把 1 GB 压到大约 110 MB 上下,折合约 0.88 比特每字节(这个数字随比赛进展变化,用的时候请核对当年数据)。而榜上前列的方法,全都是神经网络 + 算术编码。这不是巧合——下一章会告诉你为什么它们必然是同一件事。
困惑度还有一个不太常提但很有用的读法:它是「这个位置上真正有竞争力的候选有几个」的一个估计。
严格说,它是概率分布的指数熵,也叫「完美多样性」(perplexity 这个名字的来源)。它有一个直观性质:
# 如果分布是:一个候选概率 0.9,其余 26 个平分 0.1 H = 0.9×0.152 + 0.1×(log₂ 270) ≈ 0.94 比特 ppl ≈ 1.92 # 尽管有 27 个候选,困惑度只有 1.92 —— # 因为只有一个候选是真的有戏。
所以困惑度不数候选个数,它数「有分量的候选」个数。这也是为什么它比「top-1 准确率」信息量更大:准确率只看第一名对不对,困惑度看整个分布的形状。
为什么这个刻度重要
因为它是第一个把「模型好不好」变成一个不依赖任务的数字的东西。
「这个模型翻译得好不好」需要人来评;「这个模型代码写得对不对」需要跑测试;「这个模型会不会推理」争议无穷。但「这个模型在这段文本上的困惑度是多少」是一个确定的、可复现的、不需要任何人类判断的数。
而下一章会说明,这个数还有一个更硬的解释:它字面上等于「用这个模型压缩这段文本,能压到多小」。于是「模型的好坏」这件软事,被彻底换成了「文件的大小」这件硬事。
一台只读过两千个字符、只看前四个字符的模型,把 27 面骰子的难度压到了 2.68 面。
如果你选了 A 或 B,说明你低估了上下文的力量——而这正是这一整卷要说的事。语言里的大部分比特不在字符本身,在字符之间的关系里。
顺带一提:这台模型如果只看字频(0 阶),困惑度是 16.5。从 16.5 到 2.68,全部来自「往前看四个字符」这一件事。
这一章的一句话
困惑度 = 2^交叉熵 = 「等效多少面骰子」。它是指数刻度,所以别用百分比谈它;它依赖分词,所以别跨分词比它;它必须在没见过的数据上测,否则毫无意义。
下一章是这本书的中心。我们要拿同一台模型走两条完全不同的路:一条算交叉熵(纯预测),一条真的压缩(纯编码),然后把两个数字放在一起。它们会相差 1.6 个比特——整条消息一共 1.6 个。
那个等号不是比喻,不是类比,不是「某种意义上」。它就是等号。而它一旦被你真的看见,「语言模型」这四个字对你的意思会永久地变一次。