ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

完整答案蒸馏实战:Qwen3.8-Whittle-MoE-27B-A17.8B 的 teacher32 数据集如何教会大模型“何时该停笔“

完整答案蒸馏实战:Qwen3.8-Whittle-MoE-27B-A17.8B 的 teacher32 数据集如何教会大模型“何时该停笔“

完整答案蒸馏实战:Qwen3.8-Whittle-MoE-27B-A17.8B 的 teacher32 数据集如何教会大模型"何时该停笔"

Qwen3.8-Whittle-MoE-27B-A17.8B 是一个把 27B 稠密模型改造成混合专家(MoE)架构的开源模型,压缩之后它会陷入一种怪病:列表说到一半就开始"车轱辘话",反复复读同一个模板。这篇文章拆解它的完整答案蒸馏实战——用一份名为 teacher32 的数据集(245 条"写完了就停笔"的完整答案),把"何时该停"这个缺失的信号,通过 top-32 概率蒸馏灌回模型,最终把循环率从 69% 打到 8%,而且没有让模型"变哑"。

一、先认识怪病:MoE 压缩后为什么会"说个不停"

Whittle 的架构是一次"切割",而不是重建:父模型 Qwen3.8-27B 每一层宽 17408 的稠密 FFN,被切成 64 个宽 192 的 routed 专家薄片,加 1 个宽 5120 的常驻 shared 专家。算式是精确的——64×192 + 5120 = 17408,一个神经元都不新造。每个 token 只激活 64 选 16 的专家,于是 27B 总参数里只有 17.8B 真正在跑,量化后 24GB 显存就能推理。

代价是模型学会了重复。评测基线里,144 条生成有 93 条退化成列表尾部复读,循环率高达 65%(后固定为 69%)。而且它不是复读整句,而是复读模板,比如:

  • Helping with financial planning
  • Helping with health and wellness
  • Helping with travel and tourism
  • ……一直换尾巴词,前两个词永远一样

早期的 rep-4gram 指标对这种"换尾巴"的重复完全失明(直接打 0.000),这正是它反复骗过每一版模型的元凶:仪器根本没看见缺陷。诊断细节见 WHITTLE_FINDINGS.md。

二、诊断:如何看懂"重复与停止是同一个旋钮"

团队连跑了 5 轮训练,得到一个反直觉、但近乎同义反复的结论:重复,就是"不会停"。

看这张对照表(同一评测台、同一批种子):

轮次on-policy 数据EOS 是否保留单轮循环率
baseline无保留69%
B8×保留~0%,但 6/16 被截断
C2×全部屏蔽90%
E接 B + 长文档保留2%,但答案被压到 7 个词

问题不在"要不要停",而在"何时停"。B 轮证明:教师模型在学生开始复读的那个位置,意见几乎都是"停",这个梯度最猛、最能治循环——可它同时把模型教成了"哪儿都早停"。反过来,把 EOS 全局屏蔽(C 轮),模型又彻底不会停,直接弹回 90%。

更关键的证据在推理端:直接给 EOS logit 加偏置,剂量-反应曲线显示,从"全循环"一路滑到"全沉默",中间根本不存在一个健康工作点。这说明"答案何时算写完"这个信息,压根不在权重里——缺的不是压力,是数据。完整推导见 WHITTLE_FINDINGS.md。

三、teacher32 数据集:245 条完整答案如何埋下停止信号

于是下一轮蒸馏的目标被钉死了:恰好蒸馏"因为写完而停止"这件事。这就是 teacher32 数据集(logic65/whittle-teacher32-complete-answers)的由来。

它由父模型(teacher)对同一批枚举提示词写出完整、正确的答案,并在每个 token 位置记录 top-32 概率,共 245 条,覆盖:

  • 短到 7 个 token 的事实性答案,一句话就收
  • 中长度解释
  • 长到 4000 token 的结构化文档
  • 带代码块的回答
  • 多轮对话——因为实测的失败点就在第 5 轮之后

💡 设计上有个关键讲究:长度多样性不是装饰,而是解药。如果数据集里全是长答案,模型学到的会是"大概 300 词时停"这种长度先验,而不是"内容写完时停"。所以 teacher32 故意在每一个尺度上都埋了停止信号。

另有一个 r2-structured 子集,放 34 条最长 4.9k 的结构化范例,专门补 SQL / HTML / 表格这类重灾区。

数据集还刻意与评测 gate 完全不相交。早期版本里 12 条 gate 提示有 11 条混进了训练集,等于把考试卷塞进了教材。规则很朴素:在生成数据之前,先审计 train/test 重叠。设计全过程见 WHITTLE_FINDINGS.md。

四、蒸馏实战:把 top-32 概率灌回模型的 3 个工程坑

拿到数据后,真正的坑在"怎么算损失"上。

