基于通信智体增强 LLM 代码调试能力

239 篇文章 0 订阅
187 篇文章 0 订阅

24年8月来自东北大学的论文“Enhancing the Code Debugging Ability of LLMs via Communicative Agent Based Data Refinement”。

调试是软件开发中的重要方面,但大语言模型 (LLM) 的调试能力仍未得到充分开发。DEBUGEVAL 是一个旨在评估 LLM 调试能力的综合基准测试。DEBUGEVAL 从现有的高质量数据集中收集数据,并设计四个不同的任务来评估调试效果,包括 BUG 定位、BUG 识别、代码审查和代码修复。此外,为了增强 LLM 的代码调试能力,提出一种基于通信智体的数据细化框架 (MASTER,coMmunicative Agent baSed daTa rEfinement fRamework),该框架生成细化的代码调试数据,供有监督的微调。

具体而言,MASTER 使用 Code Quizzer 根据 DEBUGEVAL 定义的任务生成细化数据。然后,Code Learner 充当一个批评者Critic并保留其无法解决的生成问题。最后,Code Teacher 提供基于思维链(CoT)的详细解决方案来处理生成的问题。收集合成数据并微调 Code Learner 以增强调试能力并实施 NeuDebugger 模型。实验在 DEBUGEVAL 的零样本设置中评估各种 LLM 和 NeuDebugger。进一步的分析表明,MASTER 是一种通过为监督微调 (SFT) LLM 合成数据来增强代码调试能力的有效方法。

如图所示是LLM 在 DEBUGEVAL Benchmark 上的表现。左图:在 BUG Localization、BUG Identification、Code Review、Code Repair 四个任务上评估了 LLM 的代码调试能力;雷达图展示了在各个任务上的性能分布,反映了不同 LLM 在这些调试任务上的优势和劣势。右图:开源和闭源模型在四个任务上的平均性能;颜色相同表示参数数量属于同一级别。
请添加图片描述
所有数据和代码:
​github.com/NEUIR/DebugEval

在软件开发领域,代码调试是确保应用程序功能性和可靠性不可或缺的过程 [1],[2]。随着软件系统复杂性的增加,传统的调试方法(通常依赖于启发式 [3],[4] 和预定义模式 [5],[6])已达到极限。大语言模型 (LLM) [7],[8] 的涌现能力为自动调试开辟了新视野,为识别和纠正代码错误提供了更灵活、更全面的方法 [9]。

LLM 的功能已在代码生成和翻译等与代码相关的任务中得到广泛探索 [10]- [14]。然而,它们的调试功能仍然相对未被充分开发。最近,研究人员开始专注于使用 LLM 进行自我调试,以迭代方式修复有缺陷的代码 [9],[15],[16]。为了更好地评估代码调试能力,研究人员现在正在构建基准来评估 LLM 的代码调试能力 [17],[18]。然而,现有的代码调试基准面临两个主要问题:1)它们主要围绕代码修复设计任务,不足以全面评估代码调试能力。2)使用 GPT-4 [19] 构建有缺陷的代码,无法捕捉到实际开发环境中遇到的代码错误的复杂性和多样性。

为了定制用于代码理解的语言模型,相关工作主要集中在预训练语言模型上,并引导它们学习语法和惯用语的代码语义 [22]–[24]。CodeBERT 屏蔽自然语言 (NL) 和程序语言 (PL) 的tokens,然后要求预训练语言模型填充被屏蔽范围。然后​​,CodeBERT 遵循 ELECTRA 方法 [25],预训练语言模型以检测tokens是否被替换,这有助于模型更好地捕获代码语义 [26]。DOBF [27] 更进一步,考虑到代码相关任务的独特属性,它更加注重屏蔽和生成代码段的类、函数和变量名。CodeT5 [28] 使用范围屏蔽(span-masking)策略不断预训练 T5 模型 [29],并通过更多地关注代码内的标识符来改进屏蔽策略。这种预训练方法要求 T5 [29] 模型生成这些标识符,从而增强其在代码相关任务中识别和理解标识符信息的能力。此外,一些研究人员还将代码、注释和抽象语法树 (AST) 等多模态数据源纳入语言模型的预训练中,这也有助于通过对齐代码语义和自然语言之间的语义来提高代码理解能力 [30],[31]。

