困惑度(Perplexity,PPL)是语言模型领域最经典的整体拟合指标之一。它由平均交叉熵指数变换而来,可直观理解为:模型在每一步平均「等效于在多少个候选词里犹豫」。
段末注释:Perplexity 并非独立损失函数,而是 (\exp(\text{cross-entropy})) 的单调变换,便于人类解读模型置信度。
系列索引:微调评估指标导读
一、直观含义
若平均 token 交叉熵为 (\mathcal{L}),则:
$$
\mathrm{PPL} = e^{\mathcal{L}}
$$
直觉解释:
- PPL = 10:平均而言,模型相当于在约 10 个等概率词 中做选择(对正确答案并不十分确定)。
- PPL = 1:模型几乎总是以概率 1 给出正确 token(理想下界;实际因平滑与数值精度 rarely 精确为 1)。
- PPL 越大:模型对测试文本越「困惑」,拟合越差。
与 eval_loss 携带相同信息,只是换了一种刻度。
二、使用场景与所需数据
| 场景 | 适用性 | 说明 |
|---|---|---|
| 语言建模 / 继续预训练 | 高 | 业界惯例报告 test PPL |
| SFT 指令微调监控 | 中 | Trainer 默认日志多为 loss;PPL 需自行 exp(loss) |
| 分类 / 结构化生成任务 | 低 | 任务标签短,PPL 很快饱和,不如 F1 |
| 开放对话质量 | 低 | 无唯一 reference 时无法算标准 PPL |
数据要求:与交叉熵相同——tokenized 文本序列,需明确哪些 token 参与 loss(如 completion_only 段)。
三、计算方式
3.1 由 loss 换算
$$
\mathrm{PPL} = \exp\left( -\frac{1}{|\mathcal{T}|} \sum_{t \in \mathcal{T}} \log p_\theta(y_t \mid y_{<t}) \right)
$$
3.2 代码
1 | import math |
Hugging Face evaluate 库也提供 perplexity 指标模块,底层仍是交叉熵聚合后取 exp。
3.3 数值对照(帮助建立直觉)
| eval_loss | PPL |
|---|---|
| 0.69 | 2.0 |
| 1.10 | 3.0 |
| 2.30 | 10.0 |
| 4.61 | 100.0 |
SFT 微调后期 loss 常落在 0.1~1.0,对应 PPL 约 1.1~2.7——对短 completion 任务,继续压 PPL 的收益递减。
四、如何解读
- 同一实验内看趋势:微调后 PPL 应不高于(或略低于)基座在同一验证集上的 PPL;若反而升高,可能 catastrophic forgetting(灾难性遗忘)或验证集与训练目标不匹配。
- 与 loss 同步看:PPL 是单调变换,拐点与 eval_loss 完全一致。
- 不要跨词表比较:扩大词表通常抬高 PPL 下界,不同模型 PPL 不可直接排名。
五、局限性与常见误用
- 对数尺度压缩差异:loss 从 0.1 到 0.05 差别很大,PPL 仅从 ~1.11 到 ~1.05,视觉上「改善不明显」。
- 短序列偏差:completion 只有几个 token 时,PPL 极易接近 1,失去区分度。
- 不等价于生成流畅度:低 PPL 只说明模型能复现标注文本的概率高,不保证
generate()输出多样、有用或事实正确。 - 域外文本:在训练分布外测 PPL 会飙升,但这反映的是域偏移,不一定是「模型变差」。
- 与 BLEU/ROUGE 无直接换算:开放生成质量需另算 n-gram 指标或人工评估。
六、与其他指标的关系
| 指标 | 关系 |
|---|---|
| eval_loss | (\mathrm{PPL} = e^{\text{eval_loss}}) |
| mean_token_accuracy | 高 accuracy 通常对应低 PPL,但非严格等价(错词也可能给次高概率) |
| BLEU / ROUGE | 生成任务的外部质量指标;与 PPL 相关但优化目标不同 |
七、实践建议
- SFT 以任务指标为主时,不必强行报告 PPL;若团队习惯 LM 指标,从
eval_loss换算即可。 - 做继续预训练或领域自适应时,PPL 在 hold-out 领域语料上更有参考价值。
- 论文对比时注明:词表大小、BPE 合并规则、评估 token 是否含 BOS/EOS、是否只算 completion 段。