RAP-Gen:用于自动程序修复的基于CodeT5检索增强补丁生成

互联不一般哥 2024-06-02 11:50:33

RAP-Gen: Retrieval-Augmented Patch Generation with CodeT5 for Automatic Program Repair

Weishi Wang, Yue Wang, Shafiq Joty, Steven C.H. Hoi

引用

Wang W, Wang Y, Joty S, et al. Rap-gen: Retrieval-augmented patch generation with codet5 for automatic program repair[C]//Proceedings of the 31st ACM Joint European Software Engineering Conference and Symposium on the Foundations of Software Engineering. 2023: 146-158.

论文:https://arxiv.org/abs/2309.06057

摘要

自动程序修复(APR)可以减轻开发者的手动调试负担,提高软件可靠性。传统基于搜索的APR方法依赖启发式规则或冗余假设挖掘修复模式,近年出现的基于深度学习的方法则以数据驱动的方式自动化修复过程。但这些方法通常受限于固定参数集,难以模拟APR复杂的搜索空间。为此,我们提出了检索增强补丁生成框架RAP-Gen。它利用从历史bug修复中检索到的相关修复模式,辅助补丁生成。我们构建了一个混合补丁检索器,基于原始源码进行词汇和语义匹配,无需特定于代码的特征。同时采用CodeT5作为基础模型,统一支持检索和生成任务。RAP-Gen采用分阶段方法:首先,补丁检索器获取相关外部bug修复,增强有缺陷输入;然后,CodeT5生成器合成排名修复补丁候选。RAP-Gen是通用APR框架,可灵活集成不同检索器和生成器。评估结果显示,RAP-Gen在多个基准上显著优于最新方法。例如在TFix上,它将T5-large准确率从49.70%提升至54.15%,修复了更多Bug。进一步分析证明,我们的补丁检索器能有效搜索相关修复模式,为APR系统提供指导。

1 引言

程序修复是软件开发中一个关键且耗时的过程。为此,自动程序修复(APR)工具应运而生,旨在减轻开发人员的修复负担。

传统的APR技术中有一类称为基于搜索的方法,它们通常依赖于手工制定的启发式规则或基于冗余假设的技术来搜索修复方案。这一假设认为被修复的补丁通常可以从代码库中的其他地方找到或重构。研究表明,大量提交确实是由现有代码组成的。

近年来,基于深度学习(DL)的APR方法也应运而生,以数据驱动的方式自动化修复过程。它们将APR形式化为神经机器翻译问题,将有缺陷的程序转换为正确版本。但即使使用几亿个参数,这些方法的性能往往仍受限于固定的模型参数无法学习程序修复的高度复杂分布模式。

为了缓解这一问题,我们提出了一种新颖的"检索增强补丁生成"框架RAP-Gen。它结合了基于模型的隐式端到端修复学习和基于修复模式挖掘的显式知识利用。与之前的工作不同,我们利用最相关的bug-fix对作为修复指导,而不是通过手工规则聚类修复模板。这种检索指导策略受到开发者调试行为的启发,他们通常会查找相关bug-fix示例来获取修复线索。

图1:开发人员如何通过引用代码库中检索到的修复模式来修复 bug 的示例

我们还提出了一种混合补丁检索器,通过稀疏(基于关键词)和密集(基于语义)两种方式捕获代码的词汇和语义特征,从而检索出与目标bug相关的修复模式。这种语言无关的检索器不需要任何特定代码特征。

作为统一的基础模型,我们采用了预训练的面向代码的语言模型CodeT5,将其用于补丁检索和生成两个任务。RAP-Gen采用分阶段学习策略,先由补丁检索器搜索相关修复模式,然后将其传递给CodeT5补丁生成器,综合利用源代码中的bug信息和外部修复知识生成修复补丁。

我们在三个APR基准上评估了RAP-Gen的有效性,包括JavaScript linter诊断、Java bug-fix提交和Java开源项目中的真实bug。实验结果表明,RAP-Gen在所有基准上都明显优于现有的基于深度学习的方法。

总之,本文的主要贡献包括:

