Skip to content

[ASE] Better patching using LLM prompting, via Self-Consistency

约 2316 个字 预计阅读时间 8 分钟

Info
  • Author: Toufique Ahmed, Premkumar Devanbu
  • Conference: ASE 2023
  • arXiv: 2306.00108
论文
350 KB / 5 P / 2025-03-05

下载

论文概述

本研究探讨了大语言模型(LLM, Large Language Model)在程序修复(Program Repair)任务中的应用,重点关注自洽性(Self-Consistency, S-C)方法的有效性。传统 LLM 通过少样本学习(Few-shot Learning, FS)或思维链(Chain-of-Thought, CoT)技术进行推理,但这些方法可能无法充分利用代码修复任务中的信息。本研究提出了一种改进的 S-C 方法,利用 GitHub 提交日志(Commit Logs)作为「解释路径」,以增强模型生成正确修复补丁的能力,并在 MODIT 数据集上取得了新的最佳性能(State-of-the-Art)。

研究动机

  1. LLM 在软件工程中的应用
    • LLM 近年来在代码补全、代码摘要、程序修复等任务上取得了重大进展。
    • 传统 LLM 生成补丁时,通常采用贪心搜索(Greedy Decoding),但效果有限。
  2. Few-shot 学习的局限性:
    • FS 学习需要提供示例(输入-输出对),但通常忽略了解释步骤。
    • CoT 方法在一般任务中有效,但在软件工程任务(如代码修复)中,由于数据集中缺乏明确的解释路径,难以直接应用。
  3. 自洽性(S-C)的价值:
    • S-C 通过多次采样生成不同的解释-修复对,并选取最频繁的修复结果,能提升 LLM 生成补丁的准确性。
    • 在 NLP 任务中,S-C 已显示出显著提升,但在软件工程领域的应用仍未充分探索。
    • 本研究提出利用提交日志(Commit Logs)作为解释路径,以提升代码修复任务中的 S-C 方法的效果。

研究目标

论文围绕三个核心研究问题:

  1. S-C 方法能否提升程序修复性能?
    • 研究 S-C 在 MODIT 数据集上的表现,并与传统方法对比。
  2. S-C 方法的性能如何随采样次数变化?
    • 分析 S-C 生成不同数量的解释-修复对后,性能如何变化,以确定最优采样次数。
  3. 提交日志(Commit Logs)是否真正有助于模型学习?
    • 若提交日志只是噪声而非有效信息,则使用随机提交日志替代原始日志,模型性能应无显著变化。

关键概念

  1. Few-shot Learning(少样本学习)
    • 定义:向 LLM 提供少量示例(输入-输出对),然后要求模型对新输入进行预测。
    • 问题:缺乏「解释路径」,仅靠输入-输出示例可能不足以引导模型生成高质量修复补丁。
  2. Chain-of-Thought(CoT,思维链)
    • 定义:在 Few-shot 示例中,加入解释步骤,使 LLM 在推理过程中生成更合理的中间推理步骤。
    • 局限:软件工程任务中,数据集通常缺乏手工标注的「思维链」,难以应用。
  3. Self-Consistency(S-C,自洽性)
    • 定义:使用 CoT 提示 LLM 生成多组「解释-修复」对,然后选择最常见的修复结果。
    • 优势:通过高温度(High Temperature)采样生成不同的修复路径,提高模型的稳定性。解决了单次推理可能带来错误或不稳定结果的问题。

本研究的创新点:使用 Github 提交日志作为「解释路径」,引导模型生成更合理的修复方案。

研究方法

  • 数据集(MODIT)
    • MODIT 数据集包含 GitHub 代码变更记录,包括错误代码(Buggy Function)、修复后代码(Fixed Function)以及提交日志(Commit Message)。
    • 研究选取两个子集:
      • B2Fs(短序列)
      • B2Fm(长序列)
  • 模型
    • 使用 OpenAI 的 Code-DaVinci-002(175B 参数),在 OpenAI API 上进行实验。
  • 实验流程
    • 基线方法(Baseline):
      • 贪心搜索(Greedy Decoding):直接选择最可能的补丁,无额外解释。
      • Few-shot Learning + BM25 检索:使用 BM25 算法选取相关示例进行 Few-shot 学习。
    • 改进方法(Proposed Method):
      • Few-shot Learning + CoT:Few-shot 示例中加入解释路径(提交日志)。
      • Few-shot Learning + CoT + S-C:先使用 Few-shot + CoT 生成不同的修复方案。进行多次采样(最高 50 次),统计最常见的修复结果。

评价指标

Top-1 精确匹配率(Exact Match Accuracy)

Top-1 精确匹配率(Exact Match Accuracy, EMA)衡量的是模型生成的修复代码是否与参考正确修复代码完全一致的比例,即:

  • 若 LLM 生成的补丁与参考补丁完全匹配,则计为正确;否则视为错误。
  • 该指标是一种严格的评估标准,只有完全一致的修复才会被认为是正确的,忽略了可能存在的等效变体(即代码逻辑相同但格式或变量命名不同的情况)。

