困惑度:语言模型的内在度量
困惑度衡量模型对真实文本有多意外。这个数字是什么意思,它和损失是什么关系,以及为什么分数更低不等于助手更好用。
如果想用一个数字说明模型预测文本的本事,那就是困惑度(perplexity)。它是语言模型的标准内在度量——「内在」是因为它拿模型对着预测目标本身打分,不牵扯任何下游任务。它同时也是被滥用得最多的指标之一。搞清楚它到底在衡量什么,你才知道什么时候该信它,什么时候它什么也没告诉你。
一句话定义
困惑度就是模型面对真实文本的每个 token 时,平均有多意外。越低越不意外,也就预测得越好。
值得记住的直觉是:困惑度就是模型每一步实际在多少个 token 之间做选择。 困惑度为 1,意味着模型每次都准确知道下一个是什么,毫无不确定性。困惑度为 50,意味着模型的平均不确定程度,相当于在 50 个等概率选项里均匀乱猜。困惑度等于整个词表大小,意味着模型什么都没学到,纯粹在瞎猜。
它和损失的关系
困惑度不是独立于训练损失的另一回事——它们是同一个量换了一身衣服。
训练在最小化交叉熵损失:模型分配给正确 token 的负对数概率的平均值。困惑度不过把这个损失取指数——以 e 为底、指数为平均交叉熵,得到的就是困惑度。
有了这层关系,推理起来就方便了。因为带指数,损失上很小的改善会表现为看起来大得多的困惑度下降;困惑度减半,对应的损失下降量是固定的。当你看到训练曲线用损失报告、评测结果用困惑度报告,它们只是同一个数字的两种视角。
感受一下量级
假设模型读完一个留出句子,平均给每个正确的下一 token 分配 1/20 的概率。它的困惑度就是 20——每一步的不确定程度大致相当于掷一颗公平的 20 面骰子。
再假设一个更好的模型,平均给正确 token 分配 1/8。它的困惑度是 8。同样的文本,第二个模型明显没那么意外,因为它把更多概率质量给了本该预测到的 token。
这就是为什么困惑度在训练和预训练期间是干净的进度信号:它变化平滑,在留出文本上算起来便宜,数字下降确实意味着模型在它被造出来要完成的预测目标上变强了。
它支撑不了的比较
这里正是人们出错的地方。困惑度只有在条件一致时才有可比性。
它取决于tokenizer。 困惑度是按 token 算的,两个模型如果把文本切成不同的 token,就是在不同的单位上衡量意外程度。词表更大的模型可能显得更好或更差,纯粹因为它的 token 更大或更小,而不是因为它更会预测语言。跨不同tokenizer比较困惑度,几乎毫无意义。
它取决于测试文本。 新闻上的困惑度不能和代码或诗歌上的困惑度相比。用与训练数据相似的文本去评测,模型得分会更低,而这可能反映的是重叠,不是能力。只有用同一份留出数据比较才公平。
它奖励流畅,不奖励真实。 困惑度衡量的是文本看起来是否合乎概率,而不是其中的论断是否正确。模型可以自信而流畅地犯错,同时拿到漂亮的困惑度,因为分布尖锐不等于说的是真话。
为什么低困惑度不是目标
最重要的一条提醒:困惑度更低的模型,并不自动是更好用的助手。
困惑度衡量的是对文本的原始预测拟合程度。但人们真正想要的素质——遵循指令、拒绝有害请求、不跑题——来自另一个对齐阶段,这个阶段不一定降低困惑度,甚至可能让它略微升高。一个对话模型的困惑度可能比它基于的基座模型更高,但有用得多。
所以困惑度只适合干一件事:追踪预测目标学得怎么样。要回答「这是不是一个好助手」,你需要任务评测,而不是困惑度。把它用在职责范围之外,是这个指标最常见的错误,没有之一。
要点回顾
- 困惑度是模型每个 token 的平均意外程度——大致就是它在多少个等概率选项之间做选择
- 它是交叉熵损失的指数,所以和训练损失是同一个信号,只是单位不同
- 对预测而言越低越好,而且它在训练期间是干净、平滑的进度指标
- 只有tokenizer和测试文本都相同的模型之间才能比较
- 它衡量流畅,不衡量真实或有用的程度——更好的助手困惑度可能比它的基座模型更高
下一篇: Transformer 如何工作——正是这个架构把困惑度一路压低。