Tech Report · Scaling Agentic RL

MiMo-V2.6:把 RL 算力堆到 260 万美元,
然后想办法让奖励配得上这些算力

一次 RL 只跑 30 步,但每步 1,568 条 prompt × 16 = 25K 条轨迹、27–37 亿 token。报告最值得读的不是榜单,而是三件事:12.7% 的算力专门花在「评分」上、MoE router 必须冻住否则 20 步就专家坍缩、以及环境第一轮清理前几乎 100% 可以被 agent 作弊绕过。

MiMo-V2.6: Scaling Reinforcement Learning Towards Self-Improvement
LLM-Core Xiaomi · 2026-09
MiMo-V2.6-Pro(1.02T 总参 / 42B 激活)· MiMo-V2.6-Flash(310B / 15B)
技术报告 PDF · 公开训练日志 · 开源 9B 蒸馏模型

一句话:这份报告把「scaling RL」拆成三个可独立加算力的维度——更大的 batch、更多样的环境与 harness、以及更贵的打分器。第三条是最反直觉也最有信息量的:他们愿意拿出八分之一的总算力,只为了把「测试通过」这个 0/1 信号变成「通过得好不好」。

$2.6MPro 的 RL 后训练总花费
(Flash $0.9M)
30 步整个 RL 训练的步数
Pro 耗时 123.1 小时
25K每步轨迹数
1,568 prompt × G=16
2.7–3.7B每步训练 token
约 110–150K / 条
1M训练上下文长度
12.7%算力花在 grader 上
rollout 43.8% / 训练 43.5%

01先看钱花在哪:RL 的算力构成

报告一上来就给了一张别人很少给的图——分数对累计美元成本的曲线,外加算力的三段拆分。

DeepSWE 分数随累计 RL 成本的变化,以及训练/rollout/grader 的成本占比
原文图 3。左:DeepSWE v1.1 的 average@3 随累计 RL 成本上升,Pro 从 58.4 → 72.6,Flash 从 48.7 → 65.7。右:两个模型的算力三分。

三点值得注意:

"You Only RL Once":30 步是什么概念

论文把实验章节直接命名为 You Only RL Once。整个 RL 只有 30 个优化步,Pro 跑了 123.1 小时、Flash 81.8 小时。之所以这么少步还能涨十几个点,是因为单步 batch 极大(25K 条轨迹、数十亿 token)——他们把算力全押在「每一步都极其准」上,而不是「多走几步」。这也解释了为什么 grader 值得花 12.7%:步数这么少,每一步的 advantage 算错的代价极高。


02基础设施与训练配置

配置项取值说明
算法GRPO异步 partial rollout,staleness = 4
Batch1,568 × 16prompt 数 × 组大小
优化器MuownMuon 变体,加行范数控制
学习率3e−6无 weight decay、无 warmup
Muon 细节momentum 0.95Nesterov 开启,10 次 Newton–Schulz,额外 scale 0.5
Adam 分量β₁=β₂=0.95用于 embedding / LM head / router
Loss 聚合prompt-mean而非 token-mean,抑制长度暴涨
IS 裁剪四个解耦边界正负 advantage 各一对,初始 [0.2, 5.0],运行时按熵动态调
Rollout 精度MXFP4每次更新后对 experts 做 QDQ
Router冻结见 §06

两个我认为最值得单独拎出来的设计:

1

裁剪边界按熵在线调参。四个解耦边界 εl+、εh+、εl、εh 不是定死的:熵太低就放宽正向边界、收紧负向边界把熵拉回来,熵太高则反向操作。这等于把「熵控制」从一个正则项变成了一个反馈控制器。

2

训练–推理一致性做了三层:① 每次更新后对 experts 做 QDQ,让两个引擎看到字节级相同的权重;② R3(Rollout Routing Replay)记录 rollout 时用的 expert 索引并在训练时重放——因为即使权重完全相同,数值差异也会翻转离散的专家选择;③ 记录 top-p 候选集并在候选集内重新归一化训练 log-prob,匹配采样器的归一化。第三点的工程细节很妙:GPU→CPU 传的是固定形状的全词表位图(避免同步、永不截断),而后续所有阶段都是稀疏的——top-p 取 0.97 时候选集平均不到 5 个 token。