设测试集中有 \(N\) 个样本,LLM 生成的修复代码为 \(\hat{y}_i\),人工标注的正确修复代码为 \(y_i\),则 EMA 定义如下:

\[\text{Exact Match Accuracy} = \frac{1}{N} \sum_{i = 1}^{N} 1(\hat{y_{i}} = y_{i})\]

其中 \(1(\hat{y_{i}} = y_{i})\) 是指示函数,当 \(\hat{y_{i}} = y_{i}\) 时为 \(1\),否则为 \(0\)

优点

  • 严格评估标准:只有当模型生成的代码完全正确时,才会被计为成功,确保了结果的高可信度。
  • 直接反映模型的可靠性:如果 EMA 高,说明模型确实能够生成接近人工修复的代码。

缺点

  • 忽略等效变体:如果 LLM 生成的代码逻辑正确但格式不同(如变量命名不同、代码结构调整),仍可能被判定为错误,从而低估模型性能。

McNemar 统计检验(McNemar’s Test)

McNemar 统计检验(McNemar’s Test)是一种配对样本的非参数统计检验方法,用于比较两种方法在分类任务上的差异是否具有统计显著性。

在本研究中,McNemar’s Test 用于检验:

  • 自洽性方法(Self-Consistency, S-C)是否显著优于传统方法(Greedy Decoding、Few-shot Learning、CoT)。
  • 使用真实提交日志(Commit Logs)是否显著优于使用随机提交日志。

McNemar’s Test 主要用于成对的二分类数据,比较两个方法在相同数据集上的预测结果是否存在显著差异。例如:

  • 方法 A(Baseline)修复正确,方法 B(S-C)修复错误
  • 方法 A(Baseline)修复错误,方法 B(S-C)修复正确
  • 其他两种情况(A 和 B 都正确,A 和 B 都错误)不影响结果

假设我们有两种方法 A 和 B,对同一个测试集上的样本进行预测,统计以下四种情况:

方法 B 预测正确 方法 B 预测错误
方法 A 预测正确 \(n_{11}\) \(n_{10}\)
方法 A 预测错误 \(n_{01}\) \(n_{00}\)

其中 \(n_{10}\) 是方法 A 预测正确但方法 B 预测错误的样本数,\(n_{01}\) 是方法 A 预测错误但方法 B 预测正确的样本数。

McNemar 统计量计算公式:

\[\chi^{2} = \frac{(n_{10} - n_{01})^{2}}{n_{10} + n_{01}}\]

该统计量服从卡方分布(Chi-square distribution),自由度为 1。

如果 \(p\) 值很小(例如 \(p < 0.01\)),说明两种方法之间的性能差异是显著的,即方法 B(如 S-C)相较于方法 A(如 Greedy Decoding)确实有效果上的提升,而不是由于随机波动导致的。

优点

  • 适用于配对样本:适用于相同测试集上不同方法的对比,而不受样本规模影响。
  • 适用于二分类任务:可以直接用于判断哪种方法在「正确-错误」分类上表现更优。
  • 能判断统计显著性:能够确保实验结果不是偶然的,而是真实的改进。

缺点

  • 不能衡量具体的改进幅度,只能说明是否有显著差异。
  • 如果 \(n_{10}\)\(n_{01}\) 太小(如 \(< 5\)),结果可能不稳定,需要使用确切概率法(Exact Test)。

实验结果

RQ1:S-C 方法能否提升程序修复性能?

方法 B2Fs 精确匹配率 B2Fm 精确匹配率 相对提升 p 值
贪心搜索 9.50% 11.20% - -
CoT 10.00% 10.40% - -
S-C 13.50% 15.50% +42.10% < 0.01
BM25 + 贪心 29.00% 19.10% - -
BM25 + CoT 29.00% 20.20% - -
BM25 + S-C 31.80% 21.60% +9.65% < 0.01

S-C 方法显著优于 CoT 和贪心搜索,p 值均小于 0.01,表明结果具有统计显著性。

RQ2:S-C 方法的性能如何随采样次数变化?

在前 10 轮采样时,准确率迅速提升。

B2Fm 数据集在 10 轮后基本趋于稳定,而 B2Fs 数据集在 30 轮后仍有轻微提升。

结论:建议 S-C 采样次数设为30 轮,保证稳定性与计算成本的平衡。

RQ3:提交日志是否真正有助于模型学习?

数据集 正确提交日志 随机提交日志 提升 p 值
B2Fs 30.00% 26.56% +3.44% 0.30(不显著
B2Fm 19.90% 19.10% +4.18% 0.30(不显著)

随机提交日志未显著提升模型性能,说明提交日志确实在影响 LLM 的推理过程。

结论

S-C 方法在程序修复任务中有效,在 MODIT 数据集上取得了最佳性能。

最佳 S-C 采样次数为 30 轮,能够平衡计算成本与性能。

提交日志作为解释路径可提升 LLM 修复补丁能力,随机替换后效果下降。