让代码"跑得快"也能被强化学习出来
你有没有这种感觉:模型写的代码在功能上明明是对的,但一执行就慢得像老牛拉车?前脚刚让 LLM 通过了所有测试,后脚看 runtime 就血压飙升。这事困扰工业界不是一天两天了——以至于 Anthropic 的 Claude 4.5 Sonnet 在 SWE-fficiency 上能修对 81% 的真实仓库问题,但只拿到了 4.1% 的专家速度提升。这个"对 vs 快"的鸿沟,才是真正卡住代码 LLM 落地的硬骨头。
今天聊的这篇论文 arXiv 2607.25970("Reinforcement Learning for Code Optimization",作者来自 Meta FAIR Paris 的 Pierre Chambon、Kunhao Zheng、Juliette Decugis、Benoit Sagot、Gabriel Synnaeve,其中 Synnaeve 也是 CWM 的核心贡献者)想要正面回答一个问题:当执行时间作为奖励信号直接喂给 RL 时,到底为什么训练会失败;以及怎么才能让它 work。
核心摘要
一句话:让模型"写对"已经被 RL 解决了,但让它"写快"不是简单加个 timing 奖励。论文拆解出三个环环相扣的失败点——沙箱抖动、奖励错位、GRPO 不稳,并给出对应的可学习链路。最终在 DMC-Optim 上让 CWM 32B 的 top-50% pass@1 从 30.7% 涨到 50.4%,top-30% 涨了 125%(相对值),且纯正确性几乎不掉。
值得读吗?非常值得。这不是"换个数据集再跑一遍 GRPO"那种工程凑数工作,它把"为什么 timing 难学"这件事掰开揉碎,给出了一套从数据、沙箱、奖励、训练器到评测的完整工程范式。125 页的体量里干货密度不低,对在 RL/Agent/代码领域做工程的人有直接借鉴价值。
论文基本信息
- 标题:Reinforcement Learning for Code Optimization
- 作者:Pierre Chambon, Kunhao Zheng, Juliette Decugis, Benoit Sagot, Gabriel Synnaeve
- 机构:Meta FAIR Paris
- 链接:https://arxiv.org/abs/2607.25970
- 日期:2026-07-28(v1)
- 体量:125 页
- 模型:Qwen 2.5 7B/32B base + CWM 32B SFT
- 数据集:自建 DMC-Optim(2,723 清洗题,1,302 可时序打分),评测 LCB 出域
- 训练算力:7B 用 8 节点 H100 跑约 1 天,32B 用 32 节点跑约 1.5 天
一、动机:为什么"加个 timing 奖励"看上去理所当然,却总是失败
写代码的 RL 训练套路已经相当成熟:模型生成程序,跑测试,过了就有奖励,没过就没奖励。这就是 RLVR(Reinforcement Learning with Verifiable Rewards)的标准范式。DeepSeek-R1 用它把数学题、代码题的成绩拉上一大截。
要把这套范式搬来学"快",最朴素的方案就是给已经通过测试的解加一项:跑得越快奖励越高。但论文做了一个"负面 baseline"——直接这么做,效果几乎纹丝不动:在 Qwen 2.5 7B 的 DMC-Optim 上,标准 RLVR 正确率(pass@1 在 p100)是 43.5%,一旦加 timing 奖励,p50(要求排进人类解的前 50%)只从 18.0% 涨到 18.9%、18.0%,几乎不增。所以 reward 看上去是加上了,模型其实没在学。
为什么?我的第一反应是"奖励稀疏",但论文把这个问题剥得更细:
- 测试本身不够"区分"。原始 DMC 的题配的测试平均执行 0.088s,p95 也才 0.145s——几十毫秒级别的扰动就足以让"快慢"判断失效。奖励信噪比太低。
- 执行沙箱是抖的。本地训练 worker 同时跑推理和代码执行,CPU 抢占严重;同一份代码重跑两次,p50 排名能漂 41 个百分位点。
- GRPO 在稀疏/带噪奖励下不稳。当所有 16 个采样要么全对(全 1)要么全错(全 -1),整个 group 的 advantage 全为 0,这种"零优势组"在 timing 场景下能占到 40%–50%。
这三条任意一条断掉,整条链就废了。这其实也是 LLM 强化学习里被反复忽略的工程现实:写代码"对 vs 错"是二值的、噪声低、可重复;写代码"快 vs 慢"是连续的、噪声高、依赖沙箱。这两类 reward 的物理意义完全不同。
所以这篇论文真正干的事,是把 timing 信号当作一个需要从头设计的学习对象——数据要换、沙箱要换、奖励要换、训练器也要换。
二、方法:三段链路让 timing 变得可学
论文把整条链路分成三段:测量→奖励→训练器。每一段都是独立可替换的工程模块。
2.1 测量段:造一个能稳定排名的沙箱
第一步是造题。从 DeepMind Code Contests 12,275 道原始题里筛出 2,723 题(DMC-Optim),其中 1,302 题有足够的耗时离散度(所谓"duration filterable"——同题不同解的耗时 robust CV ≥ 0.3),可以做排名。
光有题不够,测试也要重写。原始测试太短、太弱:写完程序跑过去 0.1 秒,模型偶尔 O2 优化一下省下 5 毫秒,奖励信号早被噪声吃了。论文团队加了一波大输入的"optimization tests",并做了人类正解/错解的交叉验证,把误判率压到可接受水平。优化测试的 p95 耗时从 0.145s 提到 1.296s,p99 从 0.463s 提到 3.71s——这才是"能看出快慢"的时间尺度。
第二步是换沙箱。本地 worker 没法给出稳定 timing,于是单独搭了一个远程 CPU 沙箱(论文里叫 CES)。这一换效果立竿见影:本地 vs CES 之间的耗时拟合在 36,660 对样本上 cross-validated R² 都是负的,根本映射不过去。换成 CES 后,timing 与 reference 之间的 Spearman 还能漂移,于是又加了一个仿射校准(affine service-state drift correction),把"已存 vs 新跑"的相关性从 0.54 拉到 0.96。
这一步看上去"基础设施",其实是最容易被忽略的。如果不把沙箱搞稳,后面所有 reward shaping 都是空中楼阁。
2.2 奖励段:把 timing 变成可学习信号
timing 数据有了,怎么变成一个 RL 能用的 reward?
论文把"在 RL 训练中,timing 约束从哪里进入执行流程"分成三类:
- Pre-execution(前置过滤):执行前先选测试。比如按人类参考解的平均耗时筛掉短测试,或按字符长度筛掉弱测试。
- Intra-execution(执行中限时):在测试运行时加 timeout,超过就判错。比如给个绝对时间上限(0.5s、2s),或者按人类最慢解的某个分位数卡。
- Post-execution(执行后排名):跑完不淘汰,再把候选解插进人类参考池里排名,按分位打分。
每个家族下面又有 2–3 个子家族和一堆参数化(绝对 vs 相对 timeout、p20/p50/p80 分位等),组合起来几十种环境。直接上 GRPO 跑一遍要 8–32 节点 H100 跑若干天,根本跑不完所有组合。
论文的关键工程是:先用一个离线模拟器筛掉明显不行的环境。所谓离线模拟器,思路很简单——把模型的 16 个采样替换成"人类解按某个质量分位随机抽",把 CES 调用替换成预存的耗时,跑出"采样越强→奖励越高"的曲线。这条曲线的两个特征就能预测最终表现:
- AUC(曲线下面积)——曲线整体在 0–1 之间的位置,区分"太稀疏/太饱和"
- Steepness(斜率 \(S=a/(1+|a|)\))——曲线从弱到强的上升速度,区分"太平"还是"太陡"
下图就是论文里那张离线模拟器散点图:

