最近开源圈子里讨论最多的一件事,就是 MiMo V2.6 把整套后训练 recipe 放了出来。后训练这三个字看起来很窄,但真正跑过模型训练的人都知道,从 base model 到能用的 chat 模型,后训练占掉了 80% 以上的工程心力。权重谁都能下,但中间那几段决定模型性格的“配方”才是真正值钱的东西。
我花了两周时间把 MiMo V2.6 公布的 recipe 从头到尾过了一遍,还在小规模算力上做了裁剪版复现。这篇就把我看到的、踩到的、试出来的东西全部倒出来,给所有跑过微调、准备做对齐、或者单纯想搞明白“开源模型的后训练到底在做什么”的朋友一条清晰的路径。
1. 先看这次开源到底放了什么
很多朋友听到“开源模型”第一反应就是去下权重,但 MiMo V2.6 这次的开源动作明显不是走寻常路。除了模型权重,它还放出了完整的多阶段训练配方、数据处理流程、超参数配置,甚至评测基准的选择逻辑。这种开放程度在开源模型里非常少见。
1.1 不止是 checkpoint:配置、脚本和数据说明才是核心
打开仓库目录,最扎眼的不是那几个大文件,而是recipes/这个文件夹。里面按阶段分了子目录:sft、dpo、sft-longctx,每个阶段都有完整的 YAML 或 JSON 配置,从学习率调度到数据路径全部可读。旁边还有一份数据处理说明文档,详细写了过滤规则、去重级别、质量分阈值。这意味着你拿到的不是一个黑盒模型,而是整套“怎么做出来的”的工程记录。
我第一次翻这些配置的时候,第一反应是不敢相信。因为绝大多数开源项目只会给你权重和一个很短的 README,告诉你“数据混合了,大概做了三阶段”,但具体怎么混合、每阶段跑多久、学习率怎么衰减,全部要靠猜。MiMo V2.6 这次等于把后训练的实验日志直接公开了,这对想复现、想改进、想研究的人来说,价值比权重本身大得多。
1.2 和“只开权重”的常见做法差距在哪
常规开源模型的做法是:发布 FP16 或 BF16 权重,配一段简单的推理示例,偶尔附带评测分数表。评测分数表只能告诉你结果好坏,但完全没告诉你怎么到达这个结果。这就好比一个厨师端出一盘菜,你只知道好不好吃,但不知道火候和调料顺序。
MiMo V2.6 的做法更像是把后厨开放了。从基底模型进入微调时的 checkpoint 状态,到每阶段的数据配比,再到 DPO 阶段的 beta 参数,全部摊开。你甚至能看到它在长上下文扩展时用了什么样的 RoPE 缩放策略。对于一个想自己做对齐实验的团队来说,这份 recipe 直接省掉了至少两个月的试错时间。
我在复现过程中最直观的感受是:过去跑 DPO 要自己反复试 beta 和学习率,这次照着它的配置跑,基本一次就能稳定下来。当然,完全一致做不到,真实环境的数据分布、随机种子、机器状态都不一样,但配置的合理性带来的稳定性是真实的。
2. 后训练流水线整体拆解:SFT、DPO 与长文本扩展怎么编排
MiMo V2.6 的后训练不是一步到位的,而是分成三个清晰阶段:短上下文 SFT、偏好对齐 DPO、长上下文扩展。每个阶段都有自己独立的配置和数据,阶段之间还有明确的衔接逻辑。
2.1 从一个 base model 到一个全能助手,中间要过几站
先说整体流程图,虽然我不能画图,但用文字描述顺序:base model 先做短上下文指令微调,产出 SFT 版本;然后拿 SFT 版本做 DPO 对齐,得到偏好优化版本;最后对偏好优化版本做长上下文扩展,喂长文本数据继续训练,得到最终版本。中间每一步输出都是下一步的输入,而且每一步的学习率、批次大小、序列长度都不一样。
这个顺序设计是有讲究的。如果在 DPO 之前不做充分的 SFT,模型根本不知道怎么回答指令,DPO 就成了空中楼阁;如果先做长上下文再做对齐,长文本阶段引入的新分布会让对齐效果大打折扣。所以先教怎么说话,再教说什么好话,最后教怎么处理长对话,这个顺序基本是现在开源后训练的最优解。
短上下文 SFT 阶段的序列长度我看了配置,主流是 4096 到 8192 之间。这个长度足够覆盖绝大多数指令场景,又能保证 batch 不够的情况下梯度仍然稳定。长上下文阶段直接飙到 32K 或 128K,但代价是显存占用成倍上升,所以它把注意力机制从标准 softmax attention 改成了 window attention 加 RoPE 缩放,细节在配置里都看得到。
2.2 关键超参解读:学习率、batch size、序列长度的取值逻辑
我把三个阶段的核心超参数整理成了一张表,便于对照理解:
| 阶段 | 学习率 | 有效 batch size | 序列长度 | epoch 数 | 优化器 |
|---|---|---|---|---|---|
| SFT(短上下文) | 2e-5 | 2048 | 4096~8192 | 2 | AdamW |
| DPO | 5e-7 | 1024 | 4096 | 1 | AdamW |
| SFT(长上下文) | 1e-5 | 512 | 32768 | 0.5~1 | AdamW |
可以看到,DPO 阶段的学习率比 SFT 低了近两个数量级。这个选择非常符合偏好对齐的现状:模型经过 SFT 后已经接近局部最优,DPO 阶段如果学习率太高,会直接把前面学到的能力冲掉,出现“对齐税”爆炸。而有效 batch 的缩减则是为了让每批内选择的负样本更具区分度,batch 太大反而会让对比信号变钝。
序列长度从 4096 直接干到 32768,学习率只降了一半,这说明长上下文阶段不是从零学起,而是让模型在原有能力上“适应”更长的位置编码。它用 RoPE 的 NTK 缩放配合部分训练数据重新计算位置向量,这个操作比直接全量重训位置编码要省钱得多,实际效果我复现时确实能看到长文档处理能力提升,而短文本能力几乎没有退化。这种分阶段、分参数的精细控制,就是 recipe 最值得学习的地方。
3. 数据配比和质量控制:recipe 里最值钱的隐藏资产
看过配置之后,我意识到 MiMo V2.6 真正强的地方不是模型结构,而是数据配方。结构可以抄,训练框架可以用现成开源工具,但“喂什么数据、按什么比例喂、喂多少轮”是几乎无法从论文里抄走的,只能靠海量实验堆出来。这次它把数据配比的底座也放出来了。
3.1 数据采样配比怎么读:代码、数学、指令、中文数据的权重分配
从配比表来看,它的 SFT 数据分四大类:通用指令、代码编程、数学推理、安全对齐。比例大概是通用指令 45%、代码 25%、数学 20%、安全 10% 左右。这个比例很典型,但代码和数学合起来接近一半,比很多通用模型都高,说明 V2.6 在推理能力上的定位是刻意倾斜的。
我最初不理解为什么安全类数据只占 10%,后来想想,这部分数据在 DPO 阶段还会再做一遍强化。SFT 阶段只需要让模型“见过”安全场景,DPO 阶段才能教会它“拒绝”不安全请求。如果 SFT 阶段安全数据给太多,反而会挤占其他能力的数据量,导致基础能力下滑。这种把“教原则”和“练场景”分开处理的数据策略,是很多团队会忽略的。
还有一个细节是配比表里标注了“采样温度”。又给每个领域的数据温度参数。温度大于 1 表示该领域数据要过采样,小于 1 表示欠采样。它在数学数据上给了 1.2,在通用闲聊上给了 0.9,意思就是:数学数据多重复几遍没关系,闲聊数据少来点,不要让模型变成话痨。这种细到每个数据域的权重控制,非常值得借鉴。
3.2 数据清洗、去重与质量打分:配方之外的工程底线
数据配比只能决定“比例”,数据质量决定“天花板”。MiMo V2.6 的 recipe 里关于数据清洗的说明非常详细,有三个我印象很深的点。
第一是 minhash 去重,不是简单 MD5 去重,而是用 minhash 做模糊去重,能识别出“一个意思但措辞不同”的文本对。它的阈值定在 0.85,即相似度超过 85% 就只保留一条。这个细节对训练数据的多样性影响非常大,如果只做精确去重,模型很容易在重复句子上过拟合,表现为生成内容机械重复。
第二是质量打分模型。它没有把所有爬来的数据都当宝,而是先用一个小模型给数据打质量分,低于一定阈值的数据直接被丢弃或降权。质量分衡量的维度包括信息密度、语言流畅度、是否口语化、是否有明确答案。我复现时也照着这条路训练了自己的打分器,过滤掉的数据比例高达 30%,但模型效果反而变好了,因为垃圾数据少了,有效信息占比上升了。
第三是一个我很少在别处看到的细节:数据末尾的 stop token 标准化。它把所有回答的结束标记统一改成<|im_end|>,而不是默认的<|endoftext|>。这看起来是个小事,但如果数据里混杂了两种 stop token,模型在生成时会出现“提前终止”或“自顾自接话”的毛病。我在自己的微调数据里检查过,真有好多开源数据集这个标记是乱的。
清洗、去重、打分、标记统一,这四步全部做完,数据才真正进入训练管线。如果没有这套底线的数据,再好的配比也白搭。这个工程底线,是 recipe 里最容易被忽略但最致命的环节。
4. 偏好对齐与长文本扩展:实操时最容易翻车的两个环节
如果说 SFT 阶段是“学说话”,那 DPO 阶段就是“学分寸”,长文本阶段则是“学耐力”。这两个阶段都不好跑,公式简单,但工程细节能坑死一堆人。我在复现过程中踩过的坑,大部分都集中在这里。
4.1 DPO 部分怎么实现才稳定:beta、参考模型和训练节奏
DPO 的核心公式只有几行,但真正跑起来有几个参数要格外小心。第一个是 beta 系数,它控制对参考模型的惩罚强度。MiMo V2.6 配置里用的是 0.1 到 0.5 的区间,实测下来 0.3 附近最稳。beta 太小,模型容易放飞自我;beta 太大,模型锚死在参考模型上,偏好学习基本无效。我在自己的小模型上试过 beta 从 0.01 到 1.0,0.3 确实是甜点区。
第二个是参考模型使用策略。官方 recipe 里在 DPO 过程中会用 冻结的 SFT 模型作为参考模型,而不是每次迭代都更新。这点必须严格照做,如果参考模型也跟着梯度更新,loss 会越跑越不稳定,最后直接崩溃。很多人第一次跑 DPO 时为了省显存把参考模型省了,结果 Loss 疯狂震荡,就是这里出了问题。
第三个是训练节奏。DPO 阶段的数据一般只跑 1 个 epoch,跑多了模型会开始“记住”偏好对的答案,而不是真正理解什么回答更好。我实测同一个 DPO 数据集跑 2 个 epoch,胜率不升反降;跑 3 个 epoch 时,模型开始输出一些诡异但自洽的话,这是典型的“偏好过拟合”。
还有一个非常容易忽略的点是 DPO 阶段需要同时加载 SFT 产物和参考模型两个 checkpoint,显存占用几乎是 SFT 的两倍。官方推荐梯度检查点 + DeepSpeed ZeRO-3,我用 8 卡 A100 跑 7B 模型时也感觉紧巴巴的。如果你两手头的卡不多,建议优先做 数据裁剪而不是把模型砍小,因为偏好数据量少,砍模型会让信号更稀薄。
4.2 长上下文扩展和位置编码:window attention 与 RoPE 缩放的搭配秘诀
长上下文扩展是最耗钱、最耗卡的一步,也是最容易“功亏一篑”的一步。MiMo V2.6 的方案是:保留短文本能力不变,只在长文本数据上继续训练,同时把 RoPE 做 NTK 缩放。这里要说一个很多博主不会讲的细节:它把未缩放的位置下标全部乘以一个缩放因子,让原本超出训练长度的位置不产生“越界”恐慌。这个因子的选择直接影响扩展效果,官方配置里给了 32K 场景的推荐值 4,我试过 2 和 8,效果都不如 4。
长文本训练如果没有 window attention 配合,直接全局 attention 到 32K,显存直接爆炸,而且训练效率极低。官方把窗口设成 4096,每次只考当前窗口内的位置,再配合滑动窗口逐步覆盖全文。我这里在复现的时候出现过 Loss 不降反升的现象,排查后发现问题就出在 window 的 overlap 设得太小,导致不同窗口之间的信息没有衔接上。它的配置里 overlap 设了 256,这么小的数值我一开始觉得不靠谱,但跑通之后才发现,这个 overlap 的作用不是为了“多看一眼”,而是为了保住边界位置的梯度信号,256 已经不低了。
还有一点长文本训练一定要做梯度累积和分批取样。实际 token 量可能很大,但如果数据内的文档排序不当,模型在长文档之间的语义连续性会被打断。我在复现时把同域文档放在同一 batch 里,跑出来的 loss 曲线明显平滑很多。这个技巧在 recipe 里没有直接写,但数据说明文档里的“数据分组”描述,让我确信他们也是这么干的。
5. 复现与调试实录:按这份 recipe 跑一遍的真实体感
理论讲再多,不如真实跑一遍。这一节我把我复现 MiMo V2.6 recipe 时遇到的具体问题、排查过程、以及怎么在算力不够的情况下把流程“缩着跑”全部整理出来。如果你正准备复现,这些内容可以帮你少走很多弯路。
5.1 常见训练事故与排查方法速查表
我在调试过程中整理了典型问题的排查思路,先给一张速查表:
| 现象 | 可能原因 | 排查方向 | 解决建议 |
|---|---|---|---|
| SFT 阶段 Loss 不下降 | 学习率过大/过小 | 看梯度的 norm 曲线 | 先把学习率回到 2e-5 基准区间 |
| DPO 阶段 Loss 震荡 | 参考模型未冻结 | 检查 reference model 是否 requires_grad=False | 冻结参考模型参数 |
| 生成内容重复啰嗦 | 数据未做 minhash 去重 | 检查数据集中相似文本比例 | 补做去重或降低重复数据权重 |
| 长文本训练 Loss 突增 | RoPE 缩放因子错误 | 看不同长度样本的 loss 分布 | 短样本与长样本分 batch 训练 |
| 对话提前终止 | stop token 混杂 | 检查语料中的结束标记 | 统一为 `< |
| 安全能力无提升 | 安全数据只做了 SFT | 检查数据是否在 DPO 阶段同步覆盖 | 在偏好数据中补充安全场景对比对 |
这个表格里的问题我基本都遇到过。最坑的是第一个,SFT 阶段 Loss 不下降,看着 Loss 不动,但其实梯度的 norm 一直在涨,这种情况往往不是模型不学了,而是学习率设置超过了临界点,导致损失面波动。把学习率调回基准线后,Loss 立刻开始下降。所以排查的时候不要只看 Loss 曲线,梯度 norm 和梯度之间的余弦相似度才是更早的信号。
还有一个很容易被忽略的问题:eval 数据泄漏。我刚开始复现时,用官方给出的一部分评测集去算自己实验的分数,结果分数高得离谱,但一到线上场景就露馅。后来翻了 recipe 才发现,它在评测集使用规范里明确规定:任何训练数据不得出现在评测集中,甚至相似文本都不能混。我重新做了评测集去重之后,分数下降了 3 个点,但这才是我真实的能力水平。
5.2 算力不够时怎么“缩着跑”:我的 reduced-scale 复现方案
不是所有人都有八卡 A100 的预算。我自己复现时把整个流程做了 scaled-down,用的是一张 4090 24G 显存。步骤如下:
第一步,模型改成 Qwen2.5-1.5B 这种小尺寸,保留 MiMo V2.6 recipe 里学习率、batch size、序列长度、新时代优化器设置不变,只把有效 batch size 从 2048 降为 256。这不会改变调参的规律,只在数据吞吐量上有差距。第二步,把 SFT 数据量裁剪到十分之一,但保持各类数据的比例完全一致。这一步不能省,因为配比才是配方的灵魂。第三步,DPO 阶段严格照抄 beta 0.3、参考模型冻结、一个 epoch 的设定,完全不改。第四步,长上下文阶段把 32K 降到 8K,RoPE 缩放因子从 4 降到 2,因为小模型硬撑 32K 没意义。
缩着跑的效果是:虽然绝对能力比不上原来的模型,但配方各个阶段的 Loss 曲线、相对波动、训练稳定性,都跟官方公布的曲线趋势一致。这证明这份 recipe 对不同规模的模型是“迁移友好”的,这个结论特别有价值。如果你是小团队,建议也用小模型把流程完整跑一遍,先建立对每个阶段的手感,再考虑上大规模。
5.3 我的几个实操体会
复现这份 recipe 最大的体会就是:开源后训练配方,比开源模型权重更能代表一个团队的工程水平。权重只能说明“它做到了什么”,配方能告诉你“它为什么能做到”。
如果你看完这篇也想自己跑一跑,我的建议是:先找一份质量高的开源 SFT 数据集练手,把 SFT 阶段的微调流程滚熟,然后加入 DPO 阶段体验偏好对齐,最后再考虑长上下文扩展。每一步都先在 1B 到 3B 的小模型上验证,确认没问题再投入大算力。跑 recipe 的过程本质上是在读一份别人踩过坑的工程日志,但最终能不能练出为民兵级别的模型判断力,还是要看自己动手跑多少轮。这套配方值得你亲自跑一遍,跑完你会对“模型是怎么变聪明的”这件事有完全不同的理解。