最近,大语言模型 (LLM),如 Chat-GPT [7] 和 Llama [8],已经展示了它们在处理不同任务方面的涌现能力,尤其是在代码理解和生成任务方面。为了增强代码生成能力,一些广泛使用的 LLM,如 Chat-GPT [7],还在预训练语料库中混合一些代码数据,这已证明其在增强 LLM 推理能力方面的优势 [32]–[34]。一些典型的基于代码 LLM 还会收集一些与代码相关任务的指令数据,用于监督微调 LLM,从而显著提高 LLM 的代码生成能力 [35]–[37]。尽管 LLM 在生成代码段方面具有很强的有效性,但代码段通常包含错误 [9],从而降低了生成代码的通过率。为了缓解这些问题,现有的努力主要集中在采用迭代代码修复(iterative code repair)方法来不断优化生成的代码段 [9]、[15]、[16]。

早期的调试模型主要依赖于基于特征的方法,例如使用模板 [5],[6]、启发式规则 [3],[4] 或约束 [38],[39] 来纠正有缺陷的代码。然而,由于需要研究人员预先定义的模式或规则有限,这些基于特征调试方法的有效性很难扩展到纠正不同的错误和处理更复杂的代码错误。随着预训练语言模型 (PLM) 的发展,这项工作也遵循预训练然后微调的策略来构建调试模型并处理实际生活中出现的各种代码错误。例如,Xia [40] 使用面向代码的预训练模型 CodeX [41] 来探索 PLM 在调试中的能力。结果表明,CodeX [41] 实现了令人信服的代码修复性能,尤其是在 Python 和 Java 编程语言上。Kolak [42] 还使用 GPT-2 [43] 和 CodeX [41] 来评估它们在给定相应代码前缀时生成正确 patch 行的有效性。所有研究都证明,基于 PLM 的调试模型的有效性主要取决于预训练期间获得的代码理解能力。

与以前的调试工作不同,最近的研究更多地侧重于纠正 LLM 生成的错误。Self- Debug [9] 提示 LLM 生成代码审查以帮助自己改进生成的代码,而Self-Repair [44] 结合人工提供的反馈来修复有缺陷的代码。此外,Self-Edit [15] 通过利用来自测试用例评估和生成代码段的错误消息来训练另一个具有错误-觉察能力的编辑器来修复代码。Wang [16] 进一步探索了交互式修复链 (CoR) 的有效性,它使用 LLM 通过结合生成的代码和来自代码编译器的错误消息来生成修复代码的指南。显然,这些代码修复模型的有效性主要依赖于LLM的调试能力。

为了提高LLM的调试能力,最近的工作更多地侧重于生成用于监督微调的数据。InstructCoder [45]采用Self-Instruct方法[46]构建指令调优数据集,以提高LLM在代码调试中的有效性。Li [47]进一步构建了APR-INSTRUCTION数据集,并利用该数据集使用四种不同的参数高效微调(PEFT)方法LoRA [48]、p-tuning [49]、prefix-tuning[50]和(IA)^3 [51]对LLM进行微调。为了进一步评估LLM的调试能力,一些研究人员专注于构建基准测试来评估LLM。Wang[16]从Atcoder网站收集用户提交的真实错误代码来构建CodeError,用于评估LLM对Python代码的修复能力。Tian[17]利用CodeError对LLM对Python代码的修复能力进行评估,其进一步提出 DebugBench 来探索 LLM 在 Python、C++ 和 Java 中的调试能力。他们使用 GPT-4 [19] 在代码段中插入一些代码错误来合成有缺陷的代码,并要求 LLM 修复代码。然而,仅有代码修复任务不足以评估 LLM 的调试能力。