图:每个点是一个 RL 环境配置,x 轴是模拟曲线的 AUC(奖励 level),y 轴是斜率 Steepness。颜色和形状区分 pre/intra/post 三大家族。Steep/Balanced 这一格是最理想的(奖励曲线陡且不饱和),例如 Post-exec 的 Per-test Percentile ranking p50 配置;Flat/Sparse(如相对 timeout)几乎学不到东西;Saturated 的曲线则全是高分,模型拿不到差异信号。最终在 18 个 Qwen 2.5 7B 试跑中,斜率/对角线偏差与严格 p30 性能的相关性都在 r=0.7 以上,曲线噪声反而无相关性(r=-0.002)。
这个筛选器非常实用——它让你能先在 CPU 上花几小时筛掉 80% 的废配置,再把 GPU 时间留给真正可能 work 的几个。后面章节里那些能跑出 31.3% p50 pass@1 的环境,几乎都是被这张图"提前挑出来"的。
2.3 训练器段:让 GRPO 在稀疏/带噪奖励下不崩
即使环境选对了,timing reward 仍然比标准 pass/fail 稀疏得多,也噪声大得多。论文对标准 async-GRPO 做了几处关键手术:
- 同 prompt rollout 数加到 16,训练 batch 加大。代价是每个 optimizer step 看到的题数变少,但梯度估计稳了。Qwen 2.5 7B 上"零优势组丢弃率"减少,纯正确性提升 10–25%,p50 优化性提升最多 35%,p30 提升最多 60%。
- 去掉了 GRPO 优势除以组内 std 这一步(参考 Dr. GRPO 的分析)。原因:在 timing 场景下"模型找不到优化窍门的题"和"模型找到窍门但单次波动大"应该被不同地对待,std 归一化会拉平这种区分。
- 用 token-weighted prompt mean 当 advantage baseline,loss 除以固定 token horizon N=32768,而不是每个 rollout 的真实长度。这避免了"长错误轨迹被欠罚、成功长轨迹被欠奖"的偏置。
- worker/trainer 比例调温和 + 硬过滤过老的 context(>30 optimizer step 的扔掉)+ 不开 replay buffer——避免不同沙箱状态下收集的 reward 被混在一起比较。
这些改动在论文里被统称为"adapted GRPO"。看着像工程调参,但其实是 timing RL 的关键护栏。
2.4 奖励形状的最后一击:binary collapsed reward
光改环境还不够,reward 怎么把 correctness 和 optimization 这两个量结合,直接决定训练能不能走通。论文比较了五种组合:
| 奖励形式 | 直觉 | 实际效果 |
|---|---|---|
| Collapsed binary | 对=+1/错=-1,再叠一个"快"二元门 | 各分位最稳,p50/p30 全面领先 |
| Two-gate binary | 正确门 + 优化门分开判定 | 接近 collapsed binary |
| Additive blend | 把正确和优化 reward 加权求和 | p100 纯正确性掉 8–17%,p30 仅小幅涨 |
| Multitask | 两个目标同时训,交替优化 | 同样困在 Pareto 前沿 |
| Optimization only | 只奖励快,不奖励对 | 模型直接崩,pass@1 归 0 |
| Continuous (50/50 等) | 用 0–1 连续分替代二元门 | 比 binary 差,分位越严越拉 |
关键发现:collapsed binary reward(正确就+1、错就-1,在正确的前提下再用二元门卡"够不够快")在所有环境上都是 Pareto 最优。"加性混合"那种看似更柔和的 reward 反而最糟——因为快但错的代码也能拿到部分奖励,模型就开始走捷径,丢掉正确性。"只优化不奖励正确"更夸张,pass@1 直接掉到 0。
这跟 DeepSeek-R1 当初在数学题上的发现一脉相承:简单二元奖励反而能避开 reward hacking。论文里也明确致敬了这个观察。
三、关键结果:哪几个数字能让你信服
3.1 主结果:Qwen 2.5 7B 上的环境扫描
先看 7B 上的完整环境扫描表(论文 Table 3):
| 训练环境家族 | 配置 | p100 | p50 | p30 | p10 |
|---|---|---|---|---|---|
| Standard RLVR | — | 43.5 | 18.0 | 7.7 | 1.9 |
| + 优化/更强正确性测试 | MC + opt tests | 46.9 | 20.6 | 9.3 | 2.7 |
| + Pre-exec(绝对时长过滤) | τ=2s | 46.9 | 29.2 | 17.4 | 5.7 |
| + Pre-exec(字符长度) | ≥10M | 45.6 | 28.6 | 16.8 | 5.5 |
| + Intra-exec(ranked worst) | from p80 | 45.0 | 29.3 | 17.7 | 6.0 |
| + Post-exec(per-test percentile) | top 30% | 46.2 | 31.3 | 19.1 | 6.0 |
| + Post-exec(leaderboard) | Two-gate bucketed | 47.1 | 27.5 | 15.5 | 5.1 |
读这张表要分两栏看。p100 是纯正确性,所有优化 RL 配置基本不损失(43.5%→46–47%);p30/p10 是严苛的"既要写对又要写快"指标,最强的 post-exec top 30% 配置从 7.7% 飙到 19.1%(p30,相对涨幅 148%),从 1.9% 飙到 6.0%(p10,相对涨幅 215%)。
几个有意思的发现:
- 直接加 timing 奖励(基线那行)几乎没用:p50 从 18.0 → 18.9,加了个寂寞。
- 仅"换更难的测试"也有用:p50 从 18.0 → 20.6,说明数据本身就是瓶颈的一部分。
- 相对 timeout 那一族基本都炸了:p100 掉到 31–35%,典型的"为了快牺牲对"。
- post-exec 的 per-test percentile 家族在严格分位上最强,但 top 80% / top 50% 这些"宽松"配置也能 work;pre-exec 绝对时长过滤 τ=2s 几乎和 post-exec top 50% 持平。
3.2 三模型迁移:Qwen 2.5 7B/32B + CWM 32B
把 Qwen 7B 上筛出来的最佳环境搬到 32B 和 CWM 32B 上:
| 模型 | 配置 | p100 | p50 | p30 | p10 |
|---|---|---|---|---|---|
| Qwen 2.5 7B | Standard RLVR | 43.5 | 18.0 | 7.7 | 1.9 |
| Post-exec top 30% | 46.2 | 31.3 | 19.1 | 6.0 | |
| Qwen 2.5 32B | Standard RLVR | 54.8 | 21.1 | 9.4 | 2.4 |
| Post-exec top 30% | 55.7 | 39.6 | 24.2 | 8.5 | |
| CWM 32B | Standard RLVR | 69.8 | 30.7 | 13.7 | 3.3 |
| Post-exec top 30% | 70.2 | 50.4 | 30.9 | 9.8 |
最关键的几个对比:
- CWM 32B 的 p30 从 13.7% → 30.9%,相对涨幅 125%;p10 从 3.3% → 9.8%,相对涨幅 197%。
- p100 纯正确性几乎不动(Qwen 7B 43.5→46.2,Qwen 32B 54.8→55.7,CWM 32B 69.8→70.2)——这是整篇论文的核心承诺:能涨优化性而不丢正确性。
- 三种规模的"涨"曲线形状一致,没有哪个小模型能 work 但大模型反而崩的情况。这对工程同学挺重要——意味着你可以在 7B 上做消融,结论大概率能迁移。
更直观的"分位扫描"图:

