代码语言模型对自动化程序修复的影响

互联不一般哥 2024-05-19 12:30:54

Impact of Code Language Models on Automated Program Repair

Nan Jiang1, Kevin Liu2, Thibaud Lutellier2, Lin Tan2, 1 Purdue University, 2Lynbrook High School

引用

N. Jiang, K. Liu, T. Lutellier and L. Tan, "Impact of Code Language Models on Automated Program Repair," 2023 IEEE/ACM 45th International Conference on Software Engineering (ICSE), Melbourne, Australia, 2023, pp. 1430-1442, doi: 10.1109/ICSE48619.2023.00125.

论文:Impact of Code Language Models on Automated Program Repair | IEEE Conference Publication | IEEE Xplore

摘要

本文致力于自动程序修复(Automated Program Repair,APR),旨在通过为有缺陷的程序生成补丁来帮助开发人员提高软件可靠性。尽管许多代码语言模型(Code Language Model,CLM)已经开发并在许多软件任务中表现出效果,如代码补全,但在评估CLM的修复能力并为APR任务进行微调方面,还缺乏全面深入的工作。该研究首次评估了十个CLMs在四个APR基准上的表现,结果显示最佳CLM修复BUG的能力比最先进的基于深度学习(Deep Learning,DL)的APR技术高出72%。其中,四个APR基准中的一个是本文创建的,以避免数据泄露,确保公平评估。此外,该研究首次对CLMs进行了APR训练数据的微调,结果显示微调能使CLMs的性能提高31%至1,267%,使其修复的BUGs比现有的DL-based APR技术高出46%至164%。研究还分析了有缺陷代码行的影响,发现CLMs本身不能很好地利用有缺陷的代码行来修复缺陷,但经过微调的CLMs可能过度依赖有缺陷的代码行。最后,该研究分析了不同CLMs的大小、时间和内存效率。该研究为APR领域指明了有希望的方向,如使用APR特定设计微调CLMs,并提高了对CLMs公平全面评估的意识,并呼吁更透明地报告用于预训练数据的开源存储库,以解决数据泄露问题。

1 引言

自动程序修复(APR)通过自动生成补丁帮助开发人员提高软件可靠性修复软件缺陷。许多基于深度学习(DL)的APR 技术调整 DL 模型以软件程序作为输入并生成修补程序。典型的基于DL的APR技术构建神经网络来自训练集的模型,它们是有缺陷的代码对和对应的固定代码。然后对这些模型进行评估在测试集上,它们也是有缺陷的代码和固定代码对这与训练集脱节。凭借深度学习模型强大的学习能力,这些技术可以学习多样化的内容将有缺陷的程序转换为已修补程序的模式来自大型代码语料库,许多表现优于传统的基于模板的,基于启发式的和基于约束的APR技术。

尽管基于深度学习的 APR 技术是最先进的技术之一虽然有效,但这些工具无法修复大部分错误。此外,现有的基于深度学习的 APR 工具通常必须生成数百到数千个候选补丁并采取几个小时来验证这些补丁以修复足够的错误。尽管 CLMs 在许多领域取得了成功,但很少有全面、深入的分析和比较 CLMs 的修复能力在APR域中与现有的基于DL的APR域中专门为修复错误而设计的技术。因此,它这是一个有趣且重要的研究问题:做代码语言模型带来了自动化的改进程序修复又如何?

总的来说,本文的贡献如下:

一个新的APR基准测试HumanEval-Java,没有现有的CLMs 在预训练期间看到,以确保公平性评估。CLMs 的大小、时间和内存效率的研究。n 发现1:CodeT5和InCoder模型最好尺寸效率,建议开发更大的CodeT5或InCoder模型是最有前途的。此外,CodeT5,PLBART和InCoder模型是更好的选择资源有限,因为他们有更好的时间和记忆比CodeGen模型的效率。十个 CLMs 与 APR 的首次微调实验训练数据,以及微调影响的研究(及其APR 的 CLMs 上的训练数据大小):发现1:微调将 CLMs 的修复能力提高了 31%–1,267%,并且微调后的 CLMs 表现优于其他模型基于DL的APR技术显着提高了46%–164%。发现2:虽然微调有帮助,但有时使 CLMs 过度依赖有缺陷的线路,从而失败修复一些无需微调即可修复的错误。发现3:CodeT5和CodeGen模型达到最佳10000APR微调后的修复能力训练实例,并使用更多APR数据进行微调使他们修复的次数更少(减少 8%–19%)。编码器模型经过微调后修复了最多的错误50,000个训练实例,以及更多微调数据使其修复次数更少(减少9%)。对10个CLMs(四种架构,即PLBART、CodeT5、CodeGen和InCoder)和四种最先进的基于DL的APR技术(即CURE、RewardRepair、Recoder和KNOD)对四个 APR基准(即Defects4J v1.2、Defects4J v2.0、QuixBugs和我们新的HumanEval-Java):发现 1:即使没有微调,CLM 也具有有竞争力的修复能力。令我们惊讶的是,最好的 CLM,照原样,与最先进的基于 DL 的 APR 技术相比,修复的错误多了 72%。发现 2:虽然有错误的行(需要修改的代码行)已修改)对于指导修复很有用,CLMs 无法使充分利用它们并修复更少已明确给出的错误行。