提出了一种新颖的检索增强补丁生成框架RAP-Gen,可以轻松地与任何序列到序列模型集成。这是首次在基于DL的APR系统中利用检索的能力。提出了一种语言无关的混合补丁检索器,考虑词汇和语义匹配,不需要任何特定于代码的特征。利用通用的面向代码的预训练语言模型CodeT5作为RAP-Gen的基础模型,同时用于补丁检索和生成任务。广泛评估RAP-Gen在三个APR基准上的性能,结果显示它显著优于现有的最先进方法。

2 相关工作

2.1 自动程序修复

过去十年来,自动程序修复(APR)技术引起了广泛关注,提出了许多减少手动调试工作的方法。传统的基于搜索(或生成-验证)的APR技术,通常利用启发式算法或遗传编程来生成大量候选修复方案,再使用单元测试进行验证。这些方法假设修复补丁可以从代码库中重建,这一假设得到了实证研究的支持。此外,还有基于挖掘修复模式的冗余技术,从现有代码库或外部问答中学习修复模式,以提高APR系统的性能。

近年来,随着深度学习在自然语言处理领域的进步,许多基于深度学习的APR技术被提出,以端到端的数据驱动方式自动化程序修复液过程。这些技术通常将APR建模为一共序列到序列的机器翻译问题。在网络架构方面,从最初的循环神经网络,到卷积神经网络、Transformer模型等,不断探索新的方法。一些技术还利用代码特定特征,如抽象语法树和测试执行诊断,来进一步改进APR性能。

在基准测试方面,Defects4J是最流行的APR数据集,包含真是的缺陷修复补丁,并提供测试用例来验证缺陷是否修复。但由于依赖测试用例,这些APR方法无法应用于新发现或难以确定性测试的缺陷。获得大规模的包含测试用例的APR数据集仍然是一个挑战。为了克服这一限制,一些APR研究转向关注静态分析缺陷,这些缺陷可以由静态分析工具标记,并且更容易大规模收集数据。此外,还有一种基于提交注释APR方法,利用关键词识别缺陷修复提交。我们在这项工作中考虑了所有这些类型的APR使用案例。

2.2 用于代码的预训练语言模型

像GPT ,BERT和T5 这样的预训练语言模型(LMs)大大提高了在广泛的自然语言处理(NLP)任务中的性能。受其成功启发,最近的许多工作试图将NLP预训练方法应用于编程语言。他们通常依赖于编码器模型(CodeBERT 和GraphCodeBERT )、解码器模型(CodeGPT 和Codex)或编码器-解码器模型(PLBART和CodeT5)。其中, CodeT5是一个统一的语言模型,它在涵盖8种不同编程语言的大规模代码语料库上进行了针对代码的预训练目标,已被证明在广泛的代码理解和生成任务上达到最先进的性能。与之前依赖于主要针对自然语言语料库预训练的LM的DL 程序补修 (APR)方法(如CURE和TFix)相比,我们提出利用具有更好代码理解能力的CodeT5进行APR。

最近也有一些探索使用大型语言模型(LLMs)进行APR的少样本学习的尝试 。据Prenner et al. 报道,基于Codex的方法在TFix数据集的200个随机实例上达到了46%的EM,而微调T5则为59%,表明少样本学习和微调结果之间仍存在差距。此外,LLMs的少样本学习需要更多的工程化努力进行提示微调和后处理,这很费时费力。另一个担忧是,Codex等LLMs不是开源的,使用它们的API可能较为昂贵,例如Davinci版本的费用为0.02美元/1000 token。LeClair等人进一步提出了一种基于图的神经网络架构,结合源代码序列和AST结构信息,以改进自动代码摘要。在我们的论文中,我们重点关注对源代码意图的总结和解释。

2.3 检索增强生成

一个通用的检索增强生成模型由三个部分组成,包括信息检索、数据增强和生成模型。它在自然语言处理中得到了广泛的研究,并被证明可以在包括问题回答和问题生成以及机器翻译在内的一系列自然语言处理任务中实现 SoTA 性能。受其成功的启发,许多研究工作适应了这种范式(也称为检索和编辑/细化框架) ,以有利于软件智能任务,包括代码自动补全,代码总结和代码生成。

3 研究方法

