从 Bit 到 AGI第十章:自己训练一个模型

跑 Benchmark

从 Bit 到 AGI · 第十章:自己训练一个模型 · 跑 Benchmark

作者 David更新于 第 153 篇(共 186 篇)

PPL 与主观生成不够客观。Benchmark 用标准化题库(MMLU、GSM8K、HumanEval)给模型打分,便于与 Qwen/Llama 对比和回归测试。本篇用 lm-evaluation-harness 评估你的 Checkpoint。

直觉:高考模考

同一套卷子考所有模型,分数才可比。Benchmark 是公开模考;分数高不代表一切,但分数暴跌说明训练或合并出了 bug。

定义

常用基准(英文为主):

Benchmark测什么7B SOTA 约
MMLU57 科选择题~75%
GSM8K小学数学~90%
HumanEvalPython 代码~70% pass@1
HellaSwag常识续写~85%

125M 自训 Base 模型 MMLU 可能 ~25–30%(接近随机 25%);SFT 7B 才值得认真跑全套。

例子

例 1:安装 lm-eval

cd ~/mini-gpt-lab && source .venv/bin/activate
pip install lm-eval

# 或最新版
pip install git+https://github.com/EleutherAI/lm-evaluation-harness.git

例 2:评估 HuggingFace Checkpoint

lm_eval --model hf \
  --model_args pretrained=checkpoints/best-hf,dtype=bfloat16 \
  --tasks hellaswag,piqa,winogrande \
  --device cuda:0 \
  --batch_size 8 \
  --output_path results/bench_base.json

例 3:评估 SFT + LoRA

lm_eval --model hf \
  --model_args "pretrained=checkpoints/base/qwen2.5-7b-instruct,peft=checkpoints/sft-lora,dtype=bfloat16" \
  --tasks mmlu,gsm8k \
  --device cuda:0 \
  --batch_size 4 \
  --num_fewshot 5 \
  --output_path results/bench_sft.json

例 4:查看结果

python << 'EOF'
import json
from pathlib import Path
for p in Path("results").glob("*.json"):
    data = json.loads(p.read_text())
    print(f"=== {p.name} ===")
    for task, scores in data.get("results", {}).items():
        acc = scores.get("acc,none") or scores.get("acc_norm,none")
        if acc is not None:
            print(f"  {task}: {acc*100:.1f}%")
EOF

量化

模型任务时间(单卡 4090)
125Mhellaswag~5 min
7Bmmlu~45 min
7Bgsm8k 8-shot~20 min

MMLU 14042 题 × 7B forward ≈ 14042 × 4 choices × ~50ms → 量级小时。

中文场景加 ceval, cmmlu(若 harness 版本支持)。评估前确认 chat template 与 few-shot 格式正确。

动手试一试

训练前后对比(回归测试):

for ckpt in checkpoints/best-hf checkpoints/sft-lora; do
  lm_eval --model hf \
    --model_args pretrained=$ckpt,dtype=bfloat16 \
    --tasks piqa \
    --device cuda:0 \
    --batch_size 16 \
    --output_path results/piqa_$(basename $ckpt).json
done

中文 Benchmark 补充

英文 MMLU 对中文模型不公平。国内常用:

Benchmark说明命令示例
C-Eval中文多学科选择题--tasks ceval-valid
CMMLU中文大规模多任务--tasks cmmlu
GAOKAO高考题部分 harness 版本支持
lm_eval --model hf \
  --model_args pretrained=checkpoints/sft-lora,dtype=bfloat16 \
  --tasks ceval-valid \
  --device cuda:0 \
  --batch_size 4 \
  --output_path results/ceval.json

结果如何解读

Benchmark 分数不是「智商」。它衡量的是:在特定题库的 loglikelihood 或 exact match。125M 模型 HellaSwag ~35% 仍可能有流畅生成;7B SFT MMLU 60% 仍可能幻觉。工程上把 Benchmark 当回归测试:SFT 后 MMLU 掉 5 点,说明训练数据或 template 有问题。

建议维护 results/history.csv:

echo "date,checkpoint,piqa,mmlu,notes" > results/history.csv
echo "2026-07-09,best-hf,0.62,," >> results/history.csv

