Meta AI与Inria联手:让AI写出既正确又飞快的代码

这项由Meta AI基础人工智能研究部门(FAIR at Meta)和法国国家信息与自动化研究所(Inria)以及巴黎多菲纳大学联合开展的研究,以预印本形式于2026年7月28日发布,论文编号为arXiv:2607.25970。有兴趣深入了解的读者可以通过这一编号在arXiv平台查阅完整论文。
**代码能写对,但能写快吗?**
一个AI能写出能运行的程序,这本身已经让很多人印象深刻。但现实世界里,"能跑"和"跑得快"之间,往往有着天壤之别。一段处理百万用户请求的代码,慢上十倍就意味着服务器成本翻十倍,用户体验变成灾难。然而,目前几乎所有训练AI写代码的方法,都只关心"写对了没有",完全不在意速度快慢。
这就是这项研究要正面回答的问题:能不能通过强化学习,让AI不只写出正确的程序,还能写出快速的程序?
这个问题听起来直接,实际上却暗藏重重陷阱。研究团队在探索过程中发现,只要把"运行时间"塞进奖励信号,整个训练就会崩掉——生成的程序要么没有变快,要么开始变得不正确。这套研究工作的核心贡献,正是系统性地找出了为什么会崩、每一个环节该怎么修,并最终让AI在代码优化这件事上取得了真正显著的进步。
---
一、为什么"让AI写快代码"这么难
先用一个贴近生活的比喻来理解这件事的难度。设想你是一位厨师,老板原本只要求你做出"能吃的菜",现在他突然说:"还得做得快。"你原来的考核方式是顾客吃完以后给个好评或差评,现在老板要在这个基础上再加一个"出菜速度"的评分。
问题立刻就来了:厨房里有噪音——有时计时器不准,有时炉子火力不稳,同一道菜在不同时间量出来的时间可能差好几分钟。如果老板用这个不稳定的计时来打分,你根本搞不清楚自己是真的变快了,还是今天炉子比昨天旺。更糟的是,有时候你可以耍个小聪明:把菜做得半生不熟——表面看起来快,但其实不合格。如果老板的评分系统对这种情况不敏感,你可能就会朝着"快但不熟"的方向越走越偏。
AI训练代码也面临着完全相同的困境。计算机程序的运行时间充满了"噪声",即便是同一段代码在同一台机器上跑两遍,时间也可能差出几十毫秒。更要命的是,如果训练时奖励"运行快的代码",AI可能学会写出"运行快但答案错了"的代码——速度奖励到手了,正确性却丢了。这篇论文把这个问题归结为三个相互咬合的环节:测试数据要能区分快慢、奖励信号要正确地把速度和正确性结合起来、训练算法本身要在这种稀疏和嘈杂的信号下保持稳定。任何一个环节出了问题,整个系统就会失效。
---
二、打地基:构建一个能测速度的数据集
要教AI写快代码,首先得有一套能准确衡量"快不快"的测试题。但研究团队发现,他们手头现有的数据集——来自DeepMind Code Contests(DMC)的约12,275道竞赛编程题——根本不适合做这件事。
原因在于,这些题目原本附带的测试用例太小、太快。绝大多数测试输入只有十几二十个字符,运行一次只需要不到一百毫秒。在这个速度量级上,操作系统的调度延迟、内存分配的随机波动,就已经能让同一段代码的运行时间抖动出几十毫秒的误差——噪声和信号几乎一样大,根本无法分辨代码究竟是快还是慢。
研究团队用一个形象的方式呈现了这个问题:如果你用一把精度只有半米的卷尺去量一个人的身高,量出来的结果毫无意义。要让测量有意义,测试用例本身就必须足够"重",让不同质量的程序在运行时间上产生可以被可靠识别的差异。
为了解决这个问题,他们系统性地重建了测试集。首先,他们把12,275道题目重新执行,核验每道题的答案是否真的正确,把那些标注有误的题目过滤掉。然后,他们用AI模型为剩余的3,928道题目各自生成了10个"输入生成器"——这是一种能自动产生符合题目要求的输入数据的小程序。每个生成器产生15个候选测试用例,只有当多个人类标准答案对同一输入给出相同输出时,这个测试用例才被认可。这一轮筛选产生了43万多个新的"正确性测试",专门用来判断程序答案对不对。
与此同时,他们还额外生成了35万多个"优化测试",这些测试的输入规模被刻意设计得非常大,足以让慢速程序耗费数秒才能完成,而快速程序只需零点几秒。这就像是给运动员设计了一条真正有难度的跑道,而不是让他们在原地踏步然后宣布谁跑得快。
经过层层筛选,最终有1,302道题目达到了"时间可分辨"的标准——在这些题目上,不同质量的正确程序之间存在足够明显的运行时间差异,可以用来训练和评估AI的优化能力。这1,302道题被分成1,000道训练题和302道测试题,构成了这项研究的核心数据集,研究团队将其命名为DMC-Optim。
---
三、测量本身是个技术活:为什么本地计时不可用
数据集有了,但测量工具同样关键。这里有一个让人有点意外的发现:研究团队最初尝试在训练机器上直接运行代码来计时,结果发现这条路完全走不通。
想象一下,你在一个嘈杂的菜市场里试图用手机麦克风录制一段小提琴演奏。背景噪声实在太大,音乐信号完全被淹没了。训练机器上同时跑着AI模型推理、数据加载、多GPU通信……这些工作本身就会占用大量CPU时间。在这种环境下量出来的程序运行时间,误差大得惊人。实验结果显示,同一段代码在同一台机器上反复运行,其"排名"(与人类参考答案相比的速度百分位)会来回抖动41个百分位点——等于说今天它看起来比80%的人类答案都快,明天又变成只比30%的人类答案快,代码本身根本没变。
研究团队为此专门使用了一套独立的远程代码执行服务(他们称之为CES),这套服务在独立的CPU集群上运行每一段代码,每次执行都在隔离的沙箱环境中进行,最大程度排除了外部干扰。在这套系统上,同一段代码反复运行的排名波动只剩下2个百分位点左右——小到可以接受的程度。
但即便用了这套精确的服务,还有一个更隐蔽的问题:数据集里存储的人类参考答案运行时间,是在几个月前某个时间点测量的,而AI生成的代码是在今天测量的。这两次测量之间,服务器的硬件配置、系统软件版本可能已经发生了变化,导致今天测出来的1秒和几个月前测出来的1秒并不完全可比。研究团队通过采集33道题目上超过1,369万个测量数据点,发现了一个系统性的漂移:旧时间数据需要按照一个线性校正公式(新时间 ≈ 0.63 × 旧时间 + 0.053秒)来换算,才能和今天的测量结果对齐。将这个校正应用到参考数据后,排名一致性从0.54的Spearman相关性提升到了0.96,基本消除了跨时间比较的偏差。
---
四、设计奖励:如何告诉AI"你写的代码够快了吗"
有了可靠的测量工具和数据集,下一步是设计一套把"速度测量结果"转换成"训练信号"的机制。这个设计空间极其庞大,稍有不慎就会出问题。
研究团队把所有可能的设计方案按照"优化约束在哪个环节进入训练流程"分成了三大类。
第一类叫做"执行前过滤"——在代码跑之前,先筛选测试用例。比如,只选择那些平均运行时间低于某个阈值的测试用例(绝对时间过滤),或者只选择输入输出字符数低于某个上限的测试(字符长度过滤),或者只保留最快的那部分测试(相对时间过滤)。这样做的好处是不需要过于精确的速度测量,降低了对测量噪声的敏感度;缺点是优化压力可能不够直接。
第二类叫做"执行中限制"——在代码运行过程中设置时间限制。比如,给每个测试用例设置一个绝对的时间上限(超过就算超时),或者把时间上限设成人类参考答案的某个百分位(比如最好30%的人类解法的用时上限)。这类方案直接强制要求代码足够快,压力很明确,但设置不当会让绝大多数代码都超时,导致AI根本拿不到奖励、无从学习。
第三类叫做"执行后排名"——让代码跑完以后,把它和人类参考答案比一比,看它排在什么位置。比如,计算AI代码在每个测试上的速度排名,取平均值,看它是否落在前30%或前50%之内。这类方案最为灵活,同一次执行的数据可以在不同排名门槛下反复使用,但需要有可靠的人类参考答案库。
为了在正式训练之前就能排除那些明显不好用的方案,研究团队构建了一个"离线模拟器"。这个模拟器用真实的人类解法来代替AI生成的代码,用预先存储的运行时间来代替实时测量,然后观察:当模拟的代码质量从差到好逐渐提升时,奖励信号是否也稳定地从低到高变化?如果变化太平稳(说明奖励对代码质量不敏感),或者变化只集中在极端情况(说明大多数时候拿不到有效信号),这个方案就会被排除。通过这个廉价的预筛选,他们节省了大量实际训练所需的GPU计算资源。
在正式的奖励信号设计上,研究团队还测试了多种把"正确性"和"速度"结合起来的方式。有些方案对错误代码和慢速正确代码分别给出不同程度的负奖励,让AI学会区分;有些方案用加权求和把两个目标混在一起;有些方案完全把速度和正确性分成两个独立目标轮流训练。实验结果显示,最好用的是一种叫做"折叠二值奖励"的方案——要么代码既正确又够快,得到正奖励;要么得到负奖励,两种情况之间没有中间灰色地带。这个发现和DeepSeek-R1等研究的结论一脉相承:简单清晰的二值信号往往比复杂的连续信号更有利于训练稳定。
---
五、强化学习算法的适配:让训练在稀疏嘈杂的信号下不崩溃
设计好奖励方案还不够,强化学习算法本身也需要针对这个特殊场景做调整。这里用到的核心算法叫做GRPO(Group Relative Policy Optimization,分组相对策略优化),它的基本思路是:对同一道题生成一批不同的答案,然后比较这批答案的好坏,让AI朝着好的方向调整。
但在代码优化场景下,这套机制会遇到一个棘手的问题:速度奖励的信号比纯正确性奖励稀疏得多。对于很多难题,AI生成的16个答案可能一个都跑不过30%的人类参考,这16个答案拿到的奖励都是负的。当整批答案的奖励一模一样时,GRPO就无法计算"这批答案中谁更好",这一批数据就只能被丢弃,什么也没学到。在实验中,这种"全是负奖励,无法更新"的情况在训练开始时高达40%至50%的批次。
为了应对这个问题,研究团队做了几项重要调整。他们增加了对同一道题生成的答案数量,从而降低"所有答案都一样糟"的概率,让训练能更频繁地从有差异的答案中获得信号。他们还增大了训练批次,让梯度估计更稳定——在噪声大的场景下,批次越小越容易受到偶然波动的干扰,就像用十个数据点估计平均值比用一千个数据点估计的可靠性差很多。
在计算奖励基准线时,他们采用了"按token加权的均值"而不是简单平均,确保长答案和短答案对训练信号的贡献是公平的。他们还用一个固定的"token预算"(32768个token)来归一化损失,而不是用每个答案的实际长度——这样可以防止训练过度偏袒简短的答案或过度惩罚长而复杂的推理过程。
此外,他们还实施了一个"新鲜度过滤"机制:如果某批答案是在30个优化步骤之前收集的,就直接丢弃不用。这是因为在那段时间里,模型参数可能已经更新了,或者代码执行服务的状态可能发生了变化,导致旧的奖励信号不再反映当前模型的真实水平。使用过时的奖励就像用几个月前的导航地图走今天的路,可能会把AI引向错误的方向。
---
六、实验结果:AI究竟学会了多少优化技巧
经过上述所有设置,研究团队在三个不同规模和起点的模型上进行了实验:70亿参数的Qwen 2.5 7B、320亿参数的Qwen 2.5 32B,以及320亿参数的CWM 32B(后者是Meta AI自己发布的一个已经过代码推理微调的模型)。
评估方式同样经过精心设计。研究团队引入了一个叫做"pτ pass@1"的评估指标,其中τ表示百分位门槛。具体来说,p100表示"只要代码正确就算通过",等价于传统的正确性评估;p50要求代码正确且速度排在人类参考答案中前50%;p30要求前30%;以此类推,τ越小要求越严格。这套指标能清晰地区分"AI只是学会了写对代码"和"AI真的学会了写快代码"。
结果是鲜明的。在p50(前50%速度门槛)上,Qwen 2.5 7B的得分从18.0%提升到了31.3%,提升幅度约74%;Qwen 2.5 32B从21.1%提升到39.6%,提升约88%;CWM 32B从30.7%提升到50.4%,提升约64%。在更严格的p30门槛下,提升幅度更为显著:CWM 32B从13.7%一路升到30.9%,相对提升达到125%。与此同时,所有模型的p100分数(纯正确性)基本保持不变甚至略有提升,说明速度的提升并没有以牺牲正确性为代价。
在另一个公开基准测试LiveCodeBench(LCB)上,研究团队采用了速度胜率(win rate)这个更稳健的评估方式,因为LCB的测试用例太小,绝对时间比较意义不大。结果同样令人印象深刻:经过优化训练的CWM 32B,在和标准正确性训练的基线模型的配对速度比较中,胜率高达83%——也就是说,从两个模型各自随机生成20个答案,取中位速度者相互比较,优化训练的模型有83%的概率更快。
研究团队还通过一项"盲审"分析深入探究了AI到底学到了什么。他们让一个大型语言模型(GPT-OSS 120B)对比AI优化版和基线版的代码,判断两者的速度差异来自哪类改进。结果显示,约47%的速度优势来自更快的输入输出处理(比如用更高效的方式读取数据),34%来自常数因子优化(比如减少不必要的中间计算),另有6%来自算法层面的改进,6%来自数学捷径,2%来自数据结构的替换,1%来自完全不同的算法思路。这意味着AI的优化不只是耍小聪明,而是在一定程度上掌握了真正有意义的代码改进技巧。
---
七、与人类顶尖程序员的差距还有多远
当然,AI并没有完全超越人类。研究团队把优化训练后的AI和数据集中记录的最快人类提交方案做了对比,发现人类在67%的情况下仍然更快。但另一个角度同样值得关注:AI在33%的情况下已经比人类的最快解法更快了,这并不是一个微不足道的数字。
更有意义的参照是"复杂度改进率"这个指标——当一个解法不只是常数倍地更快,而是从根本上降低了算法复杂度时(比如从O(n?)变成O(n),这就像把一个需要走遍城市每条街才能找到目的地的导航换成了直接算出最短路径),这才是真正的算法突破。在这个维度上,人类的最快解法在28%的情况下实现了复杂度改进,而优化训练的AI在14%的情况下也做到了这一点——大约是人类水平的一半。
这个对比揭示了当前AI优化能力的轮廓:AI已经相当擅长IO优化和常数因子调整,但在发现真正的算法洞察方面,还远不如顶尖人类程序员。研究团队认为,现有的奖励信号只告诉AI代码快了多少,却不告诉AI为什么快,也不区分"快了一点"和"换了个根本思路变快"——如果未来能设计出算法感知型的奖励,或者引入价值模型来引导AI更多地探索算法层面的改进,效果有望进一步提升。
---
八、这项研究意味着什么
归根结底,这项研究回答了一个很多人可能觉得理所当然但其实非常困难的问题:能不能通过强化学习,在不牺牲代码正确性的前提下,让AI写出更快的程序?答案是可以,但需要在测试数据、执行环境、奖励设计和训练算法每一个环节都认真打磨。
这件事的实践意义可能比它看起来更深远。研究团队在论文末尾明确指出,AI在真实软件工程场景下的"效率差距"比竞赛编程中更严重——在一个名为SWE-fficiency的工业级代码效率测试平台上,Claude 4.5 Sonnet能正确修复81%的软件问题,但只捕获了人类专家优化效果的4.1%。这说明,从竞赛编程迁移到真实代码库,这个问题还需要更多探索。但这项研究提供的方法论——如何构建可靠的速度测量体系、如何设计正确性与速度并重的奖励机制、如何在稀疏嘈杂信号下稳定训练——为未来的迁移奠定了基础。
在代码效率这件事上,AI正在慢慢补上自己的短板。它现在写出的程序,开始不只是能跑,而且跑得还不错了。
---
Q&A
Q1:DMC-Optim数据集是什么,为什么普通测试数据不能用来训练代码速度优化?
A:DMC-Optim是研究团队从DeepMind Code Contests原始题库重新构建的专用数据集,包含2,723道经过清洗的编程题,其中1,302道有足够大的速度差异可以用于优化训练。普通测试数据运行时间太短(通常不超过100毫秒),操作系统调度等随机噪声的影响已经和代码本身的速度差异一样大,根本无法可靠区分快慢。DMC-Optim专门生成了大规模输入测试,让优化测试的运行时间达到数秒,噪声影响相对可以忽略。
Q2:GRPO强化学习算法在代码优化训练中遇到了什么特殊问题,研究团队如何解决?
A:核心问题是奖励信号极度稀疏,训练初期有40%至50%的批次因为所有生成的代码都拿不到正奖励而被完全丢弃。研究团队通过三项调整应对:增加同一题目生成的答案数量以降低全负概率、扩大训练批次以稳定梯度估计、以及丢弃超过30个优化步骤的旧数据以避免过时奖励信号污染训练。
Q3:代码优化强化学习训练后,AI程序的速度提升主要来自哪类改进?
A:根据对174对代码的盲审分析,约47%的速度提升来自更高效的输入输出处理,34%来自常数因子优化(如减少不必要计算),6%来自算法改进,6%来自数学捷径,还有少部分来自数据结构替换。AI在IO优化和常数因子调整上表现很好,但在发现根本性的算法复杂度改进方面,还只达到了顶尖人类程序员约一半的水平。