我们提出了一种名为RAP-Gen的新型检索辅助修补生成框架,用于自动化代码修复(APR)。该框架旨在通过利用从先前的bug修复对中检索到的相关修复模式来提高APR的性能。如图2所示,我们的RAP-Gen框架包括三个阶段:

(1) 修补检索器训练阶段,用于学习一种混合检索器,能基于词汇和语义相似性找到相关的代码修补;

(2) 修补生成器训练阶段,用于训练一个CodeT5模型,根据有缺陷的输入和检索到的bug修复示例生成修复patch;

(3) 推理阶段,预测多个修复patch,并将排名靠前的提交给开发人员进行验证。

需要注意的是,尽管检索增强生成技术已经在许多自然语言处理任务中得到探索,但将这些技术应用于APR任务并不简单,需要进行系统的适应。

第一个挑战是如何检索出有效指导APR的相关修复模式,我们构建了一种基于词汇和语义信息的混合检索器,并在表8中对其进行了分析和比较。

第二个挑战是如何为各种语言和APR场景构建一个高性能的APR模型。我们利用通用预训练模型CodeT5来实现检索和修补生成,这是一种更统一的方法,相比于之前需要不同检索器和生成器的工作。

图2:使用 CodeT5的检索增强补丁生成(RAP-Gen)框架,用于自动程序修复。我们首先通过我们的混合补丁检索器从代码库中检索相关的 bug 修复模式,该检索器同时考虑了词汇和语义的相似性。然后,我们为补丁生成器将检索到的前1个 bug 修复模式与查询 bug 补丁连接起来,以便合成一个修复补丁候选者的排名列表,供开发人员验证

4 实验设置

4.1 数据集

我们在三个APR数据集上评估RAP-Gen,分别是JavaScript中的TFix、Java中的Code Refinement和Defects4J (v1.2)。这些数据集最初都是从开源的GitHub提交中收集的,但根据不同的bug识别标准,其中TFix基于JavaScript静态分析器的诊断,Code Refinement基于修复相关的提交消息,而Defects4J基于运行测试套件。我们在表1中报告了它们的数据统计信息。

表1:三个程序修复基准的统计数据

4.1.1 TFix

TFix是一个大规模程序修复数据集,包含从550万个GitHub提交中挑选出的JavaScript代码补丁对。它包括52种错误类型,这些错误类型是由静态分析器ESLint检测到的。除了错误类型,它还提供了丰富的错误注释,如错误消息和定位的错误行,因此不需要进行故障定位。

为了准备输入序列,我们遵循之前的方法,将所有错误信息与有缺陷的代码补丁组合成一个单一的文本片段。

fix {error type} {error message} {error context: Code Line N-1 + Buggy Line N + Code Line N+1}

对于目标序列,它是通过将错误行替换为修复后的行而得到的。在数据处理过程中,我们观察到了数据拆分内部和数据拆分之间的重复问题,我们过滤掉了这些重复项,得到了一个去重后的TFix版本。

基线模型

我们将RAP-Gen与现有的基于深度学习的APR模型SequenceR和CoCoNuT进行比较。此外,我们还将一个大型预训练模型T5-large与TFix进行细调,以取得最先进的性能。

评估指标

我们报告Exact Match准确率和BLEU-4分数来评估程序修复性能,遵循之前的做法。我们还采用Error Removal指标,考虑各种形式的修复。

4.1.2 Code Refinement

Code Refinement 包含函数级别的bug-fix对,最初是从2011年3月至2017年10月间的公共GitHub存档中收集的。他们使用Google BigQuery APIs识别所有提交消息中包含"fix"、"solve"、"bug"、"issue"、"problem"或"error"等关键词的Java提交,以确保收集到的bug-fix函数对的质量。他们通过使用索引令牌如TYPE1、VAR1、METHOD1等来规范化函数。图3(b)中给出了一个数据示例。该数据集包含两个子集,根据代码令牌的数量分为:小集为≤50个令牌,中集为50<令牌数≤100。由于没有提供bug定位信息,整个代码片段被视为模型的输入序列。目标序列是整个代码片段的修复版本。

基线和指标