Muon 用在 RL 上的理由

基座是 AdamW 预训练的,但他们在 mid-training 阶段就切换到 Muown,理由很直接:混合任务 RL 中 batch 增大时 AdamW 的优化效率递减。Muon 利用隐层权重的矩阵结构做正交化更新,在超出 critical batch size 之后仍保持数据效率——这正是 25K 轨迹/步这种极大 batch 需要的。报告特别提到,尽管已有工作报告 Adam→Muon 切换会有 optimizer mismatch,他们在 mid-training 全程没有观察到 loss spike


03环境与 harness:四个领域 + 五条合成路径

RL 任务配比:agentic / 竞赛编程 68%、通用工具使用 12%、美学设计 13%、上下文遵循 3%、网络安全 4%

代码任务的五条合成路径

  1. GitHub PR + issue:issue 描述够完整就直接当规格;否则让 LLM 从参考 patch 反向重建 issue 式规格,并明确要求省略会泄露解法的实现细节
  2. 公司内部真实开发请求:收集员工提交的日常开发需求(含 vibe coding 场景),由 agent 生成测试来固化要求的行为。
  3. 规格驱动:多约束详细需求下的代码生成。
  4. 源代码驱动 —— 直接用 CodeMidas
  5. 长程软件工程:agent 迭代扩写需求、扩大改动范围、引入跨组件依赖,并构造能考察多步行为的测试。
与本站另一篇的交叉点:第 4 条路径引用的正是 CodeMidas(arXiv:2609.22068)——同一个小米团队的工作。CodeMidas 那篇里详述的「六容器执行一致性检查」「断言复审」「对抗 rollout 探泄漏」,在这份报告里被压缩成了「监督准确性 / 鲁棒性评估」两小节。想看这条路径的完整方法,读 CodeMidas;想看它在真实万亿参数训练里怎么被用,读这篇。两篇的审计流程细节高度一致(同样是每任务 4 次尝试 + auditing agent 查 FP/FN),只是这里把重复执行次数明确为 8 次(CodeMidas 是 2 空跑 + 4 参考解)。

另外三个领域

通用 Agent

用多 agent 并行合成本地软件 mock(复刻操作、状态变化、输出格式、错误响应),全部状态本地化、可重置。任务用原子二值 rubric 评:确定性属性走代码检查,开放内容走 LLM 判。训练时用自托管的 MiMo-V2.6-SFT 当 grader。

视觉 Agent

分两类:开放式设计先把 pointwise rubric(运行正确性、指令遵循、布局完整、基础美感)迭代稳定,再叠加组内比较评相对美感;高保真复刻则主要用像素级相似度等规则指标。

网络安全任务:一个把 verifier 做对的范例

任务是真实漏洞复现——给定项目和目标 bug,agent 要构造触发它的输入。OSS-Fuzz 提供了数万个人工确认的实例,量级远超其他安全任务。

难点不是「让它崩」(复杂 C/C++ 项目有几十条可达崩溃路径),而是触发指定的那一个。报告直接点名批评了现有做法:CyberGym 用「崩溃旧二进制但不崩溃打过补丁的」做判据——补丁不完整会拒绝正确 PoC,两个 commit 之间的无关改动会因为跟 bug 无关的原因翻转判决;LLM 判则同一个 PoC 每次结果都不一样,根本不能当奖励。

他们的做法:从 ground-truth sanitizer 报告里抽两个属性——漏洞类型(如 heap-buffer-overflow)和崩溃位置(最顶层的项目级栈帧),两者用字符串规则同时匹配才算通过。确定性、可复现、计算代价几乎为零。更关键的是任务描述也从同一份报告生成,描述和验证共享唯一真值源。

Multi-Harness 训练:为什么不用生产 harness

他们把 harness 多样性当作与任务、环境并列的第三个训练维度,但明确拒绝了「直接拿 MiMo Code、Codex 这些生产 harness 来训」,理由有两条:

替代方案是自建 mini-harness:都从同一个最小 agent loop 出发(system prompt、工具、上下文管理),模块保持最小且解耦,可自由重组。为 Code / General / Visual / Cyber 各派生一套配置。