常见误区

  1. Base 模型跑 MMLU chat 格式:选择题需 loglikelihood,不是生成。
  2. batch_size 过大 OOM:7B MMLU 用 batch 4–8。
  3. 只看单一 benchmark:数学涨、常识跌可能是过拟合 GSM8K。
  4. few-shot 数量不一致:论文用 5-shot,你跑 0-shot,分数不可比。
  5. 未固定 random seed:multiple choice 顺序扰动影响极小,但生成类任务需 seed=42。

端到端实践要点

Benchmark 是回归测试,不是高考排名。125M Base 在 MMLU 接近随机正常;SFT 7B 才值得跑全套。lm_eval 统一了任务格式:选择题用 loglikelihood,生成题用 generate until。结果 JSON 进 Git 或 W&B,每次改数据/超参后对比 piqa、ceval 是否掉点。

中文任务务必加 C-Eval/CMMLU,英文 MMLU 对中文模型不公平。few-shot 数量与论文一致(通常 5-shot)才可比较。不要把 benchmark 分数当用户体验唯一指标:60% MMLU 仍可能幻觉,需人工 eval 与线上 A/B。

CI 可 nightly 跑轻量 piqa(5 分钟)guard 合并;发版前跑完整套。记录 checkpoint, date, scores 表格,三个月后你知道哪次 SFT 把数学能力训没了。Benchmark 集本身也可能泄露进训练数据——公开集重复率高,分数 inflate,要清醒解读。

命令流水线复盘

pip install lm-eval;lm_eval --model hf --model_args pretrained=checkpoints/best-hf --tasks hellaswag,piqa --device cuda:0 --output_path results/base.json;SFT 后同样命令改路径;python 解析 JSON 打印 acc。中文加 --tasks ceval-valid。结果 commit 到 results/ 或 W&B artifact。下一篇监控训练若长跑尚未开 W&B 可补配。

排错速查

lm_eval 找不到 task:升级 harness 或查任务名拼写。OOM:减 batch_size。分数全随机:Base 模型跑生成任务而非 loglikelihood。Peft 路径错:model_args 字符串引号嵌套。极慢:先跑 piqa 子集验证环境。

验收标准

本篇完成后,你应能在终端用一条命令或脚本验证关键产出存在且非空:test -s 查文件、curl 查 HTTP、python -c 查 import 与 shape。把验收命令写进项目 Makefile 或 scripts/verify.sh,每次改数据或权重后跑一遍,避免带着 silent failure 进入下一篇。全章二十篇都通过验收,即表示你已具备从零训小模型到部署 API 的完整能力。

与前后章衔接

本章每篇都假设你已读完第一至九章:比特与文件格式(第一章)解释 train.bin 为何是字节流;信息论(第三章)解释为何 PPL 衡量压缩效率;Transformer(第五章)解释预训练在优化什么;Tokenizer(第六章)与本章 BPE 训练一一对应;Training(第七章)给出 loss、LoRA、Checkpoint 理论;Inference(第八章)对应推理与部署;GPU(第九章)对应硬件与显存估算。若某命令报错,先查依赖版本(Python 3.11+、CUDA 驱动、PyTorch 与 vLLM 匹配),再查路径是否与 mini-gpt-lab 目录约定一致。整条流水线可在单卡 4090 上于一个周末跑通;失败时回到从失败中恢复对照症状表,不要跳过日志与 checkpoint 排查。

完成本篇后建议把关键命令与输出路径记录到 docs/run-log.md,便于复现与团队协作。

练习扩展

若时间充裕,尝试修改一个超参或配置项,观察下游指标变化并记录到 docs/run-log.md:例如清洗 threshold、词表大小、学习率、save 间隔或 vLLM 的 max-model-len。单次只改一处,才能归因。对比实验最好开 W&B 同名 project 下不同 run,用 Notes 字段标注「baseline / variant B」。这些习惯与工业界 ML 实验管理一致,比单纯跑通命令更有长期价值。

建议每篇末尾自检:关键产出文件存在、体积合理、随机抽检内容可读,再点下一篇链接。

遇到问题先查日志与磁盘空间,再查本章排错速查表。

保持 mini-gpt-lab 目录结构与命名一致,可显著减少路径类错误。

全章命令均在 bash + Python venv 下验证;Windows 用户请用 WSL2 或调整路径分隔符。

小结

  • lm_eval + --tasks 标准化评估。
  • 125M 跑轻量任务;7B SFT 跑 MMLU/GSM8K。
  • 结果 JSON 存档做 CI 回归。

→ 下一篇:监控训练

本页目录