我们将我们的RAP-Gen与基于Transformers 的预训练编程语言模型进行比较。这些模型包括仅编码器模型,如RoBERTa(code)、CodeBERT 和GraphCodeBERT 。这些仅编码器的模型需要随机初始化的解码器来生成修复。此外,我们还比较了编码器-解码器Transformer模型,如PLBART和CoTexT 。NSEdit 是一个编码器-解码器语言模型,编码器和解码器分别初始化自CodeBERT和CodeGPT ,通过神经-符号编辑序列进行微调,在Code Refinement数据集上排名最先进。我们应用BLEU-4和Exact Match来评估Code Refinement数据集。

4.1.3 Defects4J

Defects4J 是最广泛采用的APR基准之一,包含17个开源GitHub项目中的835个真实bug修复补丁。每个bug修复示例都附有测试用例来验证修复。Defects4J中一个bug示例如图3(c)所示,其中"-"表示需要修复的有bug的行,"+"表示开发人员提交的正确修复。有bug的行及其相应的代码上下文组成源输入序列,而目标序列是修复后的行。由于Defects4J只有测试集,我们使用SelfAPR 使用自我监督学习方法整理的项目特定训练数据。具体来说,Ye等人提出了16条在Defects4J正确过去版本上进行扰动的规则,构造了1,039,873个合成的bug修复Java补丁。我们使用其中可公开获得的830,240个训练数据。在测试方面,我们遵循他们的设置,在Defects4J v1.2和v2.0的818个bug上评估我们的模型(表1),其中包括有地面真实故障定位(完美FL)和使用基于光谱的FL工具如Gzoltar预测的FL。

基准和指标

我们将RAP-Gen与一系列最新的基于深度学习的APR模型进行比较,包括SequenceR, CoCoNuT, CURE, RewardRepair, Recoder, DLFix, DEAR, BugLab和SelfAPR。在评估过程中,我们根据单元测试和手工验证计算Defects4J上可以正确修复的bug数量。我们首先运行测试套件来自动识别每个bug的可行的正确补丁,然后进行手工检查以完全验证其正确性。我们的RAP-Gen的正确预测结果包含在我们的工件中。对于基线的结果,我们引用了DEAR中DLFix和DEAR的结果,以及SelfAPR中其他结果。

4.2 实现细节

我们采用了包含12个编码层和12个解码层的CodeT5-base模型[70]作为RAP-Gen的基础模型,参数量为220M。我们使用PyTorch实现了RAP-Gen,并使用AdamW[37]优化器进行训练。为了训练神经网络组件,我们在谷歌云平台的NVIDIA A100-40G GPU上进行了实验。对于每个基准测试,我们使用对比损失LinfoNCE对DPR检索器进行50个纪元的微调,批量大小为64,学习率为2e-5。我们使用序列生成损失Lce对RAP-Gen生成器进行30个纪元的微调,批量大小为32,学习率为5e-5。这些最佳设置是通过网格搜索进行超参数调整得到的:批量大小为(16,32,64),学习率为(1e-4,5e-5,2e-5)。DPR检索器的训练时间为5-9小时,取决于数据集的训练规模,RAP-Gen生成器的训练时间在2天以内。对于基于词汇的检索器,我们使用了一个开源的Python库5来实现BM25,可以在CPU上利用多进程在一小时内高效训练。在推理过程中,我们对TFix和代码优化使用了beam search算法,beam大小为5,对Defects4J使用beam大小为100。

4.3 研究问题

为了调查RAP-Gen在 APR 任务上的有效性, 我们寻求回答以下研究问题 (RQ):

RQ1: 与基于深度学习的 APR 模型在 TFix 上的比较研究。与其他基于深度学习的 APR 方法相比, RAP-Gen在修复 JavaScript 林挺标记的编程错误方面的表现如何?RQ2: 分析 RAP-Gen 在 TFix 上的预测结果。RAP-Gen对不同类型的错误和补丁长度进行修复的情况如何? RAP-Gen在修复 bug 时采用了哪些修复操作?RQ3: 与基于深度学习的 APR 模型在代码优化上的比较研究。与其他基于深度学习的 APR 方法相比, RAP-Gen在修复与 Java 提交相关的 bug 方面的表现如何?RQ4: 我们混合式补丁检索器的分析。我们的混合式补丁检索器能否找到相关的修复模式来指导 APR?RQ5: 与基于深度学习的 APR 模型在 Defects4J 上的比较研究。与其他基于深度学习的 APR 方法相比, RAP-Gen在修复开源项目中的 Java bug 方面的表现如何?