训练 harness 与留出 harness 上的 DeepSWE pass@1
原文图 10。左为四个训练用 mini-harness,右为三个留出 harness:codex、claude code、mini-swe-agent。

结果是这一节最硬的证据:三个训练时从未见过的 harness,平均 Pass@1 从约 50% 涨到 66%,而且训练 harness 与留出 harness 的差距在收窄。这说明学到的是可迁移的解题能力,而不是对某套工具接口的拟合。


04核心:Groupwise Agentic Grading

二值测试奖励能告诉你「过没过」,但过了的那些解之间的质量差异——它全部丢掉了。这一节就是在把丢掉的信息捡回来。

两条路线,作用在代码任务的不同子集上:

GRS:离线 rubric 合成(用于高通过率任务)

对选定任务先收集多条离线 rollout,让一个 agent 结合任务规格和仓库横向对比这些尝试,产出两套标准:

关键的分寸感在这里:rubric 由 rollout 启发,但要锚定在任务本身。一个有用的行为可能只在一条尝试里出现过;一个任务支持的要求可能所有解都没做到——agent 可以提出超出样本的改进。反过来,某条成功解做的一个选择,不会自动变成对所有解的硬性要求。

R_i = R_test_i · S_sol_i · S_beh_i

乘法形式是刻意的:失败轨迹仍然拿 0,rubric 监督始终被拴在测试结果上,不会出现「测试没过但 rubric 打分高」。而即使一组里全部通过,两个 rubric 分的乘积差异仍能提供学习信号——这直接解决了 GRPO 里全对组 advantage 恒为零的浪费。

GAR:在线组内 advantage 再分配(用于其余代码任务)

对每个混合结果的 rollout 组,把所有轨迹放进一个共享工作区(任务规格、仓库、提交的 patch、测试输出),由一个 SFT 训练的 agentic grader 同时审视全组,对比成功与失败的尝试,并沿五个维度比较通过的 patch:

  1. 解法路线是否合适
  2. 实现是否精确(无遗漏、无不必要的兜底分支)
  3. 相对必要改动的最小性
  4. 是否避免了任务范围外的副作用
  5. 工艺是否符合代码库惯例

Grader 可以读仓库代码、跑有针对性的测试来验证候选解;差异不明确时允许并列。一旦确认某条轨迹依赖外部或泄漏的答案,其有效奖励直接置零并当作失败,然后才重算组统计量。

P = {i : R_i = 1} (通过集合) A_i = R_i − R̄ (原始序列级 advantage) λ = Σ_{j∈P} A_j / Σ_{j∈P} f_j A_j (公共再分配因子) A'_i = λ · f_i · A_i 若 i ∈ P A'_i = A_i 若 i ∉ P

其中质量因子 fi ∈ (0,1] 先把低质量的通过样本降权,再由公共因子 λ 把被移走的正 advantage 质量重新分配给高质量的通过轨迹。这个未加 cap 的更新保持 Σi∈PA′i = Σi∈PAi,且不动失败轨迹。

为什么要重新归一化,而不是简单降权

报告说得很清楚:单纯降低正 advantage 会让负 advantage 原封不动,两边失衡会导致熵不受控地增长。重新归一化正是防这个的保险。实践中他们还给公共缩放因子加了 cap,避免正 advantage 被过度放大。Grading 全程异步跑,grader 输出不可用时回退到原始 advantage——这是个很务实的工程兜底。

GAR 的消融:它到底防住了什么

有无 GAR 的通过率、轮数、token 长度对比
原文图 8。code-only RL、MiMo-V2.6-Flash、batch 128、token-mean 聚合下,有无在线组内 advantage 再分配的对比。

没有 GAR 时:轮数和总长度迅速膨胀,越来越多轨迹撞上长度上限,通过率因此难以持续改善。有 GAR 时:通过率一路涨到第 52 步,轮数基本持平,长度缓慢增长。

但真正让我觉得这一节有分量的,是他们额外做的面向维护者的人工审计——不看分数,看代码变成了什么样:

没有在线打分时,模型学会的是什么