2 代码语言模型

2.1 CLM架构

代码语言模型可以分为三组:仅编码器模型、仅解码器模型和编码器解码器模型。无论群体如何,大多数现有代码语言模型是使用 Transformer架构构建的因为它具有最好的学习能力和最大的可扩展性。

仅编码器模型包括 CodeBERT和Graph CodeBERT,它们仅具有双向变压器编码器具有注意机制来学习向量化输入代码序列的嵌入。因为他们只有编码器,这些模型最适合下游任务不需要生成,例如代码表示(即嵌入输入代码)和代码克隆检测。

仅解码器模型包括 CodeGen、InCoder、Codex,只有一个自回归变换器解码器来学习生成代码序列。与计算嵌入的仅编码器模型不同对于输入代码,仅解码器模型最适合下游任务,例如开放式代码生成,即,根据输入提示生成代码,其中提示可以是描述功能的自然语言文本,函数的签名,或函数中的前几行代码功能。

最后,编码器-解码器模型包括 PLBART和CodeT5,它具有双向变换器编码器和自回归变换器解码器。编码器被训练来计算输入的嵌入代码,并且解码器被训练来生成代码。因此,编码器-解码器模型更灵活,可以适应非生成(例如,代码分类)和生成(例如,代码摘要)下游任务。

图1:常见的预训练任务以及通过现有的CLM所使用的示例

2.2 常见的预训练任务

代码语言模型之间的重要设计差异是预训练中使用的任务。图1展示了几个现有代码语言使用的常见预训练任务楷模。