5 实验结果

5.1 RQ1:TFix 与基于DL的APR模型的比较研究

优化后的 TFix 评估

原始 TFix 基准采用了对 52 种错误类型的精确匹配(EM)准确率的直接平均作为主要指标。然而,如表 4 所示,这些错误类型的分布非常不平衡,例如主要错误类型"no-invalid-this"有 16,166 个实例,而最小错误类型"no-new-symbol"只有 10 个实例。因此,采用加权平均更加合理,以考虑错误类型的分布。此外,我们发现它的精确匹配评估存在另一个局限性,即如果预测的修复包含比参考修复多一个空格或换行,就会被视为错误的精确匹配。然而,额外的空格对 JavaScript 程序的正确性没有影响。因此,我们提出使用去除空格的加权平均 EM(EM w/o spaces),在计算 EM 之前对空格进行标准化,以排除空格不匹配的影响。由于我们发现 TFix 数据集存在重复问题,我们还报告了其去重版本的结果。

CodeT5 结果

我们将 CodeT5 模型与其他深度学习基线模型在 TFix 上进行比较,结果如表 2 所示。对于原始指标平均 EM(含空格),CodeT5-base(50.88)的准确率也优于 T5-large(49.33),尽管它的模型尺寸大得多(约 3.5 倍:770M vs. 220M)。 如果我们关注更合理的平均 EM(不含空格),CodeT5-base 的性能显著提升,在去除空格的情况下,它的绝对准确率提高约5个百分点(49.35→54.30),超过了 T5-large。基于加权平均 EM(不含空格),CodeT5-small(50.31)和 CodeT5-base(53.57)都优于所有基线模型,包括 T5-large(49.70)。这表明在大规模源代码上进行面向代码的预训练的 CodeT5 模型对程序有更好的理解。对于 TFix 评估,我们使用 EM 来表示加权平均 EM(不含空格)。我们进行了一项消除错误信息(包括错误类型和错误消息)的消融实验,结果显示 CodeT5-small 和 CodeT5-base 模型都有一致的性能下降,这表明向 APR 模型提供需要修复的错误类型是很有帮助的。

表2:CodeT5与原始 TFix 的比较结果

RAP-Gen 结果

我们在表 3 中报告了 RAP-Gen 模型在去重的 TFix 基准上的结果,由于数据大小的变化,结果略有不同。结果显示,RAP-Gen 明显优于 T5-large(49.58→54.15 EM)。这表明检索增强生成是一种可行有效的 APR 方法,语义信息和词汇信息对于检索相关修复模式都是至关重要的。我们在图 3(a)中展示了一个案例,可以观察到 RAP-Gen 在检索修复模式的指导下成功修复了错误,而没有检索的 CodeT5 给出了错误的修复。

表3:RAP-Gen 在已删除 TFix 上的性能。T5-large 和 CodeT5-base 的结果与表2不同,这是由于重复数据删除造成的

图3:修复三个 APR 基准测试的 Bug 示例,其中 RAP-Gen 成功地修复了 Bug,而 CodeT5未能做到这一点。

错误移除评估

虽然精确匹配可以确保机器生成的补丁的正确性,但它可能太严格,无法考虑其他形式的正确修复。因此,我们采用错误移除指标,如果错误被移除且没有引入新错误,则将修复视为正确。错误检测基于静态分析器 ESLint。我们在 6,793 个实例上报告了错误移除、EM 和 BLEU-4 的结果,如图 4 所示。我们发现 RAP-Gen 显著提高了错误移除的准确率,超过了 T5-large(69.30→78.80)。与 EM 和 BLEU-4 相比,这种更大的提升表明 RAP-Gen 更擅长生成各种形式的良好修复。此外,EM 与较为宽松的错误移除指标很好地吻合。

图4:在 TFix 上的错误消除比较,其中错误消除与精确匹配和 BLEU-4分数很好地一致

5.2 RQ2:TFix上RAP-Gen的分析

