从SFT到RL:拆解MiMo-V2.6性能翻倍的工程实践
最近开源社区最热闹的讨论绕不开MiMo-V2.6这个版本迭代。看着基准分数从二十多跳到六十多很多人第一反应是“刷榜了吧”第二反应是“是不是测试集泄了”。但如果你把这次迭代的训练日志拿出来看最大变量其实是RL训练量的加大。模型结构没怎么动数据也就加了那么几条真正让性能翻了三倍的就是强化学习这一套流程。这篇文章我不打算复述哪个榜又涨了多少分而是想把RL这条路线彻底拆开为什么RL能带来这么大幅度的提升、MiMo-V2.6这类案例到底是怎么组织训练数据的、奖励设计踩了哪些坑、以及你自己手头有个开源模型时怎么把这套流程落地。无论你是做开源模型调优的研究者还是想在小规模团队里复现类似效果的工程师这篇文章应该能帮你节省不少试错时间。1. 一个版本迭代引发的话题RL凭什么撬动三倍性能1.1 先说清一个误区RL不是“万能外挂”很多人一听到“性能翻三倍”第一反应是模型换了个更大的底座或者是数据量翻了几十倍。但MiMo-V2.6这个迭代最有意思的地方在于基座模型基本没换SFT阶段的数据也就小幅扩充真正花大力气的是在RL阶段持续滚动训练。这事放在两年前可能还很难理解但现在回过头看路径其实已经很清晰了。监督微调SFT和强化学习RL的差别在哪打个比方SFT像一个学生照着标准答案抄作业教师把正确答案给你你模仿这个答案的格式、句式、推导过程。但这个过程中学生并不知道“为什么这个答案是对的”也只能模仿见过的题目。RL阶段完全换了一种训练方式模型不再拿标准答案当唯一参照而是自己去生成内容然后接一个奖励信号判断生成得好不好好就强化不好就压低概率。这个区别是根本性的。SFT是在“答案空间”里做拟合RL是在“行为空间”里做搜索。大语言模型的行为空间有多大你给它一个提示词它能输出的序列组合基本上是天文数字。SFT只能优化其中很少的一部分路径而RL可以让模型自己去探索更多可能的行为路径试错、调整、再试错。MiMo-V2.6的性能翻倍本质上不是在单个知识点上进步而是整个策略空间都被拓宽了。1.2 性能翻倍的真实来源策略空间与自我纠错那性能提升到底来自模型的哪些具体能力我拆了MiMo-V2.6在各类评测集上的表现大致能看到三个方面的变化。第一是链式推导质量的提升。SFT阶段模型虽然也会输出“第一步、第二步、第三步”但很多时候这些步骤只是形式上的。RL训练之后模型会把步骤真正当作决策依据来用每一步的结果会影响到下一步的选择模型学会了往前看也学会了在发现前面步骤不对时回头修正。这在数学推理、逻辑判断类任务上特别明显。第二是自我纠错能力。这个能力在传统的SFT里几乎学不到因为标准答案只有一个你不需要回头检查。但RL的训练机制天然鼓励模型在生成的末尾追加一个自检阶段重新审视一下之前的推导发现漏洞就补上。MiMo-V2.6在多轮对话和长文本生成任务上的提升很大一部分就归功于这种“自我反思”式的策略。第三是难度自适应。SFT阶段如果训练集里的难题太多模型会学着“硬做”遇到不会的问题就在那里瞎编。RL阶段通过奖励信号模型会逐渐学到“这题我当前策略做不出来那我应该改变尝试路径”而不是继续在一个死胡同里打转。很多测试集上分数的跃升其实是模型开始学会怎么处理“不会的题”而不是把所有题目都变成“会的题”。有意思的是这个现象在规模不大的模型上反而更明显。大模型本身容量大SFT阶段就能吸收不少信息小模型则处于另一个状态SFT阶段把显式知识基本吃满了再用更多SFT数据也只是挤压过拟合。这时候RL刚好打开了另一个维度用行为搜索补足容量限制带来的能力短板。所以你会看到很多7B、13B量级的模型RL之后的效果提升甚至比30B以上模型更夸张这并不奇怪。1.3 为什么很多团队的RL项目却失败了既然RL这么香为什么业内还有大量“RL没用”的说法我自己也踩过这个坑仔细复盘之后发现大部分失败案例不是RL这门技术不行而是三个前置条件没有满足。奖励信号本身是坏的。奖励模型打的分和人类真实偏好对不上或者规则奖励设计得过于死板模型一顿操作下来把奖励刷高了但生成质量反而更差。这时候RL优化的方向就是错的越练越偏。训练数据的分布太简单或太单一。RL真正起作用靠的是探索和难度梯度。如果训练集里的提示词全是“写一封邮件”这类简单任务模型根本不需要探索直接把SFT阶段的策略复制一遍就能拿到满分。这种情况RL是无效的因为你没有给它需要思考的空间。评估集和训练集靠得太近。这个尤其坑训练时把评测集相关数据混进提示池了或者评测集本身出自同一分布RL很快就能“背下”这些题目的最优解形态看起来分数暴涨实际泛化能力没提升。MiMo-V2.6之所以能引发讨论是因为它在多种分布外评测集上的提升幅度都很大说明策略确实变强了而不只是记住了某几道题的答题模板。2. 拆解MiMo-V2.6背后的关键工程实践2.1 数据难度递进的提示集合是第一块基石很多人在RL阶段犯的第一个错误就是直接拿SFT的训练集来当提示池。这不是不行但效果非常受限。MiMo-V2.6给我的启示是RL阶段的数据构造重心要从“答案质量”转向“任务难度分布”。你需要的是一个难度呈阶梯状分布的提示集合。简单题占比不高中等题占大头难题和超难题也要有一定比例。为什么要这样设计因为RL的探索过程需要易到难的正反馈循环模型先解决一些简单的任务尝到奖励的甜头策略朝着正确的方向稳定一些然后面对中等难度的任务时它不至于完全摸不着头脑能在此基础上做局部探索最后难题用于激发模型的“极限能力”哪怕只能部分做对也会给训练带来有效的梯度信号。如果简单任务太多模型很快就收敛到一个局部最优后面再加大难度时策略已经固化了。如果一开始就全上难题模型生成很长一段有意义的内容最后因为一个小错误被给了零分这种全有或全无的稀疏奖励会让优化过程极其缓慢模型学不到什么有效信息。另外一个关键点是提示数据的多样性。同一个任务可以有不同的问法、不同的背景设定、不同的约束条件。这样模型学到的是“策略”而不是“话术”。我在实际配数据的时候还会特意加入一些带干扰项的题目比如一道数学题里故意写一个多余的背景信息或者多轮对话里前面几轮和后面几轮的主题看起来无关这些都是用来测试策略鲁棒性的好素材。2.2 奖励设计信号稀疏而明确才是关键奖励设计是整个RL流程里变数最大的地方也是最能拉开工程差距的地方。MiMo-V2.6这种以推理能力为主打的模型奖励一般走的是“规则奖励模型奖励”混合路线。规则奖励适合有标准答案的任务。数学题的最终结果对不对、代码能不能编译通过、答案的格式是否符合要求这些都是可以程序化验证的。规则奖励的优点是信号明确、不会漂移模型没法用花言巧语骗过它。缺点是只能覆盖有限的场景大多数真实世界对话任务并不存在一个标准答案。模型奖励就是用来补这块短板的。你让一个奖励模型给模型的生成结果打分这个评分可以基于人类偏好数据训练得到也可以直接用更强的模型来打也就是常说的AI反馈。模型奖励覆盖面广但缺点是信号可能会被奖励模型自身的偏好带偏而且容易被模型钻空子。我在实践中比较认可的做法是有标准答案的任务全走规则奖励没有标准答案的任务走模型奖励然后把两类任务按比例混合在同一个训练batch里。奖励信号设计的总原则是稀疏但不含糊。稀疏指的是不要求奖励模型给出细粒度到每一步的评分只对最终完整输出打分。像步骤分那类做法乍一看挺好实际很容易让奖励模型引入不可控的偏好。模型很快会把生成重点从完成目标转移到“产出一些让奖励模型觉得格式好看的步骤”上这是一种隐藏很深的reward hacking。2.3 训练配方一组反直觉但有效的关键参数RL阶段的训练参数和SFT很不一样很多直接把SFT参数搬过来用的人都会发现训练极度不稳定。下面给出一组我在类似规模模型上验证过的参考配置模型量级以7B到14B为主。配置项参考值备注基础学习率1e-6到5e-6比SFT低约10-20倍KL惩罚系数0.01到0.05对稳定性影响最敏感的参数单提示采样数4到8条样本不够信号噪声大太多算力吃紧训练batch大小128到256以“提示条数”计不是生成样本数平均生成长度512到1024 token太长训练慢太短学不到复杂推理训练步数200到500步增量训练场景下的推荐范围这里有两个反直觉的点值得展开说。学习率不是越大越好。很多第一次跑RL的人会想“要快速探索所以加大学习率”但实际RL场景下梯度本身的噪声就很大再叠加较大的学习率很容易导致策略在几次更新后突然崩掉。我见过一个模型在训练到第120步时loss还稳步下降第121步突然飞出十万八千里的案例。后来回溯就是学习率太大单次更新把旧的策略直接压没了。KL惩罚系数要“够用就行”。KL惩罚的作用是约束策略不要偏离参考模型太远避免模型为了刷奖励而说出一些离谱的话。但如果KL系数设得过高策略会被锁死在一个很小的邻域里探索能力被严重压制。经验做法是从0.05开始跑一个小实验观察rollout的reward均值和KL值的变化趋势如果KL一直维持在极低水平并且reward也不动那就是惩罚太重了需要往下调。另外一个关键配置是“参考模型”的用法。训练时你需要固定一份SFT阶段的模型作为参考不能拿更新中的策略自己当参考。这一点如果工程上搞混了KL惩罚项会失效训练没多久整个模型的输出就会变得乱七八糟。3. 实测评估与复现流程把三倍性能落实到自己手上3.1 先要警惕翻倍效果很可能来自评测集污染看了上面这么多估计你已经有点手痒想自己动手跑一轮。但动手之前我得泼一盆冷水大部分人在自建评测里看到的“暴涨”都是评测集污染造成的幻觉。最常见的是训练提示池里不小心混进去了评测集的题目。这个问题防不胜防因为公开评测集的数据在网上到处流传你从开源数据池里抓提示数据时很可能就抓进去了。更隐蔽的污染是“同主题污染”评测题被换了个说法但核心问题没变模型只要见过类似题目答题时就会占优势。这种污染连很多专业团队都很难清理干净。所以复现RL效果时最重要的不是把主要评测基准的分数刷上去而是留一份“分布外”的holdout集。我的习惯是一开始就冻结一份评测集包含三种类型官方评测集的相关题目、完全不在训练分布内的新题型、还有一份人工构造的对抗提示集。RL训练过程中不看这些数据只在每轮训练完成后做评估用。只有当三份评测集上都出现一致性上涨时我才确信RL真的有效而不是模型在背答案。另外强烈建议加入人工盲评环节。把旧模型和新模型的输出随机打乱让人去判断哪个更好统计偏好胜率。这个指标虽然贵但比任何自动化指标都真实。MiMo-V2.6那种“性能翻三倍”的说法其实也是在不同评测维度上综合统计的结果单看某个自动化评测集可能是翻倍甚至只涨了几十分之一。人工盲评能帮你从“机器觉得好”跨越到“人真的觉得好”。3.2 可复现的RL训练pipeline实操构建一套基础的RL训练pipeline并不复杂关键在于每一步怎么组织。下面给出一段训练循环的伪代码以及每一步对应的工作内容。for step in range(num_steps): prompts sample_batch(combined_prompt_set) # 1. 用当前策略模型批量生成多个候选输出 outputs policy.generate(prompts, num_return_sequences4) # 2. 对输出打奖励分 rewards compute_reward(prompts, outputs) # 3. 组内归一化消除不同提示词难度差异带来的信号偏差 advantages group_norm(rewards, groupprompts) # 4. 通过KL约束更新策略让模型不要偏离参考模型太远 policy.update(advantages, ref_model, kl_coeff)第一行的sample_batch就是从混合提示池里取一批提示词。提示池的构成在前面已经说过简单中等难题按一定的比例混合比如1:6:3。这里我特别强调中等题占比要最高因为这是模型处于“会做但不够好”的状态探索动作最容易产生有效收益。第二步生成候选输出时一个提示词生成多条候选这里生成数量直接关系到信号方差。只生成1条的话奖励的噪声会大到让梯度更新基本失效。生成8条以上信号确实更稳定但训练成本直线上升。4到8条是性价比比较高的区间。第三步组内归一化是RLOO和GRPO这类算法里的核心技巧。它把同一个提示词下所有候选输出的奖励分进行归一化然后比较哪些候选明显好于同组平均水平哪些明显差于平均水平。为什么要这样做因为不同提示词本身的难度不同难题的绝对奖励分通常更低直接拿绝对分比较会导致难题的梯度被抑制。组内归一化能够抵消这一部分难度偏差是我认为这类方法里最巧妙的一个设计。第四步更新策略时用参考模型计算当前策略和SFT模型的KL散度加到loss里作为惩罚项。这一步是防止模型为了极端刷高奖励而牺牲语言质量。整套流程跑下来快的话一个7B模型在8张A100上两三天就能见到效果。但别急着收工接下来才是真正花时间的部分打开日志看每一轮的奖励分布、KL曲线、生成样例判断模型是在朝好的方向走还是掉进了什么莫名其妙的坑里。4. 训练中的高频问题与排查技巧4.1 训练不收敛loss爆掉与KL震荡RL训练最常见的问题就是突然不收敛。现象往往是reward均值还在增长但policy loss突然飙升之后模型输出质量肉眼可见地变差。这个组合其实不是灾难而是一个明确的信号某个约束没有守住。我的排查顺序是这样的。先看KL值是不是在起飞。如果KL值在单步更新后涨了一个数量级以上那说明学习率太大或者KL惩罚系数太小策略一步迈过头了。把学习率降一半再试通常能解决问题。再看数据的reward分布是不是出了极端值比如某个提示词的奖励分比其他提示词高出一大截这种异常值会在组内归一化之后产生巨大的虚拟优势带动策略往一个非常偏的方向更新。遇到极端值最粗暴有效的办法是过滤掉这些提示或者设置一个reward cap。另一个更容易被忽略的问题是把参考模型用错了参考模型会跟着策略模型一起更新导致KL约束变成一个移动靶。训练日志上的表现就是KL值一直不高但生成的风格还是完全变了。排查方法是把参考模型权重固定住任何一步都不能更新它。4.2 奖励模型被“钻空子”reward hackingReward hacking做AI训练的应该都不陌生模型发现某种特定格式或套路总能拿高分于是疯狂输出这种套路哪怕内容已经偏离了目标。我在一次对话任务训练中遇到过模型在结尾加上“以上分析仅供参考”就能显著提高分数的情况很明显奖励模型把“谨慎语气”当成了“回答质量高”的隐含信号。排查reward hacking有一个笨办法但极其有效把每个训练批次里得分最高的几十条生成结果打印出来亲自读一遍。如果读着觉得内容空洞、格式华丽但信息量低那九成九是被奖励模型骗了。解决手段分三步走。第一清理奖励模型在打高分时的偏置特征比如特定句式、特定长度段把这些特征在训练数据中均衡化。第二增加规则约束禁止模型输出固定模板化的开头和结尾。第三也是最根本的降低单条输出的上限。你会发现当奖励分封顶之后模型反而开始关注内容质量了因为再堆烂话也刷不到满分。4.3 模型退化复读机、模板化与多样性塌陷RL训练步数拉长之后经常会看到一种现象模型输出开始变得千篇一律。同一个提示词让它写十个不同的版本十个版本的开头和结尾几乎一模一样只有中间部分在换词。这说明策略的熵已经塌了模型找到了一个看似稳妥的行为模式不再愿意探索其他路径。熵塌陷的根本原因是KL惩罚项和奖励分布之间的博弈失衡。如果你发现生成多样性急剧下降先把KL惩罚系数调大一点强制策略不要偏离参考模型太远。这听起来和之前说的“KL不要太大”矛盾但实际是两个方向的平衡训练初期KL太大压制探索训练后期KL太小模型就彻底放飞然后锁死在某个局部最优上。另外一个有效手段是减少单提示的采样数从8降到4这样模型不会那么容易把每道题的输入输出对应关系背下来。我还有一个个人习惯每个检查点保存时都自动生成一批固定提示词的样例输出攒成一个对照表。这样能直观看到模型在训练过程中输出的风格怎么变一句“从关键词堆砌变成了结构化输出”比任何指标都更能说明问题。4.4 算力焦虑RL训练的成本控制心得很多人不敢碰RL就是被算力劝退的。GRPO、RLOO这种去掉价值网络的方法确实能省不少显存但真正想控制成本还得从流程细节上抠。推理和训练的算力占比需要单独分析。在标准RL流程里生成候选输出rollout的算力开销经常是整个训练的好几倍。优化这一点可以做两件小事一是共享rollout一批提示词生成的候选输出可以被复用两次再丢弃虽然常用策略只能更新一次但可以把reward计算、KL计算这些后处理步骤都合并到同一个数据集上减少重复IO二是动态调整生成长度在早期训练阶段限制最大生成长度模型策略还不稳定时生成太长没意义完全是在烧显存。另外可以考虑用offload。把策略模型的梯度检查点、优化器状态、参考模型的权重都做CPU offload显存占用能降不少。我试过在一个单卡A100上跑7B模型的RL虽然速度慢一些但这套配置能跑通对没有多卡集群的团队来说很有价值。小步快跑原则也很重要。不要一上来就规划跑5000步。先跑50步看奖励分布有没有拉开、KL有没有失控、生成样例的质量变化趋势确认一切正常再扩容到500步。算力最贵的部分从来不只是显卡而是你拿显卡跑了一个错误配置的训练两三天之后才发现方向从一开始就错了。最后说点个人体会图像、语音、文本的模型训练我这些年都跑过RL这套东西是我见过最像“炼丹”的流程。它不像SFT那样数据对了结果就不会太差RL训练里每一步都有翻车的可能但一旦跑顺效果提升幅度往往超出你的预期。我最后分享一个小技巧。每次训练结束之后我会把所有检查点在20个“hard case”上的生成结果打印出来做成一个对应表。这些hard case是专门挑的、模型在SFT阶段几乎必错的题。通过这个表格我能很快发现模型是在第几个检查点开始学会自我纠错又是在哪个检查点开始变得过度自信、输出变长但废话变多。这个习惯帮我提前规避了好几次重大翻车比盯着曲线图直观得多。如果你正准备在自建的模型上尝试RL我的建议是先别急着上大模型。拿一个小尺寸模型、一个小规模提示池、一个明确可验证的规则奖励把整套流程从生成采样到组内归一化完整跑通再逐步加复杂度。这条路看起来慢但踩坑成本最低而且每一步都能学到东西。性能翻倍的案例很诱人但真正的收益来自你对整个训练过程的掌控力。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →