9. 评估:BPB、CORE 与 ChatCORE
训练损失下降,不等于模型变好。评估的作用是换几把不同的尺子,回答不同的问题。
nanochat 主要使用三个指标:
- 验证 BPB:对未见文本的下一个词元预测能力。
- CORE:基础模型在多个语言理解任务上的综合评分。
- ChatCORE:对话模型在选择题、数学和代码任务上的综合评分。
验证 BPB
BPB 的全称是 bits per byte,每字节比特数。它衡量模型压缩文本的能力:给定前文,预测下一个字节平均需要多少比特。
计算过程已经在训练目标中介绍过。这里只补充评估时的注意点:
- 验证集使用最后一个数据分片,训练时不会碰它。
- 验证损失只统计真实文本词元,特殊词元和被掩码的位置不计入。
- 多个批次的损失和字节数分别累加,最后相除,而不是先算每个批次的 BPB 再平均。
- 越低越好。
nanochat/loss_eval.py第 28–64 行↗为什么不能直接平均每个批次的 BPB?因为不同批次的字节数不同。先算总损失、总字节,再相除,才能得到正确的加权结果。
CORE
CORE 来自 DCLM 论文,用来评估基础模型的语言理解能力。它不是单一任务,而是一组上下文学习(in-context learning)任务的汇总。
读 CORE 评估流程scripts/base_eval.py第 57–123 行↗大致过程:
- 下载官方的
eval_bundle,里面包含任务配置、数据和随机基线。 - 对每个任务,按 few-shot 格式拼出提示。
- 让模型给候选答案打分,或者比较续写的概率。
- 得到该任务的准确率。
- 用随机基线做中心化:
(准确率 - 随机基线) / (1 - 随机基线)。 - 对所有任务的中心化分数取平均。
中心化的意义是:不同任务猜对的概率不同。四选一的选择题随机基线是 25%,开放题可能是 0。直接平均准确率会让简单任务主导总分。
中心化后:
- 分数为 0,表示和随机猜测差不多。
- 分数为 1,表示全部答对。
- 分数为负数,表示比随机猜测还差。
nanochat 在 README 中报告的 GPT-2 基线 CORE 约为 0.2565。这个数值是特定评估配置下的结果,不要拿不同版本的评估集直接比较。
ChatCORE
ChatCORE 是对话模型版本的 CORE,使用五个任务:
- ARC-Easy
- ARC-Challenge
- MMLU
- GSM8K
- HumanEval
scripts/chat_eval.py第 201–238 行↗其中 ARC 和 MMLU 是多项选择题,GSM8K 是数学应用题,HumanEval 是代码题。
评估方式分两类:
分类评估
对于四选一题目,不需要让模型自由生成答案。评估脚本直接取模型在答案位置对 A/B/C/D 的 logits,选择分数最高的字母。
这样做降低了评估难度,也避免了“模型知道答案但格式写错”的干扰。
生成评估
对于数学和代码题,模型必须生成完整回答。脚本从回答中提取答案,再与标准答案比较。
ChatCORE 同样做中心化:
四选一任务随机基线 = 0.25
GSM8K 和 HumanEval 随机基线 = 02
最后对五个中心化分数取平均。它不是“准确率”本身,而是“相对随机基线的综合表现”。
三个指标怎样一起看
| 指标 | 衡量什么 | 什么时候看 |
|---|---|---|
| 训练损失 | 当前训练批次拟合得怎样 | 每次日志 |
| 验证 BPB | 未见文本的预测能力 | 定期评估 |
| CORE | 基础模型的语言理解能力 | 预训练中后期 |
| ChatCORE | 对话模型的综合任务能力 | SFT 和 RL 之后 |
一个常见情况是:验证 BPB 继续下降,但 CORE 不再提升。这可能意味着模型在拟合数据分布,但没有学到更多可迁移能力。另一个情况是:CORE 提升,但 SFT 后的 ChatCORE 不理想,说明对话格式或工具使用没有学好。
不要用一个指标替代全部判断。
怎样运行评估
基础模型
评估 BPB:
python -m scripts.base_eval \
--model-tag=d4-demo \
--eval=bpb \
--device-batch-size=8 \
--split-tokens=81922
3
4
5
评估 CORE:
python -m scripts.base_eval \
--model-tag=d4-demo \
--eval=core \
--max-per-task=16 \
--device-batch-size=82
3
4
5
第一次运行 CORE 会下载 eval_bundle。小模型和 CPU 上,完整评估会非常慢,所以先用 --max-per-task 限制每个任务的样本数。
对话模型
python -m scripts.chat_eval \
-i sft \
-a GSM8K \
-g d4-demo \
-x 102
3
4
5
参数含义:
-i sft:加载 SFT 检查点。RL 模型用-i rl。-a GSM8K:只评估一个任务。多个任务用|分隔。-g d4-demo:模型标签。-x 10:最多评估 10 道题。
查看完整命令帮助:
python -m scripts.base_eval --help
python -m scripts.chat_eval --help2
评估结果不可比的几种情况
比较分数前,先确认这些条件一致:
- 评估集版本相同。
- few-shot 数量相同。
- 每个任务的最大样本数相同。
- 生成任务的温度、top-k、最大生成长度相同。
- 是否使用中心化分数相同。
- 模型词表和分词器没有变化。
尤其是小样本评估。只抽 16 道题时,差一两道题就能让准确率波动很大。把 --max-per-task 调大,结果才更稳定。
本章要记住的三件事
- BPB 衡量按字节归一化的下一个词元预测能力,越低越好。
- CORE 和 ChatCORE 是多个任务中心化后的平均分,0 表示接近随机基线,1 表示满分。
- 比较评估结果时,必须保证数据、样本数和生成参数一致。
下一章开始训练模型的对话能力:监督微调。