训练代码生成模型实现自我调试输出
代码生成——将自然语言规范自动翻译成计算机代码——是大语言模型最有前景的应用之一。但编程任务越复杂,大语言模型出错的可能性就越大。当然,任务越复杂,人类编码员也越容易出错。这就是为什么调试是软件开发流程中的重要组成部分。
在2024年神经信息处理系统大会发表的一篇论文中,我们描述了一种训练大语言模型成为更好调试器的新方法,同时还能提高代码生成能力。
先前使用大语言模型调试代码的尝试主要使用少样本学习,即提供少量成功调试示例,由大语言模型推断其余部分。相比之下,我们的工作同时使用监督微调和强化学习来专门训练大语言模型进行调试。由于调试训练数据稀缺,我们利用大语言模型创建高质量的合成训练数据。
数据合成
有几个广泛使用的公共数据集用于训练代码生成模型,这些数据集包含自然语言提示、提示的规范代码实现以及单元测试。但用于调试模型的训练数据相对稀疏。
为了创建调试数据集,我们从几个现有的代码生成数据集开始。我们反复将每个自然语言提示输入代码生成模型,为同一提示生成多个不同版本(比如20个)。然后对这些生成代码运行相关单元测试,仅保留未通过测试的代码——即有错误的代码。
接下来,我们将有错误的代码连同单元测试生成的错误消息一起输入大语言模型,提示大语言模型解释错误发生的位置和原因。最后,我们将大语言模型的诊断结果、有错误的代码和错误消息重新输入大语言模型,并附上修复错误的指令。这是思维链推理的一个版本:先前研究表明,要求大语言模型在采取行动前解释其意图通常能提高性能。
然后我们对修订后的代码执行单元测试,这次仅保留通过所有测试的修订版本。现在我们有了一个新的数据集,包含自然语言提示、这些提示的错误实现、错误诊断、调试后的代码和单元测试。
模型更新
有了这个数据集,我们就可以使用监督微调和强化学习来更新调试模型。在两种更新方法中,我们都实验了在要求代码修订前要求思维链解释的训练方案,以及仅要求修订的方案。
使用监督微调时,我们向模型提供自然语言指令、有错误的代码和单元测试的错误消息。根据模型在单元测试中的表现来评估输出。
使用强化学习时,模型与训练数据进行迭代交互,尝试学习能够最大化奖励函数的策略。经典的强化学习算法需要连续奖励函数,以便探索优化空间。
单元测试反馈是二元的,因此是离散的。为了克服这一限制,除了单元测试的成功率外,我们的强化学习奖励函数还包括修订代码的CodeBLEU分数,该分数衡量其与规范示例代码的距离,提供连续的奖励信号。
单元测试应用起来耗时且资源密集,因此基于CodeBLEU分数进行训练也开辟了直接基于规范示例进行训练的可能性,这是一个计算效率更高的过程。我们的实验表明,这种方法确实提高了调试性能——尽管不如同时基于单元测试结果进行训练的效果好。
评估
在实验中,我们使用了三种类型的模型:一种是完全依赖提示工程的普通大语言模型;一种是使用监督微调在我们的数据集上更新的大语言模型;一种是同时使用监督微调和强化学习在我们的数据集上更新的大语言模型。
我们使用三种不同的大语言模型架构实现了每种类型的模型,对于每类模型,我们测量了三组输出:初始生成、初始生成的直接修订以及涉及思维链推理的修订。最后,我们还研究了两种不同的生成范式:一种给模型一次生成正确代码的机会;另一种给10次机会。这给我们总共提供了24个不同的比较。
总的来说,我们更新的模型表现优于提示工程基线。在几乎所有情况下,同时通过监督微调和强化学习更新的模型版本表现优于仅通过监督微调更新的版本。总体而言,我们展示了一种可扩展的方法,使用执行反馈和规范示例来更好地调试代码模型并提高其生成性能。
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)或者 我的个人博客 https://blog.qife122.com/
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)
公众号二维码
公众号二维码