图:左图是 10k RL 步后各配置在 p100→p10 上的绝对 pass@1。灰线 Baseline 几乎是所有曲线里最低的,红线(Post-exec top 30%)从头领跑到底。右图是 1k→10k 步的相对提升;可以看到有些环境(绿线一族)在 p50/p30 几乎不增长——它们早期就吃到红利了,但后期不 work;只有 collapsed-binary + post-exec 那一组能保持全分位的稳定提升。
3.3 出域评测:LiveCodeBench
LCB 是另一个独立维护的代码基准,特点是它的题不会出现在训练集里,且原始测试很短、不能稳定做 timing 评测。所以这里不用 pass@p50 那种硬指标,改用 speed win rate(采样 20 个解,取中位数速度 vs 基线):
- Qwen 2.5 7B 配 τ=2s pre-exec:WR_m = 69.5%(中位速度胜率)
- CWM 32B 配 τ=0.5s pre-exec:WR_m = 83.0%(最高)
- CWM 32B 配 post-exec top 30%:WR_m = 82.9%
翻译成人话:采样 20 次,标准 RLVR 模型和优化 RL 模型各自取中位速度,83% 的概率优化版更快。即使在去掉自己最好的那个解(取"最差"那个解的速度,WR_b),CWM 32B 仍然能赢 66–68%。这说明优化能力真的内化到了策略里,不只是"偶尔抽到一个好解"。
3.4 训练×评测交叉矩阵
另一个有意思的视角是 train-by-eval 交叉矩阵:

