用于自动程序修复代码感知神经机器翻译

互联不一般哥 2024-05-31 21:32:58

URE: Code-Aware Neural Machine Translation for Automatic Program Repair

Nan Jiang1, Thibaud Lutellier2, Lin Tan3

1,3Purdue University, USA

2University of Waterloo, Canada

引用

Jiang, Nan, Thibaud Lutellier, and Lin Tan. "Cure: Code-aware neural machine translation for automatic program repair." 2021 IEEE/ACM 43rd International Conference on Software Engineering (ICSE). IEEE, 2021.

论文:https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=9401997

摘要

本文提出了CURE,一种新的基于NMT的APR技术,它有三个主要的新颖之处。首先,CURE在大型软件代码库上预训练编程语言(PL)模型,以便在APR任务之前学习类似于开发人员的源代码。其次,CURE设计了一种新的代码感知搜索策略,通过关注可编译补丁和长度接近错误代码的补丁来找到更多正确的修复。最后,CURE使用子词标记技术生成包含更多正确修复的更小的搜索空间。

1 引言

自动程序修复对于减少人工软件调试工作至关重要。神经机器翻译是一种广泛用于自然语言处理(NLP)任务的技术,最近已被采用,可以在给出错误源代码的情况下自动生成正确的代码。由于NMT模型强大的学习能力,基于NMT的APR技术优于大多数现有的基于规则的方法。NMT模型利用深度学习技术将有缺陷的源代码自动编码为潜在空间中的中间表示,然后将编码后的表示解码为目标正确的代码。通过最小化损失函数和更新权重参数,NMT模型学习捕捉错误代码和正确代码之间的隐藏关系,而无需手动设计修复模式或特征模板。

基于搜索的APR方法(包括基于NMT的技术)要生成正确的修复,需要满足两个条件:(1)正确的修复必须在搜索空间中,即APR方法可以生成的所有补丁的集合;(2)搜索策略必须有效,能够在合理的时间内找到正确的修复。假设在搜索空间中有一个正确的patch,则希望搜索空间较小,以便更容易找到正确的patch。尽管是最有效的APR方法之一,但基于NMT的方法仍然无法修复许多错误。

与自然语言文本相比,源代码有自己的特点,比如严格的语法、代码语义和无限可能的标识符。这些特征对NMT模型自动修复错误提出了独特的挑战。

首先,源代码的严格语法使NMT模型难以学习。一个主要原因是现有的技术,从有bug的代码片段和相应的修复正确的代码片段中学习(通常每个bug几行到几十行),而不使用整个源代码库(通常每个项目数百万行代码)。因此,现有的基于NMT的APR方法对编程语言的严格语法和开发人员如何编写代码的大图景了解有限。