(1) Next Token Prediction 是对于不完整的代码给定一个棋子的任务,训练语言模型来预测以下标记,例如,给定 int add(int x, int y){return,下一个标记应该是 x。如果迭代地完成此过程,则可以训练语言模型以生成完整的程序从开始到结束。

(2) Masked Span Prediction 是训练语言的任务模型来预测输入代码中的屏蔽代码片段。图1 显示了一个简单的Java函数,它返回两个整数,其中函数的某些部分被掩盖占位符 <MASK0> 和 <MASK1>。语言模型是训练预测 <MASK0> 应该是 int 并且 <MASK1>应该是 x + y。

(3) Masked Identifier Prediction是预测的任务给定代码中的标识符名称。例如,所有三个标识符(add、x 和 y)均由占位符(<MASK0>、<MASK1>和<MASK2>),并且代码语言模型是训练来预测他们的正确名字。

(4) 删除的跨度预测是给定代码的任务删除一些部分(例如,删除 int 和 + y),语言模型经过训练以生成完整的代码。

(5) 标识符标记的任务是预测每个代码中的token是否是标识符。例如,添加是一个标识符,而 int 不是。因此 add 的预测标签是1,int是0。

(6) Biomodel Dual Generation 是训练在不同语言之间转换代码的语言模型的任务,例如,从自然语言描述到Java代码,从Java 代码到自然语言文本,或从 Java 代码到 Python代码等。

图2实验设计概述

3 实验评估

图 2 显示了我们的实验设计的概述。我们应用十个CLMs和三个最先进的基于DL的 APR四个错误基准测试的技术——三个广泛使用和我们设计了一个新的基准来解决数据泄漏的挑战——生成补丁。我们研究和比较CLMs和基于DL的APR的修复能力技术(RQ1)。然后我们用APR微调这些CLMs训练不同大小的数据集,并研究补丁由微调的CLMs生成,以显示培训的影响微调数据大小(RQ2)。最后通过补丁对比由不同大小的代码语言模型生成,我们研究不同 CLMs 的大小、时间和内存效率(RQ3)。我们专注于Java单块错误,作为最好的基于 DL 的错误APR技术都是专门为Java single-hunk设计的bug(即有 bug的代码是连续的代码行)。这使我们能够探索CLMs与基于深度学习的 APR 技术修复相同类型的错误。

3.1 三个现有的错误基准

我们选择 APR 中广泛使用的真实错误基准域,包括 Defects4J v1.2、Defects4J v2.0、和QuixBugs。 Defects4J v1.2使用最广泛Defects4J基准测试版本包含393个错误,其中130个是单块错误。 Defects4J v2.0是Defects4J基准测试的最新版本包含444个额外错误,其中108个是单一错误。Defects4J v1.2和 Defects4J v2.0均收集自著名的Java项目,例如“Google Closure编译器” 和“Apache 公共数学”。QuixBugs 是一个基准测试包含40个与“快速排序”等著名算法相关的错误和“归并排序”。

3.2 新的HumanEval-Java基准以避免数据泄露

Defects4J v1.2、Defects4J v2.0和QuixBugs被广泛使用通过基于DL的APR技术。但是,仅应用CLMs可能会出现问题,因为CLMs可能已经看到了这些预训练数据中的基准。通过检查代码SearchNet和BigQuery1,哪些是数据源在常见的CLMs中,我们发现使用了四个存储库Defects4J基准测试也在CodeSearchNet中,并且BigQuery包含整个Defects4J存储库。因此,在预训练期间CLMs很可能会看到现有的APR基准。

为了克服这一威胁,我们创建了一个新的错误基准来自HumanEval,命名为HumanEval-Java。人类评估是手动创建的数据集,用于解决 CLM 的威胁可能已经在网上看到了可用的测试数据集。然而,它却被创造了用于评估代码生成任务并写入Python。我们手动将Hu manEval中的Python程序及其测试用例转换为Java程序和Junit测试用例,然后将错误注入到正确的Java程序中创建年利率基准。 HumanEval-Java包含164(单一块)Java 错误,从简单的错误(例如正确使用运算符)到复杂的逻辑错误(需要修改几行代码来修复。由于HumanEval Java是从HumanEval转换而来的,并且错误是手动的注入后,任何CLMs以前都不会看到它。因此,这是比较CLMs与基于DL的最公平的基准年利率工具。

3.3 微调代码语言模型

对于微调的训练数据,我们使用APR之前的工作中共享的数据来自提交开源GitHub Java项目,并对待每个项目single-hunk 修复为一个单独的实例,其中包含143,666总共实例数。数据集被随机分成训练集包含129,300个实例的数据集和包含14,366个实例来调整超参数(例如,数量训练时期)。

对于所有CLMs,我们应用相同的设置进行微调。具体来说,批量大小为一(由于我们的硬件限制)。我们使用 Adam 优化器进行学习1e−5的比率更新模型权重。CLMs仅针对APR数据集的一个时期进行微调,因为它们收敛快速验证数据集。我们设置一个固定的随机种子当微调不同模型以最小化方差时一致、公平的比较。

为了将CLMs与APR工具进行比较,我们选择了四个最佳的开源的基于深度学习的 APR 技术,即CURE,RewardRepair、Recoder和KNOD。其他年利率技术要么修复较少的错误,要么不可用,我们需要选择开源技术将它们应用到我们的新基准HumanEval-Java中。这些APR技术都有编码器-解码器架构,而且有APR特定的设计。

对于所有实验,我们让每个工具(CLM、微调的CLMs或基于DL的APR技术)生成十个候选补丁对于每个错误并运行开发人员编写的测试用例打过补丁的程序。第一个通过的修补程序所有测试用例都被认为是合理的补丁。和我们最后手动检查合理补丁的正确性区分正确的补丁(应该相同或在语义上等同于开发人员编写的补丁)。

3.4 实验问题

RQ1:修复能力

表I显示了10个CLMs的固定能力和针对四个bug 的三种最先进的基于DL的APR 技术基准测试,包括我们新的HumanEval-Java。我们报道前十个补丁中正确补丁的数量自最近的工作表明,每种技术产生的 93%的开发人员只愿意审查最多十个补丁。无需喂食即可获得并报告CLMs的结果有缺陷的线路,因为CLMs可以修复更多缺陷而无需有缺陷的线路信息。表I显示,在不进行微调的情况下应用于 APR 时,不同类型的 CLMs 的表现存在显著差异。通常来说,PLBART模型、CodeGen模型和InCoder模型比APR工具修复更多错误在四个APR基准组合中,同时CodeT5模型修复的次数最少。具体来说,InCoder-6B 修复了bug数量最多(105个),比之前多了72%最好的基于深度学习的APR技术,KNOD。第二个最好的是PLBART-large,修复了85个错误。CodeT5模型的糟糕结果可能是由于它是针对显着不同的任务进行预训练的,包括代码到代码生成、代码到标识符标签预测和代码到自然语言生成。因此,无需针对 APR 任务对它们进行微调,CodeT5 模型无法生成合理的代码或正确的补丁。

表1:十个 CLMs(未经微调)和四种基于 DL 的 APR 技术生成的正确修复数量。

图3显示了编译率的分布针对每个模型的所有基准测试中的错误生成的补丁。CodeGen 模型生成最可编译的补丁,平均编译率为 73%,中位数为 97%。PLBART 和 InCoder 模型还比基于 DL 的 APR 技术生成更多的可编译补丁。基于深度学习APR 技术平均只能生成 44%–62% 的可编译补丁。

CLMs 和基于 DL 的 APR 技术具有不同的修复方法不同基准上的能力。具体来说,基于深度学习APR 技术比 CLM 具有更好的修复能力Defects4J v1.2。图 4(a) 显示了一个示例 (Math-75)所有三种基于 DL 的 APR 技术都修复了 Defects4J v1.2,但是所有 10 个 CLMs 均无法修复。这个错误没有什么背景。没有足够的上下文,尽管 CLMs 可以生成合理的代码,他们无法生成正确的修复程序。无论提供有问题的行return getCumPct((Comparable<?>) v);到无论是否有 CLMs,所有 CLMs 都无法修复此错误。如图所示稍后在第 IV-B 节中,没有微调的 CLMs 会变得很差。相比之下,APR 工具旨在利用有缺陷的线路信息来修复此错误。

相比之下,在 QuixBugs 和 HumanEval-Java 基准测试中,PLBART、CodeGen 和 InCoder 模型显示出比 APR 工具更好的修复能力。图4(b)所示为示例QuixBugs 中的 (GCD) PLBART、CodeGen 和 InCoder模型可以修复,但 APR 工具不能。尽管 CLMs 确实没有看到有问题的行,否则 return gcd(a % b, b);,他们从自然语言文本或代码语料库中了解到gcd代表最大公约数,可以完成功能正常。相比之下,APR工具依赖于buggy生成候选补丁时要排队很多。他们的补丁看起来像是在有缺陷的线路上应用简单的编辑操作没有仔细考虑代码语法和语义。CURE 的补丁将 a % b 替换为 a,RewardRepair 的补丁,删除 return,这甚至使函数无法编译,Recoder的补丁将a替换为b,KNOD的补丁将b与a互换。

图4:从所有四个基准测试中为每个错误生成的十个补丁的编译率分布

图6:CLMs和基于DL的APR所针对的错误示例工具的性能不同

表2显示了当给出错误行时 CLMs 生成的四个基准上正确修复的数量。例如,“36(-36)”表示PLBART-base修复了36个bug提供有问题的线路作为输入,而 PLBART-base 修复72 个bug,没有 bug 线。令我们惊讶的是,所有CLMs当有bug的线路出现时,持续修复的 bug 数量减少 6%–78%。

为了理解原因,图 7(a) 显示了一个示例,来自 HumanEval-Java 的下一个最小 bug,其中CLMs 生成正确的补丁而没有错误线。这表明模型理解 no_duplicate上下文,从而将数字初始化为 HashSet。然而,当错误行 List<Integer>numbers = new 时ArrayList<整数>();给出,PLBART 无法修复它不再生成一个无法编译的补丁,其中数字是未申报。图 7(b) 显示了另一个示例,FLIP CASE来自 HumanEval-Java,由 CodeGen 和 InCoder 生成当给出有缺陷的行时,补丁不正确。 CodeGen 的补丁删除了整个有问题的行,而 InCoder 的补丁只是简单地删除了重复有 bug 的行,这表明 CLMs 很混乱通过有缺陷的行,并尝试遵循给定的有缺陷的代码而不是生成正确的代码。这可以解释为CLMs 没有经过预先训练来使用buggy线路。

表2:CLM 生成的正确修复数量以及提供的错误行

图7:CLMs 表现不同的错误示例何时给出越野车线路与何时不给出buggy线路

尽管当有问题的线路出现时,CLMs 修复的错误较少鉴于,他们在 buggy 的帮助下修复了一些独特的错误线。图 7(b) 显示了这样一个示例,图表 8,来自Defects4J v1.2。没有 buggy 线,CLMs 的补丁是此错误不正确,因为它们没有足够的上下文生成正确的补丁。当给出越野车线路时,他们都可以生成正确的补丁(时间,区域,Local.getDefault());。关于微调的影响,CodeT5 模型增益改进最多 (889%–1,267%) 和 PLBART 模型获得的改善最少 (31%)。尽管多任务预训练使得CodeT5模型之前生成了糟糕的代码微调,他们确实学习了通用编程语言来自预训练的知识,有助于 CodeT5 模型从微调中学习强大的固定能力。对于PLBART模型中,一个令人惊讶的结果是 PLBART-large 模型修复了 HumanEval-Java 基准测试中的四个错误微调。

图 8(a) 显示了所有 CLMs 都可以修复的示例只有在微调之后。无需微调,CodeT5 模型生成与 bug 无关的错误补丁line、PLBART 和 CodeGen 模型生成的补丁相当于 buggy 行,InCoder 模型删除了越野车线。这支持了我们的发现 2,CLMs 未能做到这一点充分利用有缺陷的线路信息(CLMs 也无法修复这个错误没有错误行)。然而,经过微调,一切CLMs 学习利用有缺陷的线路来生成正确的补丁。

表3由十个微调的 CLMs 和四种基于 DL 的 APR 技术生成的正确修复数量

图8:微调后CLMs 表现不同的错误示例

图 8 (b) 显示了 CLMs 可以实现的相反示例仅修复而不进行微调。 PLBART、CodeGen 和 InCoder模型无需微调即可修复此错误,并且无需提供越野车线路,这表明他们明白number_array 是用英文书写的数字数组,并应根据其数值排序(存储在 value_map 中)。这揭示了 CLMs 的强大能力理解代码语义。然而,经过微调之后,他们全部生成不正确的补丁。令人惊讶的是,经过微调的 CLMs 会犯与基于 DL 的 APR 类似的错误他们的补丁的技术(也未能修复此错误)过于依赖越野车线路,找不到目标功能来自上下文。

图9:生成的 HumanEval-Java 正确修复数通过使用不同大小的 APR 数据进行微调的 CLMs

图 9 显示了当使用不同大小的 APR 数据进行微调时,CLMs 在 HumanEval-Java 基准测试中生成的正确修复数量。 CodeT5-大收获微调后进步很大,年利率只有100训练实例并达到最佳修复能力(59)经过 10,000 个实例的微调后。CodeGen-6B 也经过微调后修复了最多的错误10,000 个实例。两种模型都有一个共同的模式,即如果微调数据从 10,000 增加到完整数据集(129,000),他们开始修复更少的错误。

图10: CLMs 的大小、时间和内存效率

图10(a)显示了正确修复的数量十个微调的 CLMs 生成为 CLMs 的数量参数增长。具有更多参数的较大模型始终比较小的模型表现出更好的固定能力。经过微调的 CodeT5 和 InCoder 模型始终能够解决最多的问题与其他具有以下功能的模型相比,错误数量参数数量相似,即 CodeT5 和 InCoder 是尺寸效率最高。经过微调的 PLBART 模型具有尺寸效率第二高,CodeGen 模型最少尺寸高效。结果表明,预训练和微调更大的 CodeT5 或 InCoder 模型是有前途的,这仍然是未来的工作,因为我们已经评估了最大的发布的型号。

4 结论

本文研究了CLMs对ARP带来的影响领域。我们应用了CLMs,有或没有微调四个ARP基准,包括创建的新基准在这项工作中。实验表明CLMs具有竞争性修复能力功能,最好的CLMs修复的错误比最先进的基于DL的ARP技术。微调还显着改进了CLMs,使CLMs能够修复错误数量增加31%–1,267%,并且性能优于基于DL的最佳产品ARP技术提高46%-164%。因此,本文表明开发基于CLMs的ARP技术,将ARP特定设计纳入CLMs的微调过程中,以及解决对越野车线路的过度依赖是有希望的未来的探索方向。此外,这项工作还呼吁为了提高对CLMs进行公正和全面评估的意识,包括避免数据泄露以及报告大小、时间、和记忆效率。

转述:冯晟

0 阅读:0

互联不一般哥

简介:感谢大家的关注