坑一:显存爆炸。248320 的词表,8k 序列的一次全宽 fp32 logits 就是多 GB 的张量,教师模型直接 OOM。解法是windowed pass:分块 prefill、把past_key_values带下去,边算边取 top-64。它之所以在这台混合 GDN 架构上成立,是因为线性注意力层只维持一个固定大小的循环状态,完整上下文能用一个窗口的激活代价保留。落地前先用单次完整前向对齐验证——top-1 一致率 1.0000、最大 log-prob 差 0.0000,才敢花一小时 A100。

坑二:损失函数不能是朴素的 KL。top-k 截断的 logit 需要一个解耦目标,拆成三项:

  • 对"top-32 集合内总概率质量 vs 集合外"做 binary KL
  • 对集合内部形状做 conditional KL
  • 再用真实下一个 token 做 CE 锚定

三项若合并成一个 KL,会悄悄把模型教成"形状对了、但概率量放错了地方"。

坑三:别在循环位置保留 EOS 目标。on-policy 行的"停"是病灶的症状,不是要学的东西;可对干净长文档,EOS 又是唯一告诉"段落到此结束"的信号。所以掩码必须逐行选择:只在 on-policy 行屏蔽,在干净文档上保留。一刀切全局屏蔽,代价是一整轮训练才发现自己把停止能力全删了。三处细节见 WHITTLE_FINDINGS.md。

蒸馏完成后,学生侧的训练适配器落在 v2-adapter/,完整权重索引见 v2/model.safetensors.index.json。

五、蒸馏成果:循环率从 69% 降到 8%,且不"变哑"

固定同一台评测台、同一批提示和种子,历代版本对比如下(完整历史见 README.md):

指标上一版v2v2.1
单轮循环率(12 提示×3 种子)69%11%8%
多轮循环率64%7%7%
后期轮次(第 5 轮起)56%17%8%
结构化输出循环率~75%39%22%
中位答案长度268 词386 词388 词
静默 / 截断答案未测00
知识测试28/3927/3928/39

三个数字值得圈出来:

  • 📊中位长度没掉,反升到 388 词——说明模型学会了"该长就长",而不是靠早停来假装不循环
  • 静默 / 截断为 0——这是上一轮反复踩的坑,现在被守住了
  • 知识 28/39 打平基线——修复停止没有伤害既有知识

诚实地说,它没变完美:结构化输出(SQL / HTML / 表格)仍有约 1/5 会退化,45+ 项的长列表精确计数仍是架构层面的深度短板。这些限制在 README.md 里都白纸黑字写明了。

六、可复现的评测门槛:别只测你要修的那个缺陷

每个版本的发布都要过 loop_test.py——它就是模型卡上所有循环率的生成器,任何人可复现或质疑。一条生成被判 FAILED,只要触发以下任一:

  • 4-gram 重复 > 0.15
  • 重复整行 > 0.20
  • 重复行首 > 0.40
  • 或答案低于字数底线

最后那条"字数底线"是全篇最容易漏的一课:只测重复率的 gate,会被一个只回"好的。"的模型轻松通过——所有重复指标对一句空话都打 0.000。所以每个 gate 至少要有一个"过度修复反而会变差"的指标(这里就是长度底线),否则优化器(无论人或机器)总会找到退化解。12 条单轮、6 条结构化、2 段共 14 轮对话的完整判定逻辑见 loop_test.py。

七、复刻指南:6 条把"何时停笔"教给大模型的经验清单

  1. 数据先于算力:先用小窗口对齐验证教师采集是否正确(top-1 一致率、log-prob 差),再烧 A100。
  2. 生成数据前先审计 train/test 重叠,gate 冻结,训练集与之完全不相交。
  3. 数据集要覆盖"每个尺度都有停止信号",避免只教出长度先验。
  4. 每个 gate 配一个防过度修复的指标(长度底线),并手工抽查,别信单一汇总数。
  5. EOS 掩码要逐行条件化,不是一刀切删除。
  6. 完整的方法、失败日志与脚本都公开在 WHITTLE_FINDINGS.md 与 ROADMAP.md,训练计划见 ROADMAP.md。

结语

teacher32 做的事情可以浓缩成一句话:用 245 条"写完了就停笔"的完整答案,把"何时该停"这个缺失的信号,从教师模型的 top-32 概率里蒸馏回学生。它证明了:对压缩后的 MoE,缺失的往往不是知识、也不是算力,而是"答案何时算完整"这最后一点信息。

相关权重与配置,方便你按图索骥:

  • 根目录当前发布权重:model.safetensors.index.json
  • v2.2 停止门(64 个shared_expert_gate张量):v2.2/shared_expert_gate.safetensors
  • 架构定义(64 专家 / 每 token 激活 16 / 中间维 17408):config.json

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进