错失的机会是双重的:(1)现有的技术无法利用大量可用的源代码,(2)它们只看到部分代码片段(这通常是语法上不正确的),并且错过了完整的方法、类和项目的大局。例如,对于将“while (x){”替换为“while (y){”的修复,此代码片段中的左括号“{”在语法上是不正确的,即缺少右括号“}”。

数据表明,这种无效是显而易见的。例如,由最先进的基于NMT的APR模型生成的补丁中,高达67%-97%的补丁是不可编译的,在错误的补丁上浪费了宝贵的资源。图1显示了QuixBugs中的一个bug和一些由CoCoNuT生成的排名靠前的补丁。尽管生成了20,000个补丁,但CoCoNuT仍未能为该错误生成正确的补丁,其中一个重要原因是大量不可编译的补丁。我们提出的基于代码感知的NMT方法会为这个bug自动生成一个正确的补丁(与绿色突出显示的+行相同)。这些不可编译补丁的级别很高,因为现有的基于NMT的APR技术专注于将有缺陷的代码片段翻译为正确的代码片段,这些代码片段是部分代码段,而不是完整的方法或程序。由于它们无法看到整个程序或编程语言的全貌,因此它们生成了许多带有语法错误的补丁。

图1:由基于NMT的模型生成的不可编译补丁,以及它们在QuixBugs中的等级

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

在一个非常大的软件代码库(来自1700个开源项目的404万个方法)上预训练用于APR的PL模型的方法,以捕获代码语法和类似开发人员的源代码。一个新的APR架构,结合了预训练的PL模型和NMT架构,以学习代码语法和修复模式。一种新的码感知波束搜索策略,该策略使用有效标识符检查和长度控制策略来找到更多正确的修复。一种新的子词标记在APR任务中的应用,有效地解决了面向对象的问题。一种新的APR方法,CURE,结合了上述技术,以及它对两个广泛使用的基准(Defects4J 和QuixBugs)的评估,其中CURE修复了最多的错误,分别为57个和26个,优于所有现有的APR工具。CURE是第一个基于NMT的方法,它在Defects4J上优于所有最先进的APR方法。

2 技术介绍

为了解决引言中描述的挑战,我们设计并应用了三种新技术,即子词标记化以改善搜索空间,一种编程语言模型,用于学习类似开发者的源代码并提高补丁排名,以及一种新的代码感知波束搜索策略,以提高补丁排名并生成更多正确的补丁。

图2概述了本文的方法。CURE包括三个阶段:训练、推理和验证。在训练阶段,CURE从开源项目中提取方法,称为PL训练数据,并对其进行标记。与之前的工作不同,我们使用子词标记,这产生了更小但更准确的搜索空间,其中包含更多正确的补丁。CURE使用这些标记化的方法来训练一个新的编程语言模型,该模型学习具有正确语法的开发人员源代码。CURE还将从开源项目的提交历史(称为补丁训练数据)中提取的错误行、上下文和正确修复标记为标记序列。我们使用这些序列来微调k个APR模型的集合。每个APR模型都将PL模型与上下文感知神经机器翻译(CoNuT)模型相结合。

在推断阶段,用户向CURE提供有bug的项目以及有bug行的位置。CURE对有bug的行和上下文行进行标记,然后分析源代码以提取在有bug行范围内的有效标识符列表。补丁生成模块使用新的代码感知波束搜索策略生成候选补丁列表。这个新算法在运行中丢弃许多不相关的补丁(即,一旦生成无效令牌),并惩罚不太可能正确的补丁(例如,与错误行长度非常不同的补丁),这节省了大量资源,并允许CURE更深入地搜索正确的补丁。

图2:CURE整体工作流程

2.1 数据提取

CURE使用两种不同类型的训练数据。首先,GPT PL模型是在从开源Java项目中提取的数百万种方法上进行训练的。其次,CURE为APR任务微调PL模型。此步骤需要APR特定的训练数据(即,错误行,上下文和正确修复)。我们使用的是椰子在GitHub上共享的训练数据。CoCoNuT的作者从开源存储库中提取这个数据集,并根据提交消息中的关键字(“fix”、“bug”和“patch”)识别有缺陷的提交。他们还使用提交消息反模式(“重命名”、“清理”、“重构”、“合并”、“拼写错误”和“编译器警告”)清理数据集。与CoCoNuT类似,我们使用围绕有bug行的方法作为上下文。

2.2 代码表示和标记化

单词级标记化:为了将有bug的、上下文的和固定的行标记为标记序列,CURE首先使用增强的单词级标记化,用空格、驼色字母、下划线、字符串和数字(0和1除外)分隔代码行。

词汇外问题:单词级标记化后的词汇量比NLP中常用的词汇量要大,并且测试集仍然包含2%的OOV标记。排除稀有令牌对于源代码来说是有问题的,因为OOV令牌可能是重要的特定于项目的令牌。排除这些令牌使得NMT模型难以修复这些新项目中的错误。

一些现有的基于NMT的APR模型不生成OOV令牌,失去了修复更多bug的机会。SequenceR使用一个特殊的令牌作为OOV令牌的占位符,然后使用复制机制来重建它们。复制机制将占位符标记替换为输入错误行中最可能的标记。然而,此解决方案将无法生成一些补丁,因为它只能复制出现在错误行中的令牌。

2.3 候选补丁生成

在选定错误代码的适当修复模板后,我们利用UniXcoder的填空功能生成正确的代码标记。UniXcoder是一个先进的针对编程语言的预训练模型,旨在支持代码理解和生成任务。它采用掩码语言建模(MLM)作为其预训练目标,专注于预测被掩码的标记。这一预训练目标被用来填补前一步骤中生成的空白,以产生关于错误程序的候选修补程序。

掩码的预测主要取决于掩码周围的标记。如果模型的输入中包含正确的标记,这个标记就更有可能被选为潜在的结果之一。然而,当只有单个带掩码的错误行而没有任何上下文代码时,掩码预测的准确性会受到限制。在这种情况下,可能会缺少修复错误所需的信息。为了获得更多关于每个错误行的上下文,我们提取包含该错误行的方法,并将整个方法连同带掩码的错误行一起作为UniXcoder的输入。由于错误行中的一些标记被替换为掩码,这些标记可能包含了对掩码预测有用的关键信息,所以我们在输入的第一行以注释形式添加了原始错误行(即在行前加上"//")。这条注释的错误行后面是包含错误的方法,二者一起构成了最终的输入。

对于每个输入,UniXcoder模型将生成N个候选修补程序,其中N表示beam大小,是GAMMA中的一个可调参数。选择一个相对较大的beam大小可以增加生成正确修补程序的可能性。

(a)Closure 62的错误行和正确修复

(b)词级标记的结果,错误的行和正确修复

(c)错误行的子词级标记化结果和正确修复。

图3:使用Defects4J中Closure 62的词级标记和子词标记的标记化结果

子词标记化:为了解决OOV问题并减少词汇量,我们使用了字节对编码(BPE),这是一种无监督学习算法,通过迭代合并最频繁的字节对来找到语料库中最频繁的子词。BPE已被用于许多NLP任务中,对于减少词汇量和有效缓解面向对象问题非常有用。

图3显示了推理阶段的一个示例,演示了子词标记化的有效性。以' - '开头的行是有bug的行(输入),以' + '开头的行是正确的修复。图3(a)显示了Defects4J中一个真实bug的源代码,而图3(b)显示了使用增强的词级标记化后的代码。图3(c)显示了通过子词标记化进行标记的相同代码。在图3中,用空格分隔的每个结果都是一个不包含“-”和“+”符号的标记。

当只使用增强的词级标记化时,变量“charno”是一个OOV标记。因此,CoCoNuT和SequenceR无法修复此错误,因为CoCoNuT无法生成OOV令牌,而SequenceR无法通过复制机制正确修复此错误。通过子词标记化,“charno”被分成两个标记,这两个标记都出现在词汇表中—“char@@”(“@@”表示该标记需要与下面的标记连接)和“no”,从而使CURE能够为此错误生成正确的补丁。

通过应用子词标记化,我们使用更小的词汇表来形成更小但更好的搜索空间,其中包含更多正确的补丁。第V-B3节评估我们的子词标记化方法的影响。

2.4 编程语言模型

为了解决学习类似开发者的源代码的挑战,我们在开源程序上训练语言模型,称为编程语言模型(PL模型)。PL模型优化了令牌序列作为实际代码片段的概率。我们使用生成预训练转换器(GPT)进行PL建模,因为GPT已被证明可以提高许多不同NLP任务的性能。

预训练PL模型允许从补丁学习中分离编程语言学习。这样做的好处是双重的。首先,GPT学习是无监督的,只需要完整的方法;因此,可以自动准确地提取大量数据进行训练。其次,在微调期间,APR模型已经知道PL语法(多亏了PL模型),这使得微调更加有效。

给定一个表示方法的记号序列,x = (xi,…),x n),其中xi为方法序列x中的token, PL建模目标是使平均似然最大化:

其中θ表示PL模型的可训练权矩阵。P (xi |x1,…,xi - 1;θ)是令牌xi是下一个令牌的条件概率,给定一个序列x1,…,xi - 1,由权重为θ的PL模型计算得到。在高层次上,PL模型训练的目标是找到最佳权值(Φ),以便令牌序列x1,…,xn表示项目中真实方法的xn比其他序列获得更高的LGPT分数。由于流行的开源项目中的方法主要是格式良好的正确代码块,因此我们使用它们来训练我们的PL模型,以了解给定的令牌序列是否可能形成真实世界的代码(可编译并且看起来像程序员编写的)。

2.5 用PL模型对APR进行微调

在预训练PL模型之后,CURE通过将GPTPL模型与NMT模型结合作为APR模型,对APR任务的GPTPL模型进行微调。我们使用CoNuT作为CURE的NMT架构。

APR模型将错误行及其上下文作为输入,旨在生成正确的补丁。在微调过程中,训练APR模型学习从有bug的行和上下文(例如,有bug的方法)到正确修复的转换。用xb = (x b1,…,xbn)表示有bug的行,x = (x1,…xcn)表示上下文,y = (y1,…,yfn)表示正确的修复,其中b1,…,bn为上下文中出错行的索引,cn和fn分别为上下文和正确修复的长度。

我们表示PL模型的权重为θ,CoNuT的权重为Φ。APR模型通过更新θ和Φ进行微调,以最大化以下平均对数似然

P (yi|x, xb,y0,…, yi-1;θ,Φ)是由权重为θ和Φ的APR模型计算出的条件概率,其中yi是序列(y0,y1, ...,yi-1)之后的token。对于正确修复中的第一个标记,概率是给定y0的标记y1的条件概率,其中y0是正确修复前的标记,即xb1-1。例如,整个方法“kth()”是图1中的上下文,而有bug的行和正确的修复都是从上下文中的同一索引开始的,而y0是“return”语句前面的标记{。

为了防止PL模型丢失它在预训练期间学习到的信息,我们将语言建模(例如,LGPT)作为调优过程的辅助目标。它还提高了精调模型的泛化能力。因此,通过最大化组合平均对数似然对APR模型进行微调:

微调阶段的目标是找到参数θ和Φ的最佳集合,以最大化训练数据中所有错误行、上下文和正确修复的LAPR。

在训练模式中,APR模型以预训练的GPT模块(PL模型)和patch训练数据作为输入。补丁训练数据包括错误行、上下文和正确的修复。我们训练多个epoch的APR模型(即对训练数据进行多次传递),以获得权重θ和Φ的最佳组合。

在推理模式中,APR模型只能访问有bug的行及其上下文,并输出表示补丁的令牌序列。图4显示了我们的组合APR模型的体系结构的简化视图,以及如何在推理模式中使用该模型。我们的APR模型由两个部分组成:PL模型(GPT)和NMT模型(CoNuT)。

2.6 整体学习

先前的工作表明,集成学习,即组合多个模型,使基于NMT的APR方法能够修复更多的错误:当模型数量从1个增加到20个时,正确修复的错误数量从22个增加到44个。因此,我们将(1)具有不同超参数的模型和(2)具有两种不同架构(CoNuT和FConv)的模型结合起来进行集成学习。GPT PL模型是通用的,因为它代表了整个PL。因此,每个APR模型都从相同的PL模型开始,对其进行微调,并将其与具有不同超参数的CoNuT或FConv体系结构结合起来(图2的步骤③)。

为了平衡计算成本和调优效率,我们使用随机搜索在合理范围内选择不同的超参数值(例如,卷积层数,卷积维数和dropout),并在一个epoch调整每个模型。基于验证数据上每个模型的困惑度(即模型预测实例的程度的度量),我们选择top k模型进行集成学习,并继续训练它们直到收敛。

2.7 码感知波束搜索策略与贴片生成

补丁生成的目标是在给定错误行及其上下文的情况下以最高概率生成序列。APR模型每次用其概率生成一个令牌。搜索概率最高的序列在输出序列的长度上呈指数级增长。因此,我们需要一种有效的搜索策略来寻找具有高概率的序列。

束搜索是一种经过优化的贪婪搜索策略,是NMT中最常用的搜索策略。波束搜索只保留搜索树中n个(n为波束大小,波束搜索的一个超参数)最优节点,而不是所有节点,以便在每一步展开并删除其余节点。香草束搜索的一个主要问题是,它只考虑模型提供的对数概率来生成下一个令牌。由于关于代码的其他信息(例如,作用域内的变量)对于APR模型是不可用的,因此它通常会为作用域外的变量生成一个高分,从而产生一个不可编译的候选补丁。

为此,我们设计了有效标识符检查和长度控制两种技术,使波束搜索码可感知。

有效标识符检查:在特定的Java代码片段中,只有少数令牌是有效的,因为正确的代码必须遵循Java语法和编译规则。为了只生成有效的标识符,CURE首先使用静态分析来分析和提取有效的标识符。

在每个解码步骤中,NMT模型输出词汇表中所有标记的概率分布。CURE新的有效标识符检查策略首先分析已经生成的令牌序列,以获得需要生成的下一个令牌的“前缀”。如果生成的令牌序列不包含任何前缀(即,下一个令牌将是新标识符的开始),则“前缀”将被设置为空字符串。然后,基于所有可能的前缀与其有效的后续令牌之间的映射,valid-identifier-check策略修改概率分布,并将无效令牌的概率设置为-inf。通过这样做,有效标识符检查策略丢弃了许多不可能的节点,增加了找到正确补丁的可能性。

(a)香草光束搜索与使用有效标识符检查的光束搜索,光束大小为2

(b)在同一bug中,使用长度控制的香草束搜索与使用长度控制的束搜索,但束大小为1000

图4:使用普通光束搜索和具有验证标识符检查和长度控制策略的光束搜索的示例。

图4(a)说明了我们的代码感知光束搜索如何优于普通光束搜索。正确的修复方法是“m ax_ending_here=math”。Max(0, Max_ending_here)”和输出序列的开始部分(“M ax_ending_here =”)已经在步骤1到6中生成。到达正确修复点的路径用绿色箭头标记,波束搜索策略考虑的节点用浅灰色标记。

在步骤7中,根据APR模型,两个最有可能的节点是“…”。Max“和”…我的“,哪里”……,指的是已经生成的“max_ ending_he =”。然而,在第8步,“…”的平均对数似然。是的。,即图4(a)左子图中绿色路径表示的序列,小于“…”的序列。最大_“和”…maxCaMeL”,所以香草光束搜索会放弃它。因此,包含正确修复的整个子树将被排除。

相比之下,使用我们的有效标识符检查策略,“…”的平均对数似然。maxCaMeL "被设置为- iif,因为没有以" maxCaMeL "开头的有效标识符。因此,我们的码感知波束搜索一直在搜索节点的子树。Math”,这将导致正确的修复。

长度控制:在我们的训练数据中,大多数正确的修复具有与错误行相似的长度。我们发现在270万个补丁训练数据中,75%的bug的长度差小于或等于5个令牌。这意味着大多数时候,正确的修复是对有bug的行进行小的修改,而更复杂的更改则不太常见。

因此,我们使用长度控制策略,通过惩罚短补丁和长补丁来生成相似长度的bug行补丁。在解码的每一步,长度控制策略计算已经生成的序列的长度。如果当前长度比错误线小得多,它会减少“”的对数可能性,以防止该补丁到达末尾。如果当前长度已经比有bug的行大得多,它会增加“”提示此补丁结束的对数可能性。

图4(b)说明了这个问题。bug与图4(a)相同,但波束尺寸更大,为1000。在步骤2中,序列“{}”到达“”令牌。使用香草光束搜索,补丁“{}”具有较低的平均对数概率,但仍然在前1000中,这被添加到候选补丁中,因为光束大小很大(1000)。这样的低分数补丁占用了有价值的插槽,并阻止正确的补丁被选中。

虽然CURE专注于修复与错误行长度相似的错误,但我们的长度控制策略是通用的,可以通过修改惩罚权重来生成更长的补丁。考虑到APR的复杂性,分别修复类似长度的错误和其他错误可能是分解这个复杂任务的有效方法。

2.8 补丁验证

在APR模型生成候选补丁后,我们将标记序列重构为代码语句。我们首先将以“@@”结尾的标记连接到它们的后继者,这是从子词到词的重构。然后,我们从有bug的代码文件中提取供体代码,以重建抽象的令牌(数字和字符串)。

重构的语句根据其令牌的平均对数概率进行排序,然后插入到有bug的代码文件中以替换有bug的行。每个打过补丁的项目都会被编译以过滤掉不可编译的补丁,然后我们运行测试套件,直到我们找到一个满足两个条件的补丁:(1)通过有bug的项目通过的所有测试用例,(2)通过至少一个在有bug的项目上失败的测试用例,这与之前工作中使用的验证标准相同。

3 实验评估

3.1 实验设置

研究问题。在本文中,我们研究以下研究问题:

RQ1:CURE与最先进的APR技术相比表现如何?

RQ2:CURE组件的贡献是什么?

评估数据集。对于PL训练数据,根据GHTorrent,本文从GitHub下载了所有(1700个)开源Java项目,这些项目在Defects4J中出现第一个错误之前至少有一次提交,并将它们回滚到2006年之前的版本,以避免使用未来的数据。对于Patch Training Data,本文使用在GitHub上共享的CoCoNuT的训练数据作为我们的Patch Training Data,它是从45,180个Java项目中提取的。这些Java项目是用于PL训练数据的项目的超集,因为我们需要更多的项目来提取足够的补丁数据,并且使用所有这些项目进行PL训练太昂贵了。

对比方法。我们使用两个广泛使用的基准,Defects4J (v1.4.0)和QuixBugs进行评估。接下来,我们从评估中删除了两个Defects4J错误,Closure 63和Closure 93,因为它们是其他Defects4J错误的重复。我们编译打了补丁的项目,并运行测试套件来找到可信的补丁,即通过相关测试用例的补丁。

RQ1: CURE与最先进的APR技术相比表现如何

实验设计。我们使用CURE与Defects4J (v1.4.0)和QuixBugs进行评估。

结果。在表1中,结果显示为x/y,其中x是正确修复的bug数量,y是具有合理补丁的bug数量。

在Defects4J和QuixBugs中,CURE修复了最多的错误,分别为57和26。具体来说,CURE为104个Defects4J错误生成了合理的补丁,其中57个被CURE正确修复,比现有的最佳方法TBar高出5个错误。与基于NMT的方法相比,CURE比基于NMT的最佳方法CoCoNuT多正确修复了13个bug。CURE修复了26个QuixBugs bug (bug数量是CoCoNuT的两倍),其中包括在QuixBugs上评估过的四个现有工具都无法修复的12个bug。在Defects4J中,CURE修复了一个独特的错误,这是25种现有方法中任何一种都没有修复的。

基于模式的方法(例如,TBar和Hercules)无法解决这个问题,因为它们没有固定的模式来确保方法参数是非负的。基于NMT的方法(例如,SequenceR, DLFix和CoCoNuT)无法修复它,因为这样的修复并不常见。在我们的补丁训练数据中(已经有来自45180个项目的272万个训练实例),只有两个类似的修复。因此,由于缺乏更多的信息,基于NMT的模型很难捕捉到这种转换类似的修复。然而,他补充说:“我不知道。以确保非负性在Java方法中是常见的,并由我们的PL模型捕获,从而允许CURE正确地修复图中的Defects4J。

表1:与最先进的APR工具对比结果

正如引言中所解释的,图1显示了QuixBugs中的KTH错误,只有CURE修复了这个错误,而QuixBugs上评估的现有技术都没有修复。CoCoNuT无法修复此错误,因为它生成了太多不可编译的补丁。Nopol、RSRepair和Astor无法修复此错误,因为它们没有实现所需的修复模式。

与现有的性能最好的基于NMT的方法CoCoNuT相比,CURE修复了Defects4J中的13个bug。与最佳的基于模式的方法相比,CURE比TBar多修复了Defects4J中的五个错误,其中大多数需要复杂的转换来修复。

可编译补丁率:除了正确修复错误的数量之外,我们还使用平均可编译率来衡量CURE学习PL语法和开发人员代码的有效性。我们比较了两个基准测试中由不同的基于NMT的模型生成的顶级候选补丁的平均可编译率。CURE在前30名候选程序中生成的可编译补丁比SequenceR多,在所有前30名、100名、1000名和5000名候选程序中生成的可编译补丁比CoCoNuT多(DLFix不提供可编译率数据)。比较不同的行显示每个组件都对更高的可编译补丁率做出了贡献。例如,将“BPE+GPT+CoNuT+vanilla”行与“CURE”行进行比较,我们的代码软件搜索将前100个补丁的平均可编译补丁率提高了6%(从22%提高到28%)。由于PL模型和有效标识符检查策略,CURE比现有的基于NMT的方法生成更多的可编译补丁。

RQ2: CURE组件的贡献是什么?

实验设计。本文将以下四种技术与CURE进行了比较:CoCoNut(“CoNuT+vanilla”)、BPE+CoNuT+vanilla、BPE+CoNuT+vanilla和BPE+GPT+CoNuT+vanilla。所有模型都使用1000的波束大小,生成10,000个候选补丁,为每个bug验证前5,000个候选补丁(除了CoCoNuT为每个bug生成和验证20,000个候选补丁),并在相同的数据集上进行训练。

表2:在两个不同模型的基准测试中,我用了两个不同模型的基准测试中的bug

表3:两个基准的消融研究结果

结果。在表2中,比较“BPE+CoNuT+vanilla”和“BPE+GPT+CoNuT+vanilla”可以看出,GPT使平均编译率提高了2%-4%。此外,“BPE+GPT+CoNuT+香草”生成的正确补丁(验证前)的平均排名(排名最高的是最好的)比“BPE+CoNuT+香草”高68% (131 vs 414),这表明GPT PL模型不仅使APR模型能够修复更多的bug,而且还提高了正确补丁的等级。

为了衡量长度控制策略的影响,我们比较了“BPE+GPT+CoNuT+vanilla”和CURE生成的候选补丁的长度。对于“BPE+GPT+CoNuT+vanilla”模型,候选补丁和正确修复之间的平均长度差是7个令牌。相反,CURE的候选补丁和正确修复之间的平均长度差是5个令牌。这表明长度控制策略有助于生成更多与正确补丁长度相似的候选补丁。具体来说,它有助于修复长错误(例如,它修复了QuixBugs中没有长度控制策略就无法修复的最长错误),因为它进行了更深入的搜索。

子词标记化的影响:子词标记化通过减少词汇表的大小(从139,423个标记减少到50,057个标记)和覆盖更多正确的修复来改善搜索空间。椰子与“BPE+椰子+香草”的对比表明,子词标记化帮助修复了另外四个bug(一个在Defects4J中,另外三个在QuixBugs中)。“GPT+CoNuT+vanilla”和“BPE+GPT+CoNuT+vanilla”还表明,子词标记化帮助修复了10多个bug。

我们还比较了使用不同标记化技术的OOV标记的数量。在我们的基准测试中,使用单词级标记化,有14个bug包含OOV标记(例如,“binsearch”和“charno”)。相反,在使用子词标记化时,所有这些OOV标记都被分成更常见的标记。这表明子词标记化有助于减少词汇表大小,改进词汇表,使模型更容易训练,并最终修复更多错误。

转述:丁自民

0 阅读:0

互联不一般哥

简介:感谢大家的关注