错误类型的性能细分

我们在表 4 中列出了在去重后的 TFix 数据集上 52 种错误类型的性能细分。RAP-Gen 在 40/52 种错误类型上优于之前的最先进模型 T5-large。特别是对于主要错误类型"no-invalid-this",RAP-Gen 将其精确匹配从 T5-large 的 37.48 提高到 44.13,即修复了 107 个额外的错误实例。总的来说,RAP-Gen 在模型大小更小的情况下,比 T5-large 正确修复了更多 478 个 bug。

表4:TFix 上52种错误类型的性能分解

修复操作分析

我们分析了我们的模型在 TFix 数据集上执行的修复模式。我们观察到,与代码插入和替换操作相比,修复操作中删除操作所占比例很大。我们发现修复操作包括代码插入(12.5%)、替换(8.1%)、删除(47.9%)、插入和替换(6.9%)、插入和删除(8.2%)、替换和删除(7.2%)以及三种方式混合(9.2%)。早期的研究也反映,删除操作是最常见的修复模式之一。此外,我们发现一种主导的修复操作是错误行(EL)移除,即简单地从有 bug 的代码中移除错误行,在测试集中占 23% 左右。我们在表 5 中展示了模型在执行这个操作方面的表现。我们观察到,与 CodeT5 的 67 和 T5-large 的 71 相比,RAP-Gen 取得了最高的精度、召回率和 F1 分数,并且假阳性数量最低(56)。这表明RAP-Gen 能够学习更多样化的 bug 修复模式,而不是过度依赖简单的错误行移除模式。

表5:TFix 的误差线消除操作分析

补丁长度分析

我们分析了补丁长度的影响,如图 5 所示。图 5(a) 显示了根据修复结果对补丁长度进行分组的累积分布。我们发现,RAP-Gen 成功修复的补丁倾向于更短。图 5(b) 显示了正确修复的分布,RAP-Gen 特别擅长修复 40 到 60 个标记的补丁,比 T5-large 修复更多 bug。

图5:(a) : 程序的累积分数,按照源错误补丁中令牌的数量,按照 RAP-Gen 是否能够准确修复。(b) : RAP-Gen 和 T5-large 的正确补丁分布在令牌数量上。

5.3 RQ3:与基于深度学习的自动程序修复模型在代码细化任务上的比较研究

我们在表6中报告了代码细化任务的比较结果。所有基线结果都直接从原始论文中获得。我们首先观察到"盲目复制"给出了很高的BLEU-4分数,但精确匹配为零,表明有缺陷的代码及其修复之间存在很大的重叠,因此精确匹配应该作为主要指标。在基线中,NSEdit是一个非常出色的模型,在小型数据集上有最佳结果(24.04 EM),而CodeT5在中型数据集上给出了最佳结果(13.96 EM)。与小型数据集相比,在中型数据集上获得较低的结果表明修复较长的有缺陷函数更加困难,这与图5(a)中的观察结果一致。总体而言,RAP-Gen在两个子集上都取得了新的最佳结果,小型集合为24.80 EM,中型集合为15.84 EM。这再次证实了检索的修复模式为程序修复提供了有用的信号,而基于词汇和语义信息的混合检索器更加健壮。图3(b)显示了一个案例,其中检索到的修复模式(错误行删除)帮助RAP-Gen成功修复了该bug。

表6:RAP-Gen 在代码细化中的性能

5.4 RQ4:混合补丁检索器的分析

我们在表7中探讨了不同检索模块如何影响基于检索增强的生成设置中的自动程序修复性能。我们首先与随机基线进行比较,通过从代码库中随机检索bug-fix对。与"无检索器"相比,性能一直下降,表明随机检索的修复模式无法为自动程序修复提供有用的指导信号。

表7:RAP-Gen 中检索模块的作用

然后,我们将我们的混合检索器与不同的检索器进行比较:基于BM25的稀疏检索器,以及基于CodeBERT或CodeT5的密集检索器。我们观察到,基于CodeT5的检索器优于BM25或基于CodeBERT的检索器,而我们的混合检索器结合BM25和CodeT5实现了最佳的自动程序修复性能,验证了我们在RAP-Gen中检索器模块设计的有效性。

