面向 64M Dense / 198M-A64M MoE 小模型的白盒在线 Post-Training 实验框架: 统一实现并验证 GRPO、CISPO、Dr.GRPO 和 GSPO。
English overview · 实验手册 · 源码导读 · 技术报告 · 机器可读结果
本项目基于 MiniMind 二次开发。
重点不是简单增加两个 loss,而是建立一套可审计的在线策略优化链路:冻结
old policy、同一批 rollout 执行固定 K 次更新、严格处理 action mask 和变长
轨迹,并统一记录 ratio、clip、梯度、长度、工具执行及 MoE router 指标。
当前状态(2026-08-17):Dense E1/E2 已完成。所有正式条件从同一 SFT checkpoint 出发,各运行 500 个 rollout batch / 2,000 次 policy update,并在 冻结的 994 题 test set 上做 greedy 评测。正式 E3 MoE、E4 Reward Model、 sampled pass@4、多训练 seed 和完整 E0 一轮复现尚未完成。
- 统一策略目标:
PolicyBatch -> compute_policy_loss -> LossOutput是纯张量 接口,四种算法共享同一条 rollout、reward、DDP 和 checkpoint 链路。 - 可信 online update:rollout 后冻结 old log-prob,复用同一批数据做 4 次 policy update;Torch Agent 通过 packed replay 校准 BF16 batch-shape drift。
- 严格 Math/Tool RLVR:训练与评测复用 Tool Call JSON/schema/执行和 GT verifier,主奖励不包含长度或重复 shaping。
- 工程正确性:action mask 排除 prompt、PAD、工具 observation 和 EOS 后 token;全同奖励组精确产生零 advantage;DDP 前向、尾批累积和 RNG 恢复均有测试。
- 完整实验证据链:包含冻结划分、manifest、逐步 JSONL 指标、paired bootstrap、绘图、正式 summary、失败案例和 checkpoint 哈希。
固定协议:seed 42,Dense 64M,8 prompts × 4 trajectories / global rollout,
policy_epochs=4,每个条件 500 rollouts,冻结测试集 994 题。
| Model / Objective | Task Success | 全 GT 数值覆盖 | Macro GT Coverage | Tool Call Rate | 平均回答长度 |
|---|---|---|---|---|---|
| SFT | 2.72% | 2.82% | 4.73% | 91.75% | 134.04 |
| GRPO | 0.10% | 0.10% | 0.30% | 0% | 214.27 |
| CISPO | 0% | 0% | 0.23% | 0% | 192.79 |
| Dr.GRPO | 14.08% | 14.08% | 23.64% | 55.84% | 165.73 |
| GSPO | 0.20% | 0.20% | 0.50% | 0.10% | 217.56 |
- Dr.GRPO 相对 SFT 的 Task Success 为
+11.37 pp,题目级 paired bootstrap 95% CI[+9.36,+13.38];Macro GT Coverage 为+18.91 pp,CI[+16.83,+21.04]。 - GRPO、CISPO 和 GSPO 退化为几乎不调用工具的策略。这是本项目保留并解释的 关键负结果,不是被筛掉的失败运行。
- 置信区间只描述固定评测题目的抽样不确定性,不包含训练 seed 方差。
| Advantage | Loss 分母 | Task Success |
|---|---|---|
| z-score | 实际回答长度 | 0.10% |
| mean-centered | 实际回答长度 | 0.20% |
| z-score | 固定 768 | 0% |
| mean-centered | 固定 768 | 14.08% |
Task Success 的 2×2 interaction 为 +13.98 pp,paired evaluation-sample
95% CI [+11.87,+16.20]。两个单因素都没有复现完整 Dr.GRPO 的效果,说明在
当前小模型/工具任务设定下,“去 reward std”和“固定长度分母”表现出强交互。
更完整的长度、工具调用、难度分桶和失败案例分析见 技术报告,原始 compact JSON summary 见 results/summaries。
| Objective | Advantage | Ratio / clipping | Reduction |
|---|---|---|---|
| GRPO | 组内 z-score | token-level,对称 clip | 每条实际回答长度平均 |
| CISPO | 组内 z-score | detach 的截断 IS 权重乘 log π |
每条实际回答长度平均 |
| Dr.GRPO | R - group_mean(R) |
token-level,对称 clip | token surrogate 总和除以固定 L=768 |
| GSPO | 组内 z-score | 长度归一化 sequence ratio,整条序列统一 clip | response-level mean |
实现严格按所引用论文的目标语义校准;reference KL 独立于 policy objective 归约。完整公式、张量形状和代码逐行映射见 源码全景导读第 6 节。
flowchart LR
A[SFT checkpoint] --> B[Batched multi-turn rollout]
B --> C[Tool execution + RLVR verifier]
C --> D[Pack trajectories + action mask]
D --> E[Freeze old/ref log-probs and rewards]
E --> F[GRPO / CISPO / Dr.GRPO / GSPO]
F -->|same rollout, K=4| G[DDP optimizer updates]
G --> H[Atomic checkpoint + JSONL metrics]
H --> I[Frozen greedy evaluation]
I --> J[Summary + paired bootstrap + plots]
G --> B
Torch Agent rollout 会动态合批当前仍活跃的轨迹;工具 observation 会进入下一轮
上下文,但不会进入策略 loss。训练时将同一 prompt 的完整 reward group 打包,
在策略尚未更新时重放得到固定 old_logps,随后才进行 4 次更新。第一次 update
的 ratio 应约为 1、clip fraction 应为 0;第二次以后 ratio 才应偏离 1。
建议 Python 3.10+、CUDA 12.x。请先按本机 CUDA 安装 PyTorch,再安装其余依赖:
git clone https://github.com/Troy0630/MiniMind-PostTrainLab.git
cd MiniMind-PostTrainLab
pip install torch --index-url https://download.pytorch.org/whl/cu124
pip install -r requirements.txtCPU 即可运行核心 objective、mask、奖励和汇总测试:
pytest -q \
tests/test_policy_objectives.py \
tests/test_rollout_engine.py \
tests/test_posttrain_tools.py \
tests/test_posttrain_diagnostics.py完整测试:
pytest -q tests训练数据、checkpoint 和逐题运行产物体积较大,不进入 Git。按
上游 MiniMind 数据说明下载 agent_rl_math.jsonl 后执行:
python scripts/prepare_posttrain_splits.py \
--input dataset/agent_rl_math.jsonl \
--output-dir dataset/posttrain \
--seed 42脚本会做 NFKC/空白/Tool JSON 规范化、prompt 去重、按 GT 数量与粗操作类型分层,
并生成带 SHA256 的 manifest.json。正式划分为 17,894 / 994 / 994。
E1 不能从随机初始化直接启动。先按 实验手册 E0 得到:
out/full_sft_e0_dense_768.pth
然后运行:
# E1:GRPO / CISPO / Dr.GRPO / GSPO,依次执行
E1_GPU_LIST=0,1,2,3 \
PYTHON_BIN=python TORCHRUN_BIN=torchrun \
bash train.sh e1
# E2:只训练 2×2 消融中缺失的两个 cell
E1_GPU_LIST=0,1,2,3 \
PYTHON_BIN=python TORCHRUN_BIN=torchrun \
bash train.sh e2
# 994 题冻结 greedy 评测与 paired summary
EVAL_GPU_LIST=0,1,2,3 \
PYTHON_BIN=python \
bash scripts/run_frozen_e1_eval.shtrain.sh 会拒绝覆盖非空 run 目录;断点续训、单条件命令、E0/E3/E4 和绘图命令
见完整实验手册。协议 JSON 是可审计清单,不会
被 trainer 隐式加载;实际参数会展开进 CLI 并写入 manifest。
trainer/
├── policy_objectives.py # 四种 PO 目标的纯张量实现
├── train_agent.py # Math/Tool RLVR 主训练循环
├── train_grpo.py # 通用 Reward Model RLAIF 路线
├── rollout_engine.py # Torch / SGLang rollout 后端
├── agent_rewards.py # 安全工具执行与严格 GT verifier
├── posttrain_diagnostics.py # ratio、clip、DDP、MoE 指标
└── trainer_utils.py # DDP、checkpoint、RNG 与 token 快照
scripts/
├── prepare_posttrain_splits.py
├── capture_posttrain_manifest.py
├── eval_posttrain_agent.py
├── summarize_posttrain_results.py
└── plot_posttrain_metrics.py
experiments/posttrain/
├── configs/ # 冻结实验协议
├── results/ # 可提交 summary 与正式图表
├── README.md # 完整实验手册与命令
├── README.en.md # English method/results overview
├── REPORT.zh-CN.md # 方法、结果、失败案例与局限
├── CODEBASE.zh-CN.md # 从模型到评测的逐模块源码导读
└── RESUME_INTERVIEW.md # 简历与面试讲解材料
tests/ # loss、mask、DDP、resume、评测测试
原始 MiniMind 的 Dense/MoE、Pretrain、SFT、DPO、PPO、LoRA、蒸馏、转换和部署 代码仍完整保留。中文上游文档见 README_MINIMIND.md, 英文上游文档见 README_en.md。
如果你想真正理解实现,按依赖顺序阅读:
model/tokenizer_config.json:确认 chat/tool transcript 如何编码;model/model_minimind.py:Config → GQA/RoPE → Dense/MoE → CausalLM;dataset/lm_dataset.py:各阶段监督哪些 token;trainer/policy_objectives.py:脱离 trainer 手推四种 loss;trainer/rollout_engine.py:old log-prob 与 completion mask 从哪里来;trainer/agent_rewards.py:reward/verifier 的事实边界;trainer/train_agent.py::rl_train_epoch:串起 rollout、packing、K updates 与 DDP;scripts/eval_posttrain_agent.py和 summary/plot:理解结论如何从逐题记录产生;- 对照
tests/阅读每个反例与不变量。
完整中文导读已整理在 CODEBASE.zh-CN.md,包含目录职责、张量 形状、公式到代码映射、checkpoint 格式、评测链路、常见误区和扩展方法。
- 只有一个训练 seed;不能宣称跨 seed 稳定或普遍显著。
- 提升主要集中在 1-GT 题;2-GT success 为 0.81%,3-GT 为 0%。
- 140 个 Dr.GRPO success 均有 GT 相关工具执行证据,但重复和无关调用仍常见。
- Dr.GRPO 相对其他 PO 缓解错误回答变长/截断,但仍弱于 SFT 的长度表现,不能 宣称“消除了长度偏置”。
- GSPO 在本次 Dense 任务上未获得效果收益;正式 MoE 稳定性结论需要 E3。
- 不使用“SOTA”“稳定复现论文性能”或把 evaluation bootstrap 写成训练稳定性。
本项目是 MiniMind 的衍生研究项目,不代表 upstream 官方实验结论。原始实现与 社区贡献归各自作者所有;具体 base revision 和修改范围见 NOTICE。代码 沿用 Apache License 2.0 发布。
欢迎提交能保持实验可比性的 bug fix、新 objective、verifier 或诊断指标。贡献前 请阅读 CONTRIBUTING.md,并为算法语义和边界条件补充测试。
