本文为邹德清教授的《网络安全专题》课堂笔记系列
的文章,本次专题主题为大模型。
饶鸿洲同学: @weixin_42161680 分享了Conversational Automated Program Repair《对话式自动程序修复》.CoRR abs/2301.13246(2023)
分享时的PPT简洁大方,重点突出
对流程图介绍清晰,没看论文也能理解
论文:https://arxiv.org/abs/2301.13246
代码:https://github.com/ASSERT-KTH/RapidCapr
引入会话式 APR 范例:引入了一种新的程序修复方法——会话式 APR。与以前的 LLM for APR 方法不同,它采用交互式的生成和验证过程,以提高修复效率和准确性。
利用验证反馈:会话式 APR 利用验证反馈
,将先前生成的补丁与测试集进行验证,以改善模型的生成补丁。这种方法有助于模型理解先前错误补丁
的问题,并避免重复生成相同的错误补丁
。
LLM 的长期上下文窗口:会话式 APR 允许利用 LLM 的长期上下文窗口,以更好地理解被测程序的语义含义,而不仅仅是代码片段的信息
。
广泛的模型评估:作者对包括新开发的 ChatGPT 模型在内的 10 种不同 LLM 进行了广泛评估,证明了会话式 APR 方法相对于以前的 LLM for APR 方法的改进。
改进模型框架:包括更智能的反馈机制
、更有效的信息合并策略
以及更复杂的模型结构
。这篇论文进一步改进和细化对话式 APR 框架,探索更有效的补丁生成和验证策略。
生成多样性:鼓励生成多样性
,以提高最终修复的鲁棒性。多样性生成可以降低生成相同错误补丁的风险。
APR 框架扩展:这个框架可能不仅适用于代码修复,感觉还适用于其他代码驱动的任务?代码重构、性能优化和缺陷预测
。
还有其他与代码相关的任务,如代码生成、自动文档生成
等。
这篇论文做的实验比较浅、比较模糊
能读懂函数风格提示的模型,
自然语言chatgpt能读懂
增加长度,效果下降了很多
论文给出的解释:冗余的信息让模型误判,改正确的代码改错了
所以有上限
(或许可以)增加实验:成功率
16B的模型
(或许可以)尝试增加大模型
G&V是一种常见的APR范式,它包括生成和验证
两个主要步骤:
预定义的prompt
或prefix来引导生成
。缺乏多样性
。包含了大量误报
,导致数据集质量低下,构建困难。软件维护
的一部分,用于跟踪和记录开发团队如何修复软件中的问题。这些提交通常包括所做的更改,可能包括源代码文件、配置文件或文档的修改,以解决已知的问题。通过查看 “bug fix commits”,开发人员可以了解在项目的不同阶段修复了哪些问题,以及如何解决它们。Conversational APR是一种新的APR范式,通过交互式的补丁生成和验证过程提高了程序修复的效率和准确性。
过程:
好处:
通过使用先前生成的补丁/验证结果作为反馈,从 LLM 迭代获取新的候选补丁,此过程称为轮次。每个轮次包括三个不同的步骤:
(1)根据先前的反馈构建新的提示;
(2)对模型采样以产生样本输出函数;
(3)根据测试用例验证样本输出函数来获取验证反馈。多个按顺序排列执行的轮次称为链。
终止条件是样本输出补丁能够通过所有测试用例(即获得合理的补丁)
或达到最大轮数(即链达到最长的长度)
。
首先使用原始buggy function创建一个初始提示I,这个提示使用自然语言来表明该函数有缺陷(e.g. The following code is buggy)以及希望LLM解决的任务(e.g. Please provide a fixed version)。
然后,使用初始提示 I 对模型进行采样,获得第一个样本输出函数 S1 。 对第 4 行进行了更改: S1 中的函数否定了原始 if 条件。
然后,根据测试列表验证 S1:新补丁能够成功通过先前失败的 sieve(2) = [2] 测试,但是无法 通过sieve(4) 测试。 该验证信息 F1 被收集作为反馈,在下一个对话轮次期间使用。
使用Turn 1中失败的测试用例构建验证反馈 F1,并向模型表明之前的样本 S1 仍然不正确(The fixed version is still not correct)和新任务(Please provide another fixed version)。
然后将初始提示、第一个样本输出函数和验证反馈 { I , S1 , F1 } 连接在一起作为 LLM 的输入。
该模型不仅能够使用原始的buggy function,还能够使用先前生成的样本及其测试用例反馈来生成新的修补函数。
与Turn 1一样,本轮结果获得 S2 和 F2,在保证第4行是正确的前提下,候选补丁函数将 for 循环的上限范围减小了 1。
首先根据之前失败的测试用例构建新的验证反馈 F2。
然后按顺序连接所有先前采样的输出及其验证反馈,生成 { I , S1 , F1 , S2 , F2 } 。
使用此输入再次对 LLM 进行采样以生成下一个候选补丁 S3 。
这时候选补丁修复了bug,并且能够通过所有测试用例,即S3是本次的plausible 补丁至此,程序修复过程终止。
Prompt是在各种downstream任务中利用LLM的有效方法,并且不需要任何明确的微调。
在会话式 APR 中,本文提供的任务提示遵循Xia et al.[1]的风格。本文还遵循先前的指导方针,保证prompt是开放式的,避免generation被限制。
[1]. Jason Wei, Xuezhi Wang, Dale Schuurmans, Maarten Bosma, Brian Ichter, Fei Xia, Ed H. Chi, Quoc V. Le, Denny Zhou: Chain-of-Thought Prompting Elicits Reasoning in Large Language Models. NeurIPS 2022
最大链长度是终止条件之一。所使用的 LLM 具有最大上下文窗口并且不能采用任意长度输入。 一旦达到最大链长度,会话 APR 将从头开始(即通过再次制作initial prompt)并使用新的链会话。 最大链长度是控制 LLM 可以接收多少历史记录的参数。 较小的最大链长度意味着模型生成的不正确补丁较少,对最终的结果的正确性有影响。 较大的最大链长度意味着模型可以看到多个先前失败的补丁,但这也可能没有好处,因为它可能导致 LLM 重复一些早期的补丁或卡在函数的特定实现上。
注:本文的评估标准与QuixBugs Lin et al. [1]中的一致。
评估指标包括:
使用 CODEGEN 的 Hugging Face HuggingFace ,在 Python 中实现 LLM 的生成流程。
通过 OpenAI API 通过查询 code-davinci-002 引擎来访问 Codex。 由于 ChatGPT 不是开源的,并且不提供官方 API (如 Codex),因此本文手动输入提示并提取输出
。
对于除 ChatGPT 之外的所有模型,使用核采样的默认生成设置
,top p = 0.95,temperature= 1,每个 bug 50 个样本,最大链长度为 3。
计算机部分参数: 32核workstation,每个workstation:AMD Ryzen Threadripper PRO 5975WX CPU、256 GB RAM 和 3 个 NVIDIA GeForce RTX 3090 GPU,运行 Ubuntu 22.04.1 LTS。
本文首先将会话式 APR 的性能与之前 LLM 中用于 APR 工作的baseline approach进行比较,其中所有APR的patches是通过从相同的initial prompt中连续采样生成的。本文进一步评估了随着模型规模的增加LLM 的扩展效果,并研究了不同预训练策略(例如 ChatGPT 与 Codex)的性能差异。
表 2 显示了 QuixBugs-Python 和 QuixBugs-Java 上的结果:
对话式 APR能够提高所有模型的所有无监督训练的 LLM 的plausible补丁数量。
对话式 APR 能够减少获得第一个plausible补丁之前所需的tries次数(样本数量)。
与传统的生成补丁的采样方法相比,会话式 APR 能够利用模型对自然语言的理解来表明补丁错误的原因。
对话式 APR 有助于减少使用相同的提示进行采样而产生的重复补丁的数量
表 3 中,与以无监督方式训练的 Codex 相比,ChatGPT在使用Human Feedback强化学习 (RLHF) 后,表现得更好。这种改善部分归因于模型参数的增加以及ChatGPT 中使用的基于对话的微调数据集。 对话式 APR 依赖于验证反馈来调节下一代生成的能通过测试用例的补丁,面向对话模型(例如ChatGPT )的训练数据和算法都包含反馈驱动循环,因此非常适合此任务。
本文研究了会话式 APR 的不同参数:对话链的长度和不同的验证反馈提示是如何影响性能的。
图 3 显示了将 4 个 CODEGEN 模型的最大链长度从 1 更改为 6 时的补丁数量。随着链长度的增加,模型必定会获得越来越多之前迭代的上下文信息。
当链初始长度较小时,随链的长度增加,性能会提高,并在 3 或 4 左右达到最大值,然后随着链长度的继续增加而降低。
一旦达到较高的链长度,plausible补丁数量就会减少,因为上下文信息过多,模型可能无法处理。
这种下降在参数较小的模型中更为显著
,但是参数较大的模型受较长链长度的影响较小,其原因可能是参数较大的模型能够更好地捕获长期的上下文依赖性
。
总结:用于对话式 APR 的最佳链长度可能取决于所使用的各个 LLM。
表 4 显示了 QuixBugs-Python 中使用不同验证提示的合理补丁数量。
no testcase列不包含任何测试用例反馈(仅说明补丁不正确),natural language描述失败的测试用例(e.g.当输入为2时,补丁错误地返回[],但它应该返回[2]),functional提示风格是默认的提示风格。
不同的提示风格对会话 APR 的最终表现的影响:从 no testcase开始,可以通过在告诉 LLM 补丁不正确的基础上添加特定的测试用例反馈信息来提高性能。
使用 buggy/patch 函数名称和传递参数的functional提示风格表现最好,因为 functional提示风格通过将测试用例的输入和预期输出关系表述为函数调用,以更简洁、自然的方式传达失败的测试用例信息。