# 00 · 分层重构路线图 > 原则:按论文概念的依赖顺序逐层重建,每层完成后代码可运行、可验证。学习路径 = 提交历史。 > 后面各层不提前细化——细节在进入该层时随章节文档长出来(依据见 `appendix-claudemd-decisions.md` 的延迟接入哲学)。 ## 当前进度(存档点) > 每次断点(层完成/工作暂停)更新此节。恢复上下文时:读 CLAUDE.md → 本节 → 对应章节文档。 - **日期**: 2026-07-19 - **当前层**: 层 3(相似度 φ + MC 估计器),**docs/04 已精读**(用户已理解:logit-free 支点=比文本非比 logits、k_sem 是外部 teacher 信号 π̄ 只是防塌缩地板、detach 命门、chunk-vs-prefix 对应靠"同一前缀现场生成 teacher 续写"非搜索匹配);**下一步开写 E1**。层 3 全本地 CPU 纯逻辑,不碰 GPU/远程。E1 similarity.py(式3 φ+k_sem,两度量统一到词级文本、默认 edit_distance 对齐论文§5.1)、E2 estimator.py(式4 π̄ 几何均值+detach、式5 π̂ 贝叶斯凸组合)、E3 test_estimator_detach.py 接真实现。设计取舍已定见 docs/04 §3。层 2 ✅ 已关账 - **层 2 代码构成**: U1 DistillConfig(configs.py,两温度分名/三处刻意缺席/max_grad_norm 显式化);U2 token_divergence + 梯度爆炸单测(trainer.py,全词表 KL/JSD);U3 SFTCollator prompt_only 模式(data.py);U4 DistillTrainer + build_generated_batch(trainer.py,生成→双前向→divergence);U5 train_whitebox.py/.sh(full/sanity/noclip 三模式)。附带:load_sft_dataset 毛刺已磨平(改吃散装参数);hf-mirror 不代理 Xet CAS → HF_HUB_DISABLE_XET=1 - **层 2 关账判据全过**(详见 docs/03 §6.1 实证): 66 单测全绿;B=4/T=2048 **实测不 OOM**(§5 估算成立);两次远程跑(sanity 裁到 1.0 / noclip ≈关裁剪+lr5×)均平稳、不 NaN、生成不塌(num_gen ~1900-4096)、loss 0.35→0.21 下降;checkpoint 存下 - **层 2 关键发现(勘误"预期见毛刺")**: §4.1 梯度爆炸是真机制(U2 单测坐实单 token π_T→0 暴涨),但真实训练**高度阻尼**——同门 teacher + per-token mean 摊平,batch 级 grad_norm 峰值仅 ~14 且只降不升,关裁剪也不炸。启示:`grad_norm` 日志是**裁剪前**值(14→2 那串即爆炸证据,被 HF 默认 max_grad_norm=1.0 静默压平,现已显式化);层 5 有界乘子 π̂ 真正杀手锏是 **logit-free**(白盒的同 tokenizer 约束把你锁在温和区间) - **层 2 接口回看**(§6.5 每层必做,全部判"深",无需返工的毛刺): DistillConfig/token_divergence/build_generated_batch/load_sft_dataset(已修) 接口均远简于实现。三条**记录不返工**的小注:① DistillTrainer 从 self.data_collator.tokenizer 取 student tokenizer(隐式耦合,但省一个冗余参数,可接受);② SFTCollator 名字略超范(现含 prompt_only 非 SFT 模式),rename 的 churn 不值;③ token_divergence 的 labels 仅作掩码非目标(已在 docstring 标注) - **层 0**: ✅ 已关账(2026-07-18) - **层 1**: ✅ 已关账(2026-07-18)。判据全过:正本缓存 sha `33deb18c…`(1000 条,键唯一,think 残留 0,仅 2 条硬题截断);正式 1 epoch loss 0.94→0.60(56s/16 步);checkpoint 生成通顺(`/data/zym/outputs/sft_qwen3-0.6b_dapo1k`);接口回看完成(全部模块判"深";毛刺记录:load_sft_dataset 吃整个 SFTConfig 迫使诊断脚本填假 output_dir,层 2 第二消费方出现时定夺) - **层 1 疤痕档案**(详见 docs/02 §2.6/§5 勘误): ① 显存大头是 (B,T,V) logits 链与激活(正比 B×T,与参数量无关),B=8 曾爆 80G;② HF 梯度累积契约两幕剧(×8 → ÷4),终解 = model_accepts_loss_kwargs=False 退出新式契约;③ 缓存正本纪律:本地生成一次、单向 scp 分发、sha256 对账,两侧独立生成曾花双份钱且内容漂移 - **诊断工具箱**: scripts/diag_collator.py(对齐链逐环)、diag_loss_probe.py(预训练 CE 基准 0.85)、diag_generate.py(生成质量)——层 2+ 数值异常照此三板斧 - **已完成学习**: 第一/二/三章全部精讲(第三章含 standard 路径三大反直觉点、两温度、抉择原则、§4.1 梯度爆炸机制+实证) - **未精讲的文档账**: docs/01 的 §3.7(KL 锚三处实现差异)、§3.8(论文外稳定器)、§4(训练步流程走读) - **远程磁盘备忘**: 根分区 100% 的结构性原因是 `/root/zym`(507G 历史工作区)压在根分区,建议择期整体搬迁 `/data`;临时缓解 = 清 `/tmp/pip-unpack-*`、旧 tar.gz、journal。所有新增写盘已改道 `/data/zym` ## 分层计划 | 层 | 主题 | 论文对应 | 产出 | 验证方式 | |----|------|----------|------|----------| | 0 | 环境与骨架 | — | 本地/远程 conda 环境、gitea 同步、包骨架 | 两端 `pytest` 空跑通过 | | 1 | SFT 基线 | §3.1 式(1) | 数据管线 + 最小 SFT 训练脚本(Qwen3-0.6B) | 远程 4 卡跑通,loss 正常下降 | | 2 | White-box OPD 基线 | §3.1 式(2) | token 级反向 KL 蒸馏(teacher Qwen3-4B 本地 vLLM) | 远程跑通;理解式(2)梯度爆炸问题(§4.1) | | 3 | 相似度 + MC 估计器 | §3.2.1-3.2.2 式(3)(4)(5) | `similarity.py` + `estimator.py`(纯逻辑) | 本地 CPU 单测,对拍 `validate_mc_estimator.py`;detach 命门测试已预置(`tests/test_estimator_detach.py`),完成后需接入真实实现 | | 4 | Peak-entropy 调度器 | §3.2.3 式(6)(7) | `chunking.py`(纯逻辑) | 本地 CPU 单测:toy 熵序列上验证 chunk 选择与合并 | | 5 | 完整 OmniOPD | §3.2.4 式(8) | `teacher.py`(API 客户端+缓存)+ `trainer.py`(chunk 损失 + KL 锚定) | 远程端到端跑通(DeepSeek/MiniMax teacher) | | 6 | 评测与消融 | §5 | 数学评测脚本;三个消融开关 | MATH-500 子集上 student 有可测提升趋势 | ## 章节文档索引 | 文档 | 内容 | 状态 | |------|------|------| | `00-roadmap.md` | 本文 | ✅ | | `01-paper-code-map.md` | 论文 §3-§4 精读 + 参考实现全景解剖 + 概念↔代码对照表 | ✅ | | `02-sft-baseline.md` | 层 1:SFT 与数据管线 | ✅ 待读 | | `03-whitebox-opd.md` | 层 2:token 级 KL 蒸馏及其脆弱性(含 §6.1 远程实证) | ✅ 已关账 | | `04-mc-estimator.md` | 层 3:语义相似度 φ + MC 估计 + 贝叶斯平滑(式3/4/5) | ✅ 待读 | | `05-entropy-chunking.md` | 层 4:熵调度 | ⬜ | | `06-omniopd-full.md` | 层 5:完整损失与 teacher 客户端 | ⬜ | | `07-eval-ablation.md` | 层 6:评测与消融 | ⬜ | ## 关键设定(与论文默认对齐,规模缩小) | 参数 | 论文默认 | 本项目 | 说明 | |------|----------|--------|------| | chunk 数 M | 10 | 10 | 每条轨迹审计的 chunk 数 | | rollout 数 N | 10 | 10 | 每个 chunk 的 teacher MC 采样数(§4.2 证明 N=10 是甜点) | | chunk 长度 C | 50 | 50 | token 数 | | 先验强度 α | 1.0 | 1.0 | `chunk_alpha`,Dirichlet 平滑 | | 相似度 φ | **edit_distance**(§5.1) | edit_distance | ⚠️ 代码默认 rouge1(config L298)与论文默认背离,须显式指定 | | KL 锚权重 β | **0.1**(§5.1) | 0.1 | ⚠️ 代码默认 `mc_kl_weight=0` 与论文背离,须显式指定 | | 训练数据 | DAPO-Math-17K(prompt-only) | 同(层 1 先抽 ~1k 子集控制 API 成本) | 一份数据服务层 1-6;学生升到 1.7B 后可直接对表论文 Table 1 | | Student | Qwen3-1.7B / 4B | Qwen3-0.6B | 跑通优先;升级 1.7B 即可与论文对比 | | Teacher | Qwen3-32B / Claude-4.5-Haiku / Gemini-2.5-Flash | MiniMax-M3(自建 new-api 网关,OpenAI 兼容;2026-07-18 由 DeepSeek 改定) | logit-free 主路径;M3 是 reasoning 模型,思考段入库前剥离(teacher.py strip_think) | | SFT 基线定义 | teacher rollout 上的离线蒸馏(非人写答案) | 同 | 对应参考实现 `_generate_teacher_completions` + JSONL 缓存路径 |