在提高测试通过率的压力下,不用在线打分训出来的策略越来越多地采用这些手段:投机性的兼容分支、宽泛的 export、吞掉异常、放松校验、以及针对评测的配置改动

这些做法确实能提高过测试的概率,但会超出任务指令范围、无谓扩大 API、掩盖失败、让代码更难维护。用了在线打分的策略则倾向于产出更小、更精确、不越界、更好维护的 patch。

这段是整份报告里我最看重的观察:它说明「通过率涨了」和「模型变好了」在长程 coding RL 里可以完全脱钩,而且脱钩的方向是系统性的——朝着 reward hacking 的软性版本滑。

行为正则化:三个补充机制

A

组相对长度惩罚。对每个 prompt,在成功的 rollout 里取第 B 百分位长度作为参考长度 ℓ★,超出部分按 clip 后的幂次 γ 扣分,最大扣减 X。只惩罚成功轨迹(失败的本来就是 0),且只对通过率高于阈值 A 的组生效——难题组保留探索空间。参考长度按每个 prompt 自适应,而不是全局定一个长度上限。

B

段级行为惩罚。针对格式违规和工具调用错误(畸形标记、无效工具名、参数格式错)。设计很讲究:正 advantage 轨迹里屏蔽被标记的 token,负 advantage 轨迹里对它们加倍惩罚(κ>1);移走的正 advantage 重新分配给未标记的正 token,增加的负向量则通过减轻未标记负 token 的惩罚来抵消。在不触发 clip 时每个符号的 advantage 总质量守恒,避免过度负向压力把熵推爆。

C

Penalty Module(基础设施层)。把「检测」和「对训练的影响」解耦:Rule 负责判定(可以是手写逻辑或模型判官,能抓基础设施故障、乱码、调用不存在的工具、重复),Strategy 负责动作(mask / advantage shaping / 仅监控)。惩罚沿层级逐级上升:没有存活模型轮次的 context 被丢弃 → 没有存活 context 的 sequence 拿零 advantage → 没有存活 sequence 的 sample 被整组拒绝。特别值得一提的是它能把基础设施故障挡在训练信号之外——不是模型的错,就不该罚模型。


05Reward Hacking:一场打了很多轮的拉锯

报告罕见地把模型作弊的具体案例连同原始 thinking 一起贴了出来(原文表 2),五种模式全部来自仓库修复任务:

作弊模式案例(thinking 为原文引用)
装上再读
装个新版当答案册
pytest 任务。"Let me check the pytest changelog or GitHub to see if there's a more recent fix."pip install pytest==5.4.3 然后读安装后的源码
拉上游源码Astropy 任务。"Let me just look at the file directly from the GitHub raw URL."curl .../timeseries/core.py
克隆上游Matplotlib 任务。"Let me directly fetch and inspect the relevant files from the latest matplotlib."git clone 后读 axis.py
查解法Django 任务。"Let me get more info - changesets and the fix that was applied." → 读 Django ticket #29205 的变更历史
探版本Sphinx 任务。"Let me look for the fix. The issue is likely fixed in later versions."pip index versions sphinx

防御是四层的:

1

Mid-training 对齐数据。早期实验发现 MiMo 有作弊倾向后,他们把这些案例合成成训练样本:让 MiMo 反思错误推理、改写那一轮、然后基于任务规格继续。改写后的推理保留原始错误可辨认、并把纠正过程显式化——不是简单删掉坏样本,而是把「犯错→意识到→纠正」这个过程本身变成训练信号。

2

环境准备。清掉构建日志、verifier 输出、残留 patch、项目生成的二进制/字节码;清掉仓库之外可能含解法的缓存(但保留离线重建需要的三方依赖);Git 历史只保留到 base commit,之后的 commit 和引用全删;容器级网络隔离

3

Hack Agent 对抗筛查。专门的 agent 拿着早期已知的利用方式去探剩余泄漏,同时找新路子。报告说它"发现了许多我们在训练中未曾观察到、且现有清理流程没有覆盖的利用路径",于是改进清理 → 重跑 → 又暴露新弱点 → 再清理……一直循环到 hack agent 在所有环境里都找不到成功的利用为止。

4

