摘要:大型语言模型(LLMs)已经在代码生成领域取得了显著进步,但生成的代码虽然功能正确,却往往存在效率低下的问题。这一研究缺口正是由南洋理工大学、新加坡国立大学、香港大学、西安交通大学和字节跳动的联合研究团队着手解决的。在最近发表的论文《Afterburner:
想象一下飞机上的加力燃烧室(Afterburner)——它能在关键时刻为喷气发动机提供额外推力。同样,研究团队开发的"Afterburner"系统也能为代码提供效率上的"额外推力"。这个系统不是一次性优化,而是设计了一个反复迭代的过程:模型生成代码后,通过名为"Monolith"的沙盒执行环境评估代码性能,然后将性能反馈回馈给模型,促使它在下一次迭代中生成更高效的代码。
研究团队探索了三种优化策略:监督微调(SFT)、直接偏好优化(DPO)和群体相对策略优化(GRPO)。在自建的Venus数据集和APPS基准测试上的实验表明,SFT和DPO策略在效率提升方面很快达到饱和。相比之下,基于强化学习的GRPO方法通过执行反馈持续优化代码性能,显著提高了代码通过率(PASS@1从47%增至62%)和在效率上超越人类提交的可能性(从31%提高到45%)。
这项研究不仅展示了测试时代码效率改进的有效方法,更重要的是揭示了强化学习在教导大语言模型自我改进代码效率方面的强大潜力。
一、为什么代码效率很重要?现有大语言模型的短板
现在的大语言模型在生成功能正确的代码方面表现出色,有些甚至在特定任务上能与人类工程师相媲美。然而,这些模型普遍存在一个重要短板:它们生成的代码虽然能正确运行,但效率往往不尽如人意。这就像一个厨师做出了美味的菜肴,但烹饪过程浪费了太多能源和时间。
在实际应用中,代码效率问题远比我们想象的重要。想象一下,如果你的手机应用每次操作都需要多等待几秒钟,或者你的网站因为后台代码效率低下而不断崩溃,这些都会直接影响用户体验。更严重的是,在大规模系统中,低效的代码会导致计算成本激增、系统延迟增加,甚至整体服务质量下降。
为了评估代码效率问题的严重性,研究人员分析了多个代码效率基准测试的结果。例如,EffiBench通过与参考解决方案比较相对性能来评估效率;PIE4PERF使用系统模拟来评估C++代码对的优化影响;Mercury采用百分位排名与人类解决方案对比突显效率差距;EVALPERF则根据参考解决方案对生成的解决方案效率进行分类。这些基准测试一致表明:尽管大语言模型在生成功能正确的代码方面表现出色,但它们生成的代码在效率上通常表现不佳。
早期解决这一问题的尝试,如PIE中的思维链(Chain-of-Thought)方法、Effilearner中的自我优化,或在效率导向数据集上微调大语言模型,都只取得了有限的成功。这些方法往往未能赋予模型在各种情况下进行稳健效率改进所需的适应性知识。
二、Afterburner:一个闭环的代码效率优化框架
为了解决这一问题,研究团队提出了名为"Afterburner"的迭代优化框架。这个名字借鉴了航空领域的加力燃烧室(afterburner)——一种在喷气发动机中提供额外推力的装置。同样,这个框架也旨在为代码提供"额外推力",但不是通过消耗更多"燃料",而是通过智能优化来提升效率。
整个框架围绕两个核心组件展开:Afterburner和Monolith。Afterburner负责生成和优化代码,而Monolith则是一个代码执行沙盒,负责评估代码性能并提供反馈。这两个组件共同构成了一个闭环系统,类似于人类开发者通过尝试和反馈不断改进代码的过程。
具体来说,工作流程是这样的:首先,Afterburner接收问题描述、效率指令(如"优化执行时间"或"减少内存使用")和原始代码(如果有的话)作为输入。然后,它生成一个改进的代码版本。这个新生成的代码会被送入Monolith沙盒执行,Monolith会测量其执行时间、内存使用情况等性能指标。这些经验性能数据随后被反馈回Afterburner,指导下一轮的代码优化。通过这种循环迭代的方式,代码质量可以不断提升。
值得注意的是,这种方法与人类开发者优化代码的方式高度相似:我们编写代码,测试其性能,发现瓶颈,然后针对性地进行改进。Afterburner框架本质上是将这一人类智能过程自动化,并通过机器学习技术加以增强。
三、训练策略的比较:SFT、DPO和GRPO各有何特点?
为了训练Afterburner模型,研究团队探索了三种不同的优化策略,每种策略都代表了不同的学习范式。就像教导一个学生可以采用不同的教学方法一样,这三种策略各有特点,也带来了不同的学习成果。
首先是监督微调(Supervised Fine-Tuning,SFT)。这种方法就像传统的课堂教学,通过向模型展示低效代码和相应的高效版本,教它"模仿"转化过程。具体来说,模型学习从次优解决方案到更高效解决方案的映射关系。这种方法直观简单,但可能缺乏灵活性和创新性,因为它主要依赖于训练数据中看到的模式。
第二种策略是直接偏好优化(Direct Preference Optimization,DPO)。这种方法更接近于批改作业,模型学习区分"好"代码和"坏"代码。DPO不需要在训练过程中从参考模型明确采样,而是直接增加正面响应(高效代码)的可能性,同时降低负面响应(低效代码)的可能性。这样,模型可以根据指定的效率目标内在地生成更高效的代码。
第三种也是最复杂的策略是群体相对策略优化(Group Relative Policy Optimization,GRPO)。这种方法类似于项目式学习或实验室实践,模型通过实际操作和反馈来学习。GRPO将DPO的成对离线比较扩展到群体性在线排名场景。对于给定的提示,GRPO生成多个候选解决方案,并学习这些解决方案之间的相对优势。受最近研究的启发,研究团队探索了GRPO是否能增强代码效率。
GRPO的奖励函数设计尤为关键,它包含三个组成部分:格式控制奖励(鼓励模型按预定格式输出)、功能正确性奖励(确保生成的代码功能正确)和计算效率奖励(测量与基准输入代码相比的相对性能改进)。这些奖励被加权组合,共同指导模型的学习方向。
简单来说,SFT通过"看示例学习",DPO通过"辨别优劣学习",而GRPO则通过"实践和反馈学习"。这三种方法代表了从简单模仿到复杂交互式学习的进阶。
四、数据集构建:Venus——专为代码效率评估打造的新基准
要训练和评估代码效率优化模型,需要高质量的数据集。虽然已有一些代码效率基准,如Mercury、EffiBench和EVALPERF,但它们都存在一定的局限性。为此,研究团队构建了名为Venus的新数据集,这是一个专门为代码效率评估设计的多语言基准测试集。
Venus数据集的构建过程非常严谨。研究团队从LeetCode平台的3,535个问题开始,首先排除了付费题目,保留了2,821个免费可访问的问题。然后,他们筛选出算法类问题,排除了数据库或Shell类别的题目。为确保评估的可靠性,他们执行了所有可用的解决方案,排除了通过所有测试用例的解决方案少于16个的问题。最终,他们精选出1,284个高质量问题,分为984个训练集和300个测试集。
Venus数据集的几个主要特点使其在代码效率评估中脱颖而出:
首先,Venus采用了类似Mercury和EVALPERF的方法,计算生成代码相对于多样化参考解决方案分布的百分位排名,而不是依赖单一的、可能有偏见的基准。这就像评价一个学生的成绩不是只与班上最优秀的学生比较,而是看他在整个班级中的排名位置。
其次,Venus提供了大量的解决方案,平均每个任务有106.6个人类提交的解决方案,远超现有Python效率基准中的不到20个解决方案。这确保了百分位计算的稳定性和可靠性,就像调查人群意见时,样本越大结果越可靠一样。
第三,Venus提供了全面的评估,不仅评估执行时间和内存使用情况,还考虑它们的综合影响。特别是,Venus引入了积分得分(∫_0^{r^gen_k} m^gen_k(t) dt)作为全面的效率指标,其中m^gen_k(t)是时间t时的瞬时内存占用。这类似于评估汽车不仅看最高速度和最大载重,还要看整个行程的燃油效率。
此外,Venus突破了以往基准主要关注Python的局限,提供了对多种编程语言的强大支持,包括Python、C++、Go、Java和JavaScript等。这种语言无关的测试用例生成方法使Venus成为更具普遍性和适应性的基准测试。
基于Venus数据集,研究团队构建了用于训练Afterburner模型的各种数据集,包括监督微调数据集(DSSFT)、偏好数据集(DSDPO)、冷启动数据集(DSCOLD)和GRPO训练数据集(DSGRPO)。
五、实验结果:强化学习在代码效率优化中的突出表现
研究团队在Venus和APPS基准测试上进行了广泛实验,比较了不同优化策略的性能。实验结果揭示了各种策略在代码效率优化方面的不同学习动态。
首先,研究团队评估了各种原始大语言模型在代码效率方面的表现。结果显示,尽管这些模型在功能正确性(PASS@1)方面表现出色,但它们生成的代码在计算效率方面明显逊于人类解决方案。例如,在Venus基准上表现最好的OpenAI o4 mini模型,虽然PASS@1达到89.11%,但其运行时效率(BEYOND-T)仅超过56.85%的人类解决方案,在APPS基准上则仅为40.07%。这一普遍存在的效率差距凸显了开发专门优化框架的必要性。
接下来,研究团队比较了三种优化策略(SFT、DPO和GRPO)在迭代优化过程中的表现。结果显示出明显的差异:
SFT策略(类似于模仿学习)在最初的几次迭代中能实现一定的效率提升,但很快就达到饱和,难以持续改进。这是因为SFT主要学习了训练数据中的表面模式,一旦应用了这些已知的优化模式,就难以进一步创新或适应新的效率挑战。就像一个只会按照食谱烹饪的厨师,面对新食材或要求时显得力不从心。
DPO策略(基于偏好学习)表现比SFT更好,但也存在类似的饱和趋势。DPO内化了基于训练中成对比较的静态偏好,这使其能做出更细微的判断,但由于是离线方法,没有从自己的生成中学习的能力,其探索范围仍受限于初始偏好数据集的多样性。这就像一个有品味的美食评论家,能辨别菜肴的好坏,但不一定知道如何改进它。
GRPO策略(基于强化学习)展现出最为显著的持续改进能力。通过在线交互式学习,AfterburnerGRPO能够从执行反馈中不断调整和优化其生成策略。这种适应性使GRPO能够探索和利用解决方案空间,在迭代过程中不断突破效率优化的边界。在Venus基准上,GRPO将PASS@1从47%提高到62%,显著提升了所有效率指标,例如BEYOND-I从31%增加到45%。这就像一个不断实验和学习的专业厨师,通过尝试和反馈不断完善自己的技艺。
研究团队还进行了消融实验,移除执行反馈和原始代码输入,以了解它们对各策略性能的影响。结果表明,移除这些组件对AfterburnerGRPO的性能影响最大,证实了反馈机制和原始代码上下文在其持续学习能力中的关键作用。
在与人类代码效率的比较中,AfterburnerGRPO在8次迭代后达到了最高的超越人类解决方案的百分比:TIME(8.00%)、MEMORY(7.00%)和INTEGRAL(5.33%)。这表明AfterburnerGRPO不仅能复制训练中观察到的常见模式,还能通过强化学习主动探索解决方案空间,发现结构上与传统人类方法不同的高度优化实现。
六、GRPO为何能持续改进代码效率?探究其成功机制
GRPO在代码效率优化中的出色表现并非偶然,而是源于其独特的学习机制。那么,是什么让GRPO能够持续改进代码效率,而其他方法如SFT和DPO则很快达到性能瓶颈呢?
首先,生成多样性是GRPO迭代能力的基础。在训练阶段,通过放松KL散度限制,AfterburnerGRPO能够探索多种潜在的优化路径,而不需要依赖于已知的"正确答案"。这种多样性确保模型不会被局限在局部最优解上,就像一个探险家不仅沿着已知的小路行走,还会尝试开辟新的路径。
其次,GRPO通过迭代优化循环获得改进代码的经验。它不仅生成代码,还执行这些代码以获取其真实世界性能的具体反馈,从而在一个持续的循环中有效地从自己的成功和失败中学习。随着模型在训练中识别出更高效的代码结构,它逐渐变得更善于在推理过程中生成这些结构。
消融研究证实了这一点:移除反馈机制或原始代码上下文显著降低了AfterburnerGRPO的性能,这种影响在AfterburnerSFT或AfterburnerDPO中并不总是那么明显。例如,在迭代4时移除反馈,AfterburnerGRPO的BEYOND-T指标下降了6.66个百分点,而AfterburnerSFT只下降了1.20个百分点。
这种基于反馈的学习方式与人类学习新技能的过程惊人地相似。就像一个人学习弹钢琴不仅是通过观看他人表演(SFT)或判断哪些表演更好(DPO),而主要是通过自己实践并从错误中学习(GRPO)。这种实践和反馈的循环使人们能够不断完善技能,突破初始水平。
总之,GRPO成功的关键在于它将代码效率优化视为一个动态的、交互式的学习过程,而不仅仅是静态模式的识别或偏好的内化。通过实时反馈和持续探索,它能够适应不同问题的独特需求,并随着时间的推移不断改进其优化策略。
七、Afterburner能生成超越人类效率的代码吗?
一个自然而然的问题是:Afterburner能否生成效率超越人类编写代码的解决方案?研究结果给出了令人振奋的答案。
虽然大型语言模型擅长生成功能正确的代码,通常是通过模仿训练数据中的人类编写示例,但一个关键问题是:它们能否产生效率超越这些人类编写代码的解决方案?为了研究这一点,研究团队将模型生成的代码效率与Venus中的人类解决方案进行了对比。
结果表明,推理能力强的模型如QwQ 32B和OpenAI o4-mini确实展现出了生成超人类解决方案的能力,尽管频率较低。更重要的是,经过8次迭代的AfterburnerGRPO在所有评估指标中达到了最高的超越人类水平的百分比:TIME(8.00%)、MEMORY(7.00%)和INTEGRAL(5.33%)。
这一发现表明,AfterburnerGRPO不仅仅是复制预训练期间观察到的常见模式。通过强化学习积极探索解决方案空间,它能够发现高度优化的实现,这些实现在结构上往往与传统人类方法不同。这就像一个棋手通过自我对弈和试验发现了与人类大师传统策略不同的新颖下法。
然而,这种增强的探索能力也带来了一个权衡:AfterburnerGRPO还会生成比人类基准效率低的解决方案。这反映了探索与利用之间的经典权衡——为了发现真正创新的解决方案,系统必须愿意尝试可能不如当前最佳实践的新方法。
八、Afterburner的局限性与未来发展方向
尽管Afterburner在代码效率优化方面展现出显著成效,但它仍存在一些局限性,理解这些局限性对于未来研究至关重要。
首先,虽然Afterburner在竞赛级编程任务上展示了有效的效率优化,但将其扩展到更大的实际软件工程项目仍需进一步研究。现实世界的项目通常涉及更复杂的代码上下文、多样化的效率标准(超出算法性能,如库交互或I/O操作),并可能需要复杂的任务分解策略,这些都超出了当前工作的范围。
其次,Afterburner的迭代优化框架在代码生成阶段需要比单次方法更多的推理时间。这就像精心烹饪一道复杂菜肴需要比简单加热预制食品更多的时间。研究团队认为,这种前期优化投资可以通过高效代码部署后的显著累积运行时节省来抵消,特别是对于频繁执行或性能关键的模块。然而,这种优化成本与长期执行收益之间的权衡需要根据特定应用需求和部署场景进行仔细评估。
此外,尽管研究表明强化学习方法在持续优化方面表现优异,但SFT和DPO在特定场景下仍有其价值。未来的研究可能会探索这些方法的混合策略,结合各自的优势。
另一个有价值的研究方向是探索更复杂的奖励函数设计,可能包括更多维度的代码质量,如可读性、可维护性,甚至是安全性考虑。这就像评价一道菜不仅看其味道,还要考虑其营养价值、外观和创新性。
最后,将Afterburner框架扩展到更多编程语言和更广泛的软件开发任务(如重构、测试生成或文档生成)代表了激动人心的未来方向。
来源:至顶网一点号