DEBUGEVAL 基准,引入四个不同的任务来评估 LLM 的调试能力。评估任务包括 BUG 定位、BUG 识别、代码审查和代码修复。
DEBUGEVAL 的数据统计如表所示。对于每个任务,都有 Python、C++ 和 Java 的问题来评估 LLM 在不同编程语言上的调试性能。

请添加图片描述

BUG 定位、BUG 识别、代码审查和代码修复任务分别有 578、2320、2400 和 414 个测试实例,几乎均匀分布在三种编程语言中。如图展示了这四个评估任务的图示及其描述:

请添加图片描述

为了保证 DEBUGEVAL 的质量,从可靠的数据源收集高质量数据,例如 Debug-1 Bench [17] 和 LiveCodeBench [52] 以及 AtCoder 网站。
DebugBench 专注于代码修复任务,需要调用 LeetCode API 来评估生成代码的正确性。DebugBench 的每个测试实例都包含一个有缺陷的代码和相应的错误类型。LiveCodeBench 是一个代码生成数据集,每个测试实例包含任务描述、正确代码和测试用例,以评估生成代码的正确性。该工作只使用来自 LiveCodeBench 的问题,并为 AtCoder 网站的每个问题构建一个正确代码和有缺陷的代码对。

DEBUGEVAL与其他代码修复基准的比较如表所示,与其他调试基准测试不同,DEBUGEVAL 是一个多语言、多任务的调试基准测试,对 LLM 的调试能力进行了更全面的评估。此外,DEBUGEVAL 包含了 GPT-4 和人类生成的错误代码,使得评估更具说服力、真实性和真实性。注:SIZE 仅代表测试集的大小。CE 表示编译错误(例如SYNTAX ERROR)。SOURCE OF BUGGY CODE 表示BUGGY CODE是如何构造的。AGAINST DATA LEAKAGE 表示是否有数据泄露。DEBUGEVAL 的部分数据来自 DEBUGBENCH,不存在数据泄露。

请添加图片描述

监督微调(SFT)已被广泛用于使用人工标记的数据集或 LLM 生成的数据 [15] 来增强 LLM 在特定领域 [37]、[57] 的性能。然而,SFT 对标记数据的可用性和质量的依赖限制了它的整体有效性。在这种情况下,本文引入MASTER 自动细化代码调试数据以进行监督微调。如图所示,向 LLM 提供任务示例,然后提示 LLM 扮演不同的角色来合成 SFT 数据。最后,MASTER 使用不同的智体来细化合成的数据以保证 SFT 数据的质量。

请添加图片描述

为了进行数据细化,MASTER 构建了三个智体,它们协作生成和细化调试问题数据,合成高质量的 SFT 数据集。如图所示,用不同的提示来引导 LLM 扮演 Code Quizzer, Code Learner 和 Code Teacher 的角色。

请添加图片描述

对于所有 LLM,生成温度设置为 0.2,将最大生成长度设置为 1024 个 token。对于闭源模型,用各自供应商提供的 API endpoints,对于开源模型,用 vLLM [73] 框架进行推理。对于 DEBUGEVAL 中的所有任务,在实验中使用零样本设置。为了微调 NeuDebugger 模型,用 DeepSeek-Coder-6.7B-Inst [64] 和 Llama3-8B-Inst [68] 作为主干模型,并利用 MASTER 合成的相同数据作为 SFT 数据。在 SFT 期间,所有模型都使用 Llama-Factory [74] 进行训练,用 LoRA [75] 进行高效微调。在实验中,学习率设置为 2e-5,训练 epoch 为 1。用 AdamW 优化器优化模型,批量大小为 8,梯度累积步长为 4。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值