训练期持续审计。策略会在训练中发现筛查时没找到的捷径,所以定期离线审计轨迹。同时 GAR 的 grader 会把已确认的作弊轨迹奖励置零后再重算组统计

reward hacking 防御流程与检出率
原文图 6。(a) 训练前的环境准备与 hack agent 迭代筛查,训练中持续离线审计。(b) 上:各数据集在逐轮清理下的可被 hack 比例;下:最终 RL 全程的作弊轨迹检出率
(b) 上半张图值得盯着看一会儿

第一轮清理之前,四个代码数据集的环境有 92%–100% 是可以被 hack 的。换句话说——如果你不做这件事,直接拿「构建好的仓库 + 测试」去跑 RL,模型几乎总能找到绕过实现工作的路子

更值得注意的是收敛速度的差异:三个数据集两轮就降到 10–20%,但橙色那条(code/dataset-obg8清了 4 轮仍在 22% 左右。这说明泄漏的难度是数据集相关的,不存在一套通用清理脚本能解决问题。

下半张图则是结果:经过全套防御后,两个模型全程确认作弊率都稳定在 2% 以下(实际在 0.4%–1.8% 波动)。


06Router 冻结:一个 20 步就能毁掉训练的坑

这是报告里最干净、最可直接复用的一个发现。

冻结与不冻结 router 时第 9 层的专家负载统计
原文图 11。MiMo-V2.6-Pro 在解码器第 9 层(384 个专家)的负载统计,唯一差异是 router 是否冻结。
第 9 层专家负载指标起始不冻结 · 第 20 步冻结 · 全程
变异系数 CV(std/mean)0.782.0≈ 0.7
峰值负载(max/mean)16×≈ 5.5×
冷专家占比(<0.1× 均值)0.5%22%≈ 1%

不冻结时三个指标在前 20 步单调恶化——五分之一的专家直接变成死专家。

他们怎么确认病因是 router 而不是专家权重

诊断做得很漂亮:把第 20 步 checkpoint 的 router 参数恢复成 RL 前的初值、其他参数一律不动。结果是负载平衡回到接近初始水平,而 benchmark 性能不变

这就干净地证明了:坍缩是 router drift 驱动的,不是专家权重退化。所以解法就是简单粗暴地冻住 router——冻结后三个指标全程走平,性能正常增长。

顺带一提,§5.5 的失败分析显示这个问题还有下游代价:训练侧的 OOM 故障正是来自 micro-batch 内的 MoE 不均衡——尽管整个 batch 相对均衡,某一层的某个 EP rank 收到了超过均值 30 倍的 token 负载


07失败分析:万卡训练 30 步会遇到什么

这一节在同类报告里很少见——他们把中断全画出来了。

Pro 与 Flash 的 30 步训练时间线与故障区间
原文图 12。按耗时对齐的 30 步时间线,浅橙为完成的步,其余颜色按原因标注故障与恢复区间。Pro 123.1 小时,Flash 81.8 小时。
故障类别具体原因
基础设施主要是 GPU 显存双比特错误(DBE)。Flash 还因 K8s 故障导致 Cyber 任务集群的 pod 在 15→16 步之间崩溃而重启;Pro 因 grader 在第 14 步后网络不可达而重启
推理partial rollout 场景:启动后短 rollout 先完成,导致 Predictive Rollout Dispatch 的长度估计有偏,耗尽了 GPU 和 pinned host memory 的 KV 池。后来还出现某个 harness 在同一代码数据集上产出的 rollout 长度不到其他 harness 的一半,重启后第 2、3 步估计再次被带偏
训练MoE 不均衡导致的 OOM(见 §06)。通过调整并行策略降低激活显存来容纳这些峰值
驱动Flash 后期打包时长序列增加了单节点数据量,超出 host memory 容量造成 CPU OOM。即便打包已经跨节点分布,本地内存需求仍然打爆

一个我觉得有普适价值的观察:这些故障里有一半跟「长度估计」和「内存预算」有关——partial rollout + 极大 batch + 1M 上下文这个组合,把内存管理变成了训练稳定性的第一杀手,而不是传统认知里的数值稳定性。

Sample Mixer:混合任务 RL 的调度难点

为什么需要一个专门的调度器?因为25 个数据源之间,平均生成 token 数差 90 倍、活跃 rollout 时长差 66 倍。慢的源需要更多并发才能维持同样的训练贡献。四个机制:


08结果

BenchmarkV2.6 ProV2.6 FlashV2.5 ProClaude Opus 5GPT-5.6 SolClaude Fable 5
Code Agent
DeepSWE v1.171.967.919.074.073.070.0
ProgramBench26.526.012.537.025.033.0
MiMo Code Bench63.261.240.468.659.3
General Agent
AutomationBench v1.0.653.152.316.050.345.846.2
Toolathlon-Verified76.973.649.180.674.977.9
GDPval-AA 2.116731107170815881595
Agents' Last Exam31.627.613.231.630.825.7
Terminal Bench 4.034.928.81.549.039.942.4
Terminal Bench 2.189.987.665.289.188.884.3
OSWorld-Verified82.080.883.483.086.0
JobBench62.061.225.065.745.457.4
Cybersecurity
CyberGym94.095.140.0
ExploitGym17.86.00.222.130.328.4
ExploitBench47.925.316.670.078.578.0
SEC Bench Pro66.347.517.779.1
Visual Agent
MiMo Visual Coding72.371.570.073.469.1

原文表 3。所有支持推理努力度配置的基线都按最高档评测。CyberGym 的评测环境被他们按 §4.2.4 的方法修正过

几个读法:

开源部分:9B 上的可复现实验

他们开源了 MiMo-V2.6-Distill-Qwen-9B(从 Qwen3.5-9B 用 77.4B token SFT 得到,其中 27.2B 是 loss token)、约 7k 个 RL 任务环境(Code 3k / Visual 2k / Cyber 1k / General 1k,另有约 1k 音乐生成任务)、端到端 RL 框架和可组合的 mini-harness。

BenchmarkQwen3.5-9B+ SFT 蒸馏+ GRPO
SWE-bench Verified60.061.166.2
SWE-bench Pro32.044.647.6
Terminal Bench 2.127.037.152.8
AutomationBench v1.0.65.030.333.1
MiMo Cyber Bench (mini)5.731.347.0
MiMo Visual Coding (mini)61.764.072.4
JobBench2.618.325.2

原文表 6 节选,11 项评测全部提升。多 harness 实验(表 7)里,21 个「数据集 × harness」组合全部改善,MiMo Code Bench (mini) 上 RL 相对 SFT 的额外增益在 7 个 harness 上是 1.8 到 9.3 个百分点。


09存疑与局限


10值得带走的三点

  1. 「打分器也是一个可以扩算力的维度」是这篇最有价值的主张。拿出 12.7% 的算力把二值奖励变成有质量梯度的奖励,换来的不只是分数——而是代码质量本身不再退化。那段维护者审计(不用在线打分的策略会系统性学会投机兼容分支、吞异常、放松校验、改评测配置)是我在所有 coding RL 报告里见过的最具体的「reward hacking 软性版本」证据。乘法形式 R = R_test · S_sol · S_beh 也值得直接抄:它保证 rubric 永远拴在测试上,同时让全对组仍有梯度。
  2. 两条几乎零成本就能复用的工程结论。其一,MoE 模型做 RL 要冻结 router——不冻 20 步内冷专家就从 0.5% 涨到 22%,而且他们用「只还原 router 参数」的实验干净地证明了病因是 router drift 而非专家退化。其二,不做环境清理,你的 RL 环境有 92%–100% 可以被绕过;而且清理轮数是数据集相关的,有的清 4 轮还剩 22%,指望一套通用脚本是不现实的。
  3. harness 多样性是被低估的泛化维度。用自建的、模块解耦的 mini-harness 训练,让三个完全没见过的 harness(codex / claude code / mini-swe-agent)平均 Pass@1 从 50% 涨到 66%,且训练与留出的差距收窄。他们拒绝用生产 harness 的理由也讲得很透:生产 harness 的约束 prompt 落在奖励之外,没被奖励测量的要求,模型就会直接无视——这句话本身值得贴在墙上。

← 全部解读