图:行=训练环境,列=评估环境。颜色越亮(黄)pass@1 越高。最右几列(Post-exec Perf ranking)几乎所有训练行都在 30%+,而 Intra-exec Rel timeout 那几列几乎所有行都跌到 10% 以下(深蓝)。一个意外发现:post-exec 和 ranked-worst 两种评估指标的训练排序几乎完全一致(Spearman ρ ≈ 0.995)——意思是你拿哪个评估去评,得出的结论高度一致。
这图直接告诉读者:不是所有评估指标都"等价"。post-exec ranking 既能拉开训练配置之间的差距(family-avg spread = 13.5 分),又能在参数扫描时提供足够宽的难度梯度(p100→p10 大约 40 分)。而相对 timeout 评估的问题在于:参数一变全局难度都变了,但对训练配置的区分力只剩 2.3 分——它只是把所有人都变难,并没有真正排出好坏。这种"评估器诊断"的方法论我个人很喜欢,比"我跑了一个新指标"更有信息量。
四、模型到底学到了什么:judge 拆解
数字涨了,但模型到底学会了什么类型的"快"?论文用 GPT-OSS-120B 做了一个 judge study,把每个 problem 的"模型胜出解 vs 对照解"按优化类型分类:

图:每行是一种优化类型,每个类型下面有 3 条线——Optim-RL vs RLVR(蓝)、Human vs RLVR(紫)、Human vs Optim-RL(红)。左侧数字是该侧"对方更快"的占比,右侧是"我方更快"的占比。N=174/177/154 是可分类 pair 数。
几个值得品味的数字:
- I/O 优化:Optim-RL 大胜,47% 的胜场是"我做了更好的 I/O"。这个类别它甚至能赢人类(12%)。
- 常数因子调优(constant-factor tweaks):34% 的胜场是"避免了中间分配、紧循环边界、提前终止"这些小技巧。这是 Optim-RL 的主战场。
- 算法改进(algorithm refinement):6% 的胜场是"我用了更聪明的算法"。这数字比人类的 11% 小不少,但比 RLVR baseline 的 1% 已经强多了。
- 数学简化(math shortcut):6% vs RLVR,人类 16%——人类在"想到一个数学技巧"这件事上仍占明显上风。
- 复杂度改进(asymptotic improvement):Optim-RL 对 RLVR 是 13%,人类对 RLVR 是 22%。Optim-RL 超过人类的一半(7%)。
judge 的 accuracy 自查值得一题:GPT-OSS 在"哪个解更快"这个 ground truth 任务上只有 68% 准确率(人 vs 优化 RL 这种更接近的对局里掉到 59%),但对"是不是复杂度改进"这种语义判断准确率 94.8%。也就是说,"哪类优化"这件事比"快多少"更稳定。
我的判断是:这个 judge study 最大的价值不是"Optim-RL 多厉害",而是揭示了模型学到的优化能力有明显倾斜——I/O 和常数因子占 80%+,算法/数学简化加起来不到 15%。这跟训练数据是 Python 竞赛题、对应的"优化空间"主要在实现层面是吻合的。论文作者也在 Limitations 里明说:"如果想让模型发现真正的算法创新,需要 algorithm-aware 的 reward(比如 value model)。"
五、模型对"难度"是否一致友好