我们进一步分析了我们的检索器在词汇和语义匹配方面的性能。我们使用BLEU-4分数来衡量查询和检索到的补丁之间的子标记重叠度来评估词汇匹配,而对于语义匹配,我们计算它们由我们的fine-tuned DPR检索器编码的密集向量之间的余弦相似度(CosSim)。表8显示了我们的检索器在TFix和代码细化基准上的性能。第一行表示通过从代码库中随机检索bug-fix对获得的下界性能,我们观察到这个随机基线在词汇和语义匹配方面都达到了较低的分数。

表8:词法(BLEU-4)和语义(CosSim)在 TFix 和代码精化基准上的检索匹配结果

在词汇匹配方面,BM25在TFix上优于DPR(基于CodeT5),但在两个代码细化子集上有较差的性能。我们预期这是由于TFix和代码细化之间数据的差异造成的,后者使用了混淆的标识符(如VAR1、VAR2、...),这阻碍了基于词汇的BM25检索器的性能。混合检索器在所有数据集上实现了最佳的词汇匹配,表明语义信息可以补充词汇信息。在语义匹配方面,DPR在所有数据集上都取得了最佳结果,这并不令人意外,因为它针对相同的目标进行了优化。值得注意的是,我们的混合检索器在语义匹配方面略低于DPR,但远高于BM25,这意味着它可以平衡词汇和语义信息,并比仅依赖词汇的检索器更加健壮,后者对标识符命名的选择很敏感。

5.5 RQ5:与DL为基础的APR模型在Defects4J上的对比研究

RAP-Gen的结果

RAP-Gen的结果。我们将RAP-Gen与其他最新的DL为基础的APR模型在Defects4J v1.2和v2.0数据集上进行对比,结果如表9所示。我们考虑了两种设置:基于谱系的错误定位(FL)和完美FL。在完美FL设置下,我们的RAP-Gen在修复bug数量上达到了新的最佳水平,v1.2修复72个bug,v2.0修复53个bug,均超过了其他基线模型。在基于谱系的FL结果上,RAP-Gen也取得了第二好的性能。综合v1.2和v2.0的bug,RAP-Gen总共修复了74个bug,超过了其他模型。这些结果证明了RAP-Gen在DL为基础的APR模型中的优越性。RAP-Gen还具有语言无关的优势,可以推广到其他APR用例。

表9:RAP-Gen 在 Defects4J v1.2和 v2.0上的性能

我们发现RAP-Gen可以补充现有的APR模型,在Defects4J上修复了一些之前无法被其他模型解决的独特bug。我们展示了一个成功修复Chart-9bug的案例,结果与开发者的修复不同。

从不同修复模式中检索的影响

我们分析了从不同修复模式中检索bug修复样本会如何影响APR性能。如图6所示,我们选取了39个在Defects4J v1.2和v2.0数据集上CodeT5无法修复(红色)但RAP-Gen可以修复(绿色)的bug。对于修复模式的分类,我们基于SelfAPR 提出的16条扰动规则,并使用其训练集作为单独的检索代码库。我们从每个规则或修复模式(标记为P1到P16)的代码库中检索top-1的bug修复样本,并检查在RAP-Gen中使用这些检索信号是否可以改进CodeT5的性能。

图6:从 Defects4J v1.2和 v2.0中的39个 bug 中从各种修复模式中检索的效果,RAP-Gen 可以修复(绿色) ,CodeT5不能修复(红色)。我们在 X 轴上表示每个 bug,并使用颜色来表示在 Y 轴上不同检索方案下的修复结果。

从图6中,我们观察到在RAP-Gen中从不同的修复模式进行检索通常有助于纠正CodeT5在Defects4J bug上的预测。我们发现,对于v1.2的大多数bug,从多种不同的模式进行检索都可以对其进行修复,而对于v2.0,有一些bug只有少数几种修复模式适用,例如Closure-150的P16和JacksonDatabind-54的P5。在各种修复模式中,我们发现"插入现有块"的P13和"删除语句"的P14是适用于大多数bug的,表示这些是修复Defects4J bug的关键修复模式。

转述:吴德盛

0 阅读:10

互联不一般哥

简介:感谢大家的关注