ChatGPT生成的代码真的正确吗?代码生成的大型语言模型的严格评估
Is Your Code by ? of Large for Code
Liu, Xia, Yuyao Wang, Zhang
of -,
引用
Liu J, Xia C S, Wang Y, et al. Is your code by ? of large for code [J]. in , 2024, 36.
论文:
摘要
编程基准,连同精心策划的合成问题和测试用例,被用来衡量各种LLM在代码合成上的性能。然而,为了充分评估生成的代码的功能正确性,这些测试用例在数量和质量上都是有限的。现有基准测试的这种限制引出了以下问题:在LLM时代,生成的代码真的正确吗?为了回答这个问题,我们提出了——一个代码综合评估框架,以严格基准测试LLM合成代码的功能正确性。通过自动测试输入生成器(由基于LLM和基于突变的策略提供支持)新生成的大量测试用例来增强给定的评估数据集。我们对26种流行的LLM(例如GPT-4和)进行了广泛的评估,结果表明+能够捕获大量以前未检测到的LLM合成的错误代码,将pass@k降低了19.3-28.9%。我们的工作不仅表明了之前流行的代码综合评估结果并不能准确地反映LLM在代码综合方面的真实性能,而且为通过自动化测试来提高此类编程基准开辟了新的方向。
1 引言
自动生成准确符合用户意图的程序是计算机科学中一个长期存在的挑战,被称为程序合成。在过去的几十年里,经典的程序合成技术得到了发展,包括演绎合成、归纳合成和神经引导合成。最近,随着大型语言模型(LLM)的出现和开放代码库的丰富,研究人员一直专注于将LLM应用于直接代码生成。然后将生成的代码片段与上下文结合起来,形成与用户意图一致的完整函数。利用自然语言理解和生成能力,LLM在代码合成方面表现出令人印象深刻的性能。
图1:为 #58合成的典型错误代码。
足够的测试。当前的编程基准通常对每个编码问题平均只包含不到10个测试。此外,这些测试相对来说过于简单,无法完全探索代码的功能或角落用例。图1显示了一个由合成的错误代码示例,它从两个列表中返回经过排序的唯一公共元素。乍一看,该函数看起来是正确的,并且在使用来自的基本测试输入时计算所需的输出。然而,在语句中,它错误地将中间列表转换为不再保留已排序列表顺序的集合。这个例子表明,逻辑上有缺陷的解决方案仍然可以通过所有简单的测试,并且由于测试不足而被误认为是正确的。
不精确的问题描述。代码生成的输入除了函数签名之外还包括自然语言描述。现有基准中的这些任务描述常常过于模糊,无法完全阐明预期的程序行为。例如,输入的可能没有指定期望的输入域或函数应该如何处理异常。因此,这些编程问题可能会被LLM根据实际测试以不同的方式解释,从而导致有能力的LLM被错误地判断为无能。
我们的建议。在这项工作中,我们着手回答这个重要问题并评估评估数据集。因此,我们构建了——一个评估框架来改进现有的代码基准,以便精确地评估LLM生成的代码的功能正确性。的核心是一个自动测试输入生成引擎,它通过生成有趣的测试输入来增强现有的代码基准,以充分执行代码解决方案,并通过交叉检查基本事实实现来检查其功能正确性。具体来说,采用了基于LLM和基于突变的方法来自动生成和多样化额外的测试输入。首先使用生成一组高质量的种子输入,目的是在有效的输入结构内测试困难的角落用例和程序的功能。使用这些高质量的种子输入,然后执行类型感知突变,以有效地生成大量额外的测试输入。然后使用这些新生成的测试输入,通过对真实实现的差异测试来评估LLM生成的代码。
图2:的概述
本文贡献如下:
2 技术示例
图2显示了的概述。我们首先将原始数据集作为输入,其中包含-truth实现和基本测试输入。首先使用原始的基本事实、示例性测试输入作为演示,以及查询和生成一组高质量种子输入的专门指令构建提示。通过遵循基本输入格式和检查基本真实解决方案,可以作为生成有效但严格的测试输入的工具。从这些种子输入开始,我们执行类型感知突变,快速生成大量新输入和种子输入,以广泛评估LLM生成的代码的功能正确性。我们使用差分测试作为来交叉检查-truth和LLM生成的解的输出。作为最终输出,使用生成的高质量测试输入获得增强基准,以充分评估LLM合成代码的功能正确性。
表1:输入x上的基本类型感知突变列表。
2.1 自动化测试输入生成
通过初始化种子。首先使用生成一组高质量的种子输入,用于以后的突变。在图2中,我们使用(i)问题的真值解构造一个提示,供检查;(ii)一组测试输入作为示范;以及(iii)鼓励提出有趣输入的指令。具体来说,每个提示都从基本事实实现开始,然后从现有数据集中随机抽样测试输入。然后,我们使用图2中选定的指令完成提示,并查询以生成新的输入。旨在利用强大的理解能力来学习有效的输入格式(例如,变量类型)以及基于真实解决方案的所需功能,以便生成有意义的测试输入,以揭示错误合成代码中的错误。程序可以有自己的预期输入格式,其中不应该将无效输入传递到函数中,因为它们可能导致未定义的行为,从而在差分测试中产生误报。因此,我们过滤掉任何违反真值实现所需的输入前提条件的无效输入。
类型感知输入突变。我们遵循典型的基于突变的模糊工作流程来连续创建输入:(i)使用的种子输入语料库来初始化种子池并引导生成管道;(ii)每次从种子池中随机选择一个输入(即种子),将其突变为新的输入(即突变体);(iii)符合程序合同的新输入被添加到种子池中,我们从(ii)开始继续生成过程。
2.2 减少测试套件
代码覆盖率:代码覆盖率度量每个测试执行的代码元素(例如,语句或分支)的数量,并且在实践中被广泛用于度量测试的有效性。在这个策略中,遵循传统的测试套件缩减,我们利用广泛使用的分支覆盖作为测试需求。换句话说,使用这个指标的目标是只保留最小的测试子集,它可以覆盖与完整测试相同的分支集。
变异杀死:覆盖率衡量代码被执行的程度;然而,高覆盖率的测试用例在发现其覆盖代码中的关键缺陷方面并不一定是有效的。因此,研究人员提出了突变检测 (也称为突变分析)来更精确地评估检测的有效性。简而言之,突变测试将一组预定义的突变规则(例如,更改“ 0),以确保函数的测试输入格式良好。合约的好处是双重的:(i)它们可以补充自动输入生成步骤,以过滤掉任何生成的违反合约的无效输入。这种形式不良的输入可能会导致未定义的行为,这对于评估LLM合成代码是不合理的;(ii)它们可以与提示符中的自然语言描述一起作为正交描述符,以便进一步澄清。
表2:改进基准的概述。
3 实验评估
实验设置。我们的评估侧重于使用pass@k的无偏版本来准确评估LLM合成代码的功能正确性。为了提高通用性,我们对26种流行的、最先进的LLM和各种温度设置进行了全面评估。
表3:对LLM在和+上的评价。
LLM评估。表3显示了同时使用基本的和+评估LLM时的pass@k。我们首先观察到,在所有LLM、模型大小和k值中,使用+,与使用基本相比,几乎所有pass@k结果都持续下降。值得注意的是,性能下降非常显著,与评估模型相比,下降幅度高达23.1% (pass@1*)/ 19.3% (pass@1) / 24.9% (pass@10) / 28.9% (pass@100)。这种性能下降不仅出现在流行的开源LLM中,例如广泛使用的-16B[46](降低18.5%)以及新兴的 – 34b (降低17.6%)和 (降低14.1%),而且还出现在最先进的商业(降低12.6%)和GPT-4(降低13.1%)模型中。总的来说,我们的结果总体上证实了我们的假设,即先前对的评估不够鲁棒,无法检测出LLM合成的错误代码。这些LLM不仅广泛用于日常编程,而且还作为评估新代码合成技术的共同参考点。因此,强烈建议使用更加健壮的基准(如+)进行评估,以便得出精确的结论。
表4:+的简化测试套件。
减少测试套件的有效性。基于+平均为每个编程任务获得764.1个测试(表2),我们的测试套件将其最小化为+ MINI,每个任务只有16.1个测试(小了47倍)。表4执行留一交叉验证,以显示表3中研究的代表性模型子集(由于时间/空间限制)上的pass@1*。也就是说,对于每个评估的LLM,我们构建简化的测试套件,而不考虑它自己的样本kill。Full列显示,缩减后的测试套件可以实现与+几乎相同的pass@1*,只需使用少47x的测试用例。仔细看一下,在每个指标上单独执行集合覆盖可以在一定程度上利用基本的pass@1 *。具体而言,使用经验LLM样本杀戮是最有效的,导致与完整方法相同的有效性,但也比其他理论指标消耗更多的测试。虽然除了使用样本剔除之外,使用覆盖度和突变分析似乎是不必要的,但它们仍然是理论测试充分性的基本保证。
通过率分布。图3显示了每个编程任务的和+测试的总体通过率。和+的通过率差距表明,总的来说,+可以检测出所有难度级别的问题中被错误识别的解决方案。我们还观察到,中的问题是不平等的。
图3:通过率分布。
中不正确的“真值”。除了使用检测LLM的错误代码外,我们还发现了18个缺陷(11%的问题),甚至在的原始基本事实中,包括(1)未处理的边缘情况:五个先前的基本事实无法处理角落情况输入(例如,空列表或字符串);(2)逻辑错误:10个先验事实错误地实现了期望的功能;(3)性能问题:三种低效的实现导致在合理大小的输入上性能缓慢。其中,不良逻辑最为严重,因为原始的“”不能准确反映用户意图。这样的缺陷也可以通过差异测试来检测,但要在我们自己重新实现的真值和中的原始真值之间进行测试。
图4:中错误逻辑真值解决方案的示例(#124)
图4显示了一个来自的不正确的真值实现(),它被归类为具有错误的逻辑。所需的任务是检查输入日期格式是否正确。我们看到,在核心逻辑中,条件首先尝试检查月份条件,然后处理相应的日期条件。然而,这是不正确的实现,因为在中” and “的优先级高于” or “,导致基真函数检查两个条件是否满足,而不是两个条件都必须满足。这是通过我们自动生成的12-31-1999的测试输入暴露出来的,其中-truth实现错误地将其标记为无效日期。令人惊讶的是,中的任何基本测试输入都没有暴露出这个严重的错误,这进一步表明了原始测试输入的弱点和有限的评估能力。
我们提出——一个严格的程序综合评估框架,由自动化测试生成驱动。结合了基于LLM和基于突变的输入生成,以获得多样化的测试输入集,以准确评估LLM生成代码的正确性。创建了+,建立在流行的之上,具有额外的高质量和自动生成的测试输入。随着测试套件的减少,还产生了+ -MINI,它比+小47倍,同时保持了类似的测试效率。我们广泛地评估了一组不同的LLM,并表明+可以识别大量以前未检测到的LLM生成的错误代码,证明了它在增加编程基准以进行更准确评估方面的有效性。
转述:王凌杰