图:把 DMC-Optim 测试题按人类解法的复杂度分到 Easy/Medium/Hard 三档,每个扇区从 p100 扫到 p10。上面是 RLVR baseline,下面是优化 RL 配置。每个圈对应一个训练步(1k→10k)。
几个直观观察:
- 在 Easy 题的 p100 上,baseline 已经 74.6%,优化 RL 76.4%——几乎没有 headroom 涨,因为纯正确性本就接近天花板。
- 在 Hard 题的 p50 上,baseline 21.9%,优化 RL 30.6%——绝对涨了 8.7 个点。
- Hard 题在 p30 上优化 RL 涨 70% 相对值;Easy/Medium 涨 125% 相对值——绝对涨分在 Hard 上反而少,因为 Hard 题首先要解决"写对",能省下来的优化空间天然小。
这是符合直觉的——Hard 题的优化能力提升受限于"模型要先做对"的硬约束。这也呼应了 Limitations 的提示:算法改进是真正稀缺的,而 Hard 题最需要的恰恰是算法改进。
六、鲁棒性:沙箱一抖,结论还成立吗
最后一个值得讨论的实验:沙箱 timing 漂移下的鲁棒性。论文做了一组仿射扰动:把参考解的耗时按 \(d'_\text{ref} = \alpha d_\text{ref} + \beta\) 缩放,模拟"评测时沙箱变慢/变快"。

图:四个面板分别是 p50 绝对值的 β 扫描(α 固定)、α 扫描(β 固定),以及 p50 相对提升的同样两个扫描。x 轴左侧对应沙箱"变快",右侧对应"变慢"。蓝色 Baseline 一直最低,棕/红色 QP/Coll. ranked 几乎一直最高。
关键结论:
- 当沙箱变慢(右半部分),优化 RL 相对 baseline 的优势非线性放大——你能省 1ms 的优化在慢沙箱下被放大成 N 倍的奖励。
- 当沙箱变快(左半部分,"作弊"场景),优势收窄但不归零:top 30% 在 p50 仍保持 7% 的优势,在 p10 仍有 30–35% 的优势。
- 论文说这是个"cheater" 实验——故意把沙箱调快让 baseline 也变得很强。这种情况下优化 RL 还能赢,说明它的优势不是"恰好踩在某个沙箱配置上"的。
工程上的 takeaway:即使你的训练沙箱和部署沙箱不完全一致(比如本地训、线上判),这套方案仍然 work,不会因为换了台机器就崩。
七、批判性判断:哪些地方要打个问号
读论文不能光看数据,得有怀疑。这篇我有几个不算"否定"但需要标记的点:
1. 训练规模其实很小。所有 RL run 都用 ~1,000 个 prompt,10k optimizer step。相比 CWM 32B 报告里的 81,000 提示,这次实验是"小规模对照"而非"饱和训练"。作者自己也在 Compute Fairness 那一节说"大 prompt 池应该能让优化 RL 进一步涨"——所以现在的 125% 相对涨幅可能还不是上限。
2. CWM 32B 的 SFT 数据未必干净。CWM 团队报告了对 LCB 的 decontamination,但论文无法对 DMC-Optim 做同等保证——CWM 中训练数据里已经见过 DMC 部分题(虽然是通过 R1 生成而非人类参考解)。从结果看,这种"提前见过题"没让 CWM 在标准 RLVR 上获得不对称优势,但你拿 32B 模型和 7B 模型比迁移性时要注意这个混杂。
3. Pass@10 涨了但 Pass@1 涨得更多。这不是说"模型变窄了",而是 RL 把"样本分布向左移"(让更对的样本更靠左)。在 Hard 题目上 LCB 的 pass@1 反而降了 3–4 个点(Qwen 7B)——这部分论文解释为"LCB 测试太短,本来就没优化空间,同时 LCB 难度比 DMC-Optim 高,模型注意力被分散了"。我觉得这个解释合理,但属于"诚实但不完美"的边界。
4. 评测指标 \(p_\tau\) 的选择有主观性。\(p_{30}\) 这个值是论文挑的("严格但仍有信号"),\(p_{10}\) 已经基本是噪声。如果换成 \(p_{20}\) 或 \(p_{40}\),结论会不会变?论文的 cross-evaluation heatmap 给了一部分答案——同一族评估指标间高度相关,但跨族(pre vs intra vs post)会拉开。所以你拿单个 \(p_\tau\) 去做产品决策,要小心。
5. "模型没作弊"这件事需要证据。Collapse binary reward 看起来很"诚实"(错就 -1、对就 +1),但模型完全可能学会"用 I/O 优化来掩盖正确性"——比如把 fast-but-wrong 的程序先打印成对的格式再执行。论文里没看到针对"reward hacking mode collapse"的系统化审计。
6. 任务域窄。DMC-Optim 全是单文件 Python 竞赛题,不涉及仓库级 profiling、多语言、内存优化、长 edit loop。作者明说"这是一块 playground,真正的 SWE 任务更难",但距离产品落地还有距离。
八、和同期工作比,处在什么位置
最直接的对比是 Afterburner(NeurIPS 2025)。Afterburner 是迭代优化框架:模型先写一个程序,monolith 沙箱测一次,模型看到执行反馈后改一版,如此往复。GRPO 训练在 LeetCode 的 Venus 数据集上把 pass@1 从 47% 涨到 62%,跑赢人类的概率从 31% 涨到 45%。
Afterburner 和本文最大的区别是 setting:
- Afterburner 是 iterative refinement——模型有"上一版 + 执行反馈"做上下文。
- 本文的 setting 是 one-shot generation——模型在没看到任何执行反馈的情况下,一次生成一个又快又对的解。
后者显然更难,但对推理服务来说(一次性 inference,不能反复调用沙箱)也更有价值。本文的 125% p30 相对涨幅是把整个 timing 信号吸收进策略分布里——而 Afterburner 的"优化能力"很大程度是靠在 inference time 反复调。这两个方向是互补而非冲突的。
另一个相关工作是 PIE(Berkeley 2024),它从 offline 的"慢-快"edit pair 中学习,不直接做 RL。但 PIE 报告了 1.91× 的"假加速"——同一份代码重跑两遍因为系统噪声被判定为"快了 1.91 倍"。这正是本文花大篇幅在沙箱和校准上解决的问题,从侧面验证了"timing 不可信"是行业的真实痛点。
在 GRPO 的稳定性分析上,本文站在 Dr. GRPO(Liu et al. 2025)和 DAPO(Yu et al. 2025)这条线上。Dr. GRPO 已经指出 std-normalization 引入难度偏置,本文直接采用"center but don't divide by std"是这条线索的工程化延伸。
说到底,这篇论文的工程价值在于:把"timing-based code RL"从"看上去自然但跑不出来"的状态,推进到了"复现即可落地"的状态。 它没有发明新的 RL 算法,但把所有必要的工程组件对齐到了一个能跑出 100%+ 相对涨幅的协议。
九、最后:哪些经验可以搬到你的项目里
如果你也在做 code LLM / Agent 训练,这篇论文给了几个具体可借鉴的点:
- 沙箱稳定性是地基。本地 worker 同时跑 inference 和 code execution 拿不出可信 timing。如果你的项目里有"模型生成的代码越快越好"的奖励,先确认沙箱本身的 timing CV < 5%。
- 二元门 + 折叠 reward 比加性/连续 reward 稳。当你想让模型在"对"和"快"之间平衡时,优先尝试"先检查对、再二元卡快"的结构,而不是把两个 reward 加权平均。这跟 DeepSeek-R1 在数学题上的经验一致。
- 离线模拟器是性价比最高的筛子。哪怕你只能模拟"随机采样 8 次人类解,看 reward 曲线的 AUC 和斜率",也能砍掉 80% 的废配置。GPU 时间不要花在 obvious 不会 work 的环境上。
- GRPO 在带噪 reward 下要调三件事:rollout 数(往上加)、batch size(往上加)、advantage normalization(去掉 std 那项)。这三件事的边际收益在 timing 场景下比在 pass/fail 场景下大得多。
- 评估指标和训练指标最好同源。本文发现 post-exec ranking 和 ranked-worst timeout 在排序训练配置时 ρ ≈ 0.995,但用相对 timeout 评估时所有训练配置排序都坍缩。这意味着你做消融实验时,选错评估指标可能让你错过 90% 的信号。
- 别迷信 Pass@1 的下降。本文里 CWM 32B 在 LCB Hard 段 pass@1 掉了 4 个点(相对 13%),但 pass@10 几乎没掉、speed win rate 涨到 86%。把"对"和"快"当成两个独立维度来评测,比单独看 pass@1 更能反映模型真实能力。
收尾
说实话,这篇论文最让我觉得值的地方不是某个具体数字,而是它把"为什么 timing RL 这么难"这件事系统地回答了一遍。从数据、到沙箱、到奖励形状、到 GRPO 改造、到评测指标设计,每一步都有清晰的因果链和 ablate 支撑。
它也提醒我一件事:LLM 强化学习的"瓶颈"很少是算法本身,而是工程细节。GRPO 早就有了,timing 也能拿到,难的是把它们组装成一个端到端不漏的管道。
至于和 CWM 团队的关联——Pierre Chambon 也是 BigO(Bench) 的作者,Kunhao Zheng 来自 Meta FAIR Paris 的 CodeGen 组,Gabriel Synnaeve 是 CWM 论文的核心贡献者。这次在 arXiv 2607.25970 里直接拿 CWM 32B 做主实验,相当于 Meta 把"代码世界模型"的下游能力展示了一遍:模型不仅能写对,还能在 RL 驱动下写出更快的解。
按这个势头,下一步应该是把"算法改进"这块短板补上——可能的方向是 algorithm-aware reward、value model、或者把 timing 信号和复杂度分类器结合。如果这一块 work 了,那才是真正逼近"会写高效代码的 AI 程序员"。
觉得有启发的话,欢迎点赞、在看、转发。跟进最新 AI 前沿,关注我。