12. 评估:证明模型真的变好了
学习目标
- 区分模型、任务与系统指标
- 避免数据泄漏和不公平对比
- 保存逐样本结果并估计不确定性
前置知识
- 概率与统计基础
- 至少完成一次模型或系统实验
本章产物成对评估结果、置信区间、错误分类和结论边界。
12.1 三层评估
模型层:loss、perplexity、标准 benchmark
任务层:你的真实业务准确率、格式、引用与工具成功率
系统层:延迟、吞吐、成本、稳定性、安全和用户结果只优化其中一层会误导。例如 benchmark 提升但延迟翻倍,可能不适合线上;格式准确率提高但事实错误增加,也不是成功。
12.2 数据划分
- Train:更新参数。
- Validation:选超参数、早停、比较 checkpoint。
- Test:最终一次或少量次数报告结果。
若反复查看 test 并据此调参,test 已经变成 validation。
对相似文档、同一用户、多轮对话或时间序列,应按组或时间切分,不能随机拆散后造成内容泄漏。
12.3 Perplexity
运行:
python code/07_evaluate_perplexity.py \
--model Qwen/Qwen3-0.6B \
--text data/tiny_corpus.txt长文本超过模型窗口时,代码使用滑动窗口,并只统计每个窗口新增 token,避免重叠部分被重复计分。
Perplexity 的限制:
- 不同 tokenizer 不可简单比较。
- 更低 perplexity 不保证更会遵循指令。
- 领域文本上的提升可能伴随其他领域退化。
- Chat Model 的用户价值不能只靠 next-token loss 衡量。
12.4 任务指标
按任务选择:
- 分类:Accuracy、Precision、Recall、F1。
- 检索:Recall@k、MRR、nDCG。
- 代码:单元测试通过率、pass@k。
- 数学:最终答案准确率和过程检查。
- 结构化输出:JSON schema 合法率、字段准确率。
- RAG:检索召回、引用正确率、faithfulness。
- Tool Use:工具选择、参数正确率、执行成功率。
12.5 生成评估的陷阱
- prompt 模板差异可能显著改变结果。
- temperature 与随机种子影响输出。
- exact match 对同义答案过严。
- LLM-as-a-judge 会有位置、长度、风格和自我偏好。
- benchmark 可能已被训练数据污染。
- 只展示最好样本属于 cherry-picking。
应保存原始输出,随机抽样人工复核,并报告失败类型。
12.6 lm-evaluation-harness
当前版本把模型后端拆为 optional extras。Transformers 后端:
python -m pip install "lm_eval[hf]"先列出任务并用很小样本检查流程:
lm-eval ls tasks正式命令应以当前 lm-eval --help 和项目文档为准,并保存:
- task 配置。
- few-shot 数量。
- chat template。
- batch size。
- model revision。
- 原始 sample 输出。
12.7 微调实验的正确对照
至少包含:
| 组别 | 用途 |
|---|---|
| Base model | 知道原始能力 |
| Base + prompt 优化 | 判断是否根本无需微调 |
| SFT/LoRA checkpoint A/B | 比较超参数 |
| 最终 adapter | 报告最终结果 |
| 负向/安全测试 | 防止局部优化带来副作用 |
如果 prompt engineering 已经解决问题,微调可能增加了不必要的维护成本。
12.8 动手:建立可重复的评估记录
实验 07A|Evaluation 资源:CPU;时间:约 2 分钟;产物:逐样本分数、聚合指标、置信区间和错误分类。
先打开评估 Notebook。它完成两件事:
- 从 token 级 NLL 计算 mean NLL 与 perplexity。
- 对同一题集上的 baseline/treatment 分数做 paired bootstrap。
评估文件不要只保存一个最终百分比。推荐逐样本 JSONL:
{"id":"case-001","group":"format","expected":"valid_json","base_score":0,"candidate_score":1,"base_output":"...","candidate_output":"...","error_type":null}汇总时至少报告:样本数、均值、置信区间、失败类型分布和原始结果路径。若区间包含 0,应写成“当前样本不足以确认稳定提升”,不能只展示正的点估计。
对语言模型困惑度运行:
python code/07_evaluate_perplexity.py \
--model Qwen/Qwen3-0.6B \
--text data/tiny_corpus.txt \
--window 512 \
--stride 256验收问题:
- 为什么同一题集必须保存逐题配对结果?
- 为什么 validation 上反复选模型后,不能再把它当最终 test?
- 为什么 perplexity、任务正确率和系统延迟必须分别报告?
- 如果平均提升来自少数容易样本,而困难任务退化,汇总数字会掩盖什么?
本章依据
原理性结论以原始论文、官方文档或公开教材为依据。论文中的实验结果只适用于其声明的模型、数据、硬件和评估设置。
多场景、多指标和透明评估框架。
标准任务评估、请求适配与可复现运行配置。
负对数似然、交叉熵和困惑度的定义。