1.结论写在前面。
讨论了推理任务作为评估 LLM 编程任务的替代方法的必要性。 介绍了支持多种推理任务的 CodeMind 框架,并将 CodeMind 用于大规模基础理论研究,以评估最先进的 LLM 进行推理。 结果表明,一般来说,LLM知道结构是如何工作的,并且能够推理程序规范,并跟踪输入到输出到执行的演变。 但是,随着它们变得越来越复杂,即控制流或数据流变得更加复杂,包含非基元类型并调用 API,它们的功能受到限制。 还有人指出,规范性推理对于从给定的程序规范生成至关重要,但这并不意味着模型也可以通过推理来执行。
二、**的简要介绍。
2.1 ** 背景。
大型模型 (LLM) 在指令(指令调整)或由链接或思维树(COT 或 TOT)和上下文学习提示时表现出卓越的编程技能。 然而,一些研究表明,LLM很难概括这种异常能力,特别是当数据集变得更加复杂时,或者当任务需要理解而不是自然语言时。 这主要是因为 LLM 被训练为将合成与自然语言规范联系起来,即推理如何组合类似于他们看到的示例的结构,以满足所解释规范的要求。
为了说明推理任务如何评估 LLM,图 1-A 显示了 GPT-35.根据自然语言规范进行合成。 突出显示与规格对应的结构,颜色匹配。 由于自然语言的歧义,这将返回列表中的最小数字,而不是索引中等于最小数字值的数字。 因此,对于给定的输入 [2,5,4,3],* 返回 2 而不是 4,断言失败。
评估 LLM 归纳推理的一种方法是包括特定的预期程序行为,并检查生成的行为是否可以重现。 这需要一定程度的推理,称之为规格推理。图 1-b 显示了新规范和相应的版本**。 给定指定的输入输出对,执行 ** 会导致测试通过,这表示 GPT-35. 能够理解给定的规范并生成正确的规范。
在提示中包含测试数据是一种已知的做法,可以提高模型在编程任务中的性能。 然而,它只是推理的一个弱指标,因为它仍然涉及与自然语言的关联。 更深层次的推理是对给定输入的执行输出进行推理,这称为执行推理 (ER)。 这项任务对 LLM 提出了更大的挑战,要求他们在没有任何自然语言交叉引用的情况下进行推理**。 图 1-C 显示 GPT-35 ER任务的COT推理。 尽管模型可以产生预期的输出(如果通过测试验证为正确),但它无法正确地推断输出是用相同的输入执行的。
2.程序的 2 **。
为了实现推理评估的自动化,该文提出了CodeMind。 CodeMind 目前提供三种类型的归纳推理任务:独立执行推理 (IER) 和依赖执行推理 (DER),用于评估 LLM 是否可以推理给定输入在任何时候如何演变为输出,或者它正确合成的内容。 规范推理 (SR) 评估 LLM 实现指定行为的程度。
2.2.1 codemind
程序规范定义了一个函数 s:si so,其中 si 是程序所有可能输入的集合,因此是一组相应的输出。 根据实现合成的**,它通常是一个函数 c:ci co。 如果程序满足以下所有条件,则在规范方面定义程序是正确的:
ci ⊆ si,co ⊆ so,∀i ∈ ci,c(i)= s(i)
这要求模型推理输入如何通过实现(执行推理)演变为给定的输出,并实现这样才能为给定的输入(规范推理)生成正确的输出。
2.2.1.1 执行推理。
考虑到上述形式化方法,执行推理任务的两个定义如下。
定义 1:独立执行推理 (IER)。 给定一个程序 c:ci co 和一组输入 i = if o = c(i),其中 o = l(i) 是 l** 的输出,那么 llm l 可以正确地推断 ** 被执行。 请注意,在此任务中,不会处理规范,因此 LLM 可以评估 LLM 的推理,以用于存在真 i,o 对的任意推理。
IER 评估 LLM 对任意 ** 的一般归纳推理,这需要构造、算术和逻辑操作以及控制流的知识。 然而,即使对于人类开发人员来说,推理他们正在开发的内容也比武断更容易。 此外,作为自洽性的衡量标准,LLM应该能够推理出它们可以被正确合成的内容。 这需要以下推理任务。
定义 2:依赖于执行推理 (DER)。 给定一个规范 s:si so,llm l 生成程序 c:ci co,并且一组输入 i = if o= c(i),其中 o= l(i) 是 l** 的输出,那么 llm l 可以正确地推断 ** 被执行。 这里的假设是,当 llm l 生成一个通过测试 i,o 的 **c 时,它应该能够正确地 **o。
2.2.1.2 规范推理。
除了归纳执行推理外,模型还应该理解规范以合成正确的**。 规范推理任务的正式定义如下。
定义3:规范性推理 (SR):给定一个规范 s:si so,任意 i,o 在提示中用自然语言规范指定,其中 i si,o so,s(i)= o,llm l 生成程序 c:ci co,如果 c(i) = s(i),那么 llm 可以正确地推理范数。 换句话说,当它们在提示中明确指定时,llm l 应该能够通过 i,o 的测试。
2.2.1.3 评估 ** 推理。
模型在给定给定模型上的推理性能是使用正确推理分数 (CRS) 来衡量的,如果模型可以正确推理,则为 1,否则为 0。 **还引入了正确推理率 (CRR) 指标,这是一个集体指标,用于衡量给定 LLM 对基准测试中多个程序进行推理的程度。 在基准 P 中计算 M 装配体的 CRR:
2.3 ** 效果。
利用Codemind,进行了大规模的基础理论研究,以评估LLM的推理能力。 选择了九个模型,包括通用 LLM 和专用 LLM,并提示它们对用 J**A 和 Python 编写的 5395 个程序执行 IER、DER 和 SR 任务。 这些程序来自五个编程基准,即 Humaneval、MBPP、Cruxeval、CodeNet 和 Atar。 **观察:
1)LLM对**结构有很好的把握,这可能是由于与自然语言规范中的概念一致。训练后的模型可以逐句解释,并且通常遵循程序的执行。 然而,LLM的推理能力仅限于简单的程序。 此外,尽管 GPT-3像 5 和 magiccoder 这样的模型可以正确解释 ** 的作用,但在跟踪数据流和正确推理执行输出时可能会失败。 在综合中实现与 GPT 模型相当的有效性的开源 LLM 在推理方面与它们有很大不同。
2)即使具有欺骗性,LLM也可以对规范中的测试数据进行推理,并将其引入合成推理过程。然而,他们的推理受到其固有局限性的限制。 当推断它们可以正确合成时,它们可以实现更高的性能。
3)在包含复杂程序的数据集上,基于综合的排名模型(生成通过所有测试的模型)与推理性能之间的相关性可以忽略不计或不存在。这需要 codemind 任务和指标来补充 LLM** 评估。
4)嵌套结构、复杂的条件谓词和循环条件、非平凡的算术和逻辑运算符以及API调用可以极大地挑战LLM推理。
2.3.1 实验设置。
*该研究包括来自 5 个编程数据集的 9 个 LLM 和 5395 个 J**A 和 Python 程序。 **法学硕士和课程选择的细节如下所述。
主题:法学硕士:** 选择了 9 个预训练或指令优化模型,包括通用和专用 LLM。 选择受到计算资源的限制,因此选择参数少于 20b 且性能优于其他模型的模型。 **主题 LLM 是 GPT-4、GPT-35. Llama 2 (13B), Mistral, Codellama (13B, 指令优化), Starcoder (155b)、wizardcoder(15b,指令优化)、magiccoder(7b)、deepseekcoder(67b)。*遵循最佳实践并为每个模型自定义提示模板(所有提示均公开提供,以供进一步调查)。 除了 GPT 模型之外,将温度设置为零以确保结果的可重复性。 它对用户开放,因此他们可以使用 CodeMind 来评估其他模型和温度。
主题节目:选择主题程序的标准是测试数据的存在(输入和相应的预期输出)以及同一程序在多种编程语言中的实现(以研究其对推理的影响)。 在几个现有的基准中,选择了Humaneval、MBPP、CodeNet、ATAR和Cruxeval中的程序。 选择该程序的 J**a 和 Python 版本,因为它们是更广泛使用的编程语言。 Humaneval 和 MBPP 是众所周知的基准测试。 CodeNet 和 ATAR 是翻译基准。 Cruxeval 是一个相对简单的 Python 程序基准测试,由 Codellama (34b) 生成,用于评估 LLM 的输入和输出。
图 2 显示了程序复杂度分布,终止为圈复杂度 (CC) 和代码行数 (LOC)。 CC 测量程序控制流图 (CFG) 中独立执行的路径数。 指标为 cc = e n + 2p 计算,其中 e 和 n 分别是 cfg 中的边数和节点数,p 是类中方法数。 一般来说,cc 越高表示过程越复杂。 对于推理任务,模型应推理给定输入应采用哪种执行路径来输出。 因此,独立路径的数量越多,模型随机成功的可能性就越小。 CC 可能与程序中的行数有关,但更多的行不会导致更高的 CC。 例如,没有条件或循环构造的 10 行程序只有一个执行路径,而具有两个嵌套条件语句的 8 行程序有 3 或 4 个执行路径,具体取决于条件谓词。
2.3.对 IER 上的 2 个 LLM 的评估。
为了评估 LLM 在 IER 任务上的性能,在两种设置中给出提示:直接答案和 COT。 对于直接答案,每个模型都会提示给定输入的输出。 在 COT 设置下,首先指示模型在执行每个语句后通过值的输出逐步模拟执行。 然后要求模型输出给定输入。 在这两种设置中,提示都包含一个上下文示例,其目的有两个:介绍 IER 任务和指示响应格式。
由于 IER 只需要任何和相应的实数 i,o 对,** 使用所有 5395 主题程序提示 LLM。 表 1 显示了 COT 提示的实验结果。 从这些结果可以看出:
GPT模型在IER任务中优于其他模型,与最好的开源模型存在较大差距,为3392% (GPT-4) 和 1556(gpt-3.5)。在开源模型中,Magiccoder 的平均优势为 4%,ATAR 数据集除外83%。
在包含 J**A 和 Python 样本的数据集上,所有模型的性能都有所下降(平均下降 291%,*ATAR 平均下降 233%)。这可能是因为 J**A 实现了比 Python 更严格的语法和类型系统,这使得执行推理更具挑战性。
COT 提示(模型在输出前用语言表示执行过程)将模型的 IER 性能提高了 524%。然而,即使有 COT 提示,(开源)模型的准确性仍然不理想,需要从根本上改变。
再往下看,该模型在codenet和**atar程序的IER(即推理执行)方面比MBPP、Humaneval和CruXeval面临更多的挑战。 一个可能的原因是这些过程的复杂性,如图 2 所示。 对模型性能的详细分析(图 3)显示,循环复杂度 (CC) 和正确推理率 (CRR)(Spearman 秩相关系数 (ROC))之间存在很强的负相关关系,这证实了该模型在处理更复杂的 **iers 时更加困难。 同时,一些模型,即 Llama 2、Codellama、MagicCoder、StarCoder 和 WizardCoder,在 CruxEval 上的性能不如 Humaneval,后者在 LOC 和 CC 方面不那么复杂。 这需要进一步改进,以了解除 CC 之外还有哪些因素会影响模型的 CRR 性能。
2.3.对 DER 的 3 个 LLM 的评估。
关键问题是模型的有效性,以正确推理它生成的正确程序。 此评估需要生成任务和推理任务的组合。 **评估 DER 的管道包括三个步骤:
1)遵循最佳实践,提示主题LLM生成**;
2)根据现有测试运行合成程序;
3) 对于通过测试的程序,使用选定的测试输入并使用 COT 样式提示模型进行推理。请注意,为确保公平性,评论也已从生成的内容中删除。
*不包括 cruxeval、codenet 和 atar 中的程序,因为这些数据集不是为生成而设计的,并且缺乏适当的程序规范。 此外,无法复制骆驼 2 的生成结果,骆驼 2 也被排除在 LLM 主题之外。 与IER实验类似,温度设置为零,以考虑结果的非确定性和可重复性。 由于此设计决策,合成结果可能与现有排行榜不同。
表2显示了该实验的结果。 GPT模型在DER任务中还是比开源模型好,和最好的开源模型有区别1797 (GPT-4) 和 1313(gpt-3.5)差距。与 IER 相比,GPT 模型和开源模型之间的差距有所缩小。 **还可以观察到,除了 Codellama 在 Humaneval 上的表现外,该模型在 DER 任务上的平均 CRR 比 IER 高 684%。
在得出模型更胜任对被评估为正确合成的程序进行推理的结论之前,将本实验中的程序与 IER 实验中的程序进行了比较。 如果为 true,则较低的复杂性可能是 DER 任务上较高 CRR 的根本原因。 图 4 显示了 MBPP 和 Humaneval 中程序的 CC 分布,与主题 LLM 生成的程序相比。 可以看出,合成与这些数据集中的基本程序一样复杂,甚至更复杂。 因此,确认模型可以更好地推断它们正确合成的内容。 然而,LLM的生成和推理能力之间仍然存在很大的差距,尤其是对于开源模型。
由于生成和推理在 DER 中是统一的,因此首先计算基于每个数据集上合成行和推理行的模型排名的 Spearman 秩相关系数。 结果显示,MBPP呈强正相关( = 0.85),但对人类的相关性可以忽略不计(= 0.)。17)。这些结果传达了一个强烈的信息:基于生成能力 (pass@k) 排名的 LLM 可能与同一级别的推理能力排名有很大不同。 这需要像 CodeMind 这样的框架来改进 LLM 的其他方面**。
2.3.4 规范推理 (SR) 评估。
规范推理 (SR) 为生成 LLM 的过程提供了新的视角,特别是它们如何利用输入输出规范。 为了评估 LLM 的 SR 能力,系统会提示 LLM 在以下三个设置下生成:
1) 包含真实输入和输出的自然语言规范。在此设置中,将随机选择现有测试并将其添加到规范中。 仅使用此测试来验证生成的。
2)不包含输入和输出的自然语言规范。删除在先前设置中添加到规范中的测试,并重新提示 LLM 进行构建。 仅使用先前设置中的测试来验证生成的测试。 直观地说,如果包含测试数据来帮助生成 LLM,则将观察到 LLM 性能的下降。
3) 包含误导性输入和输出的自然语言规范。
* 在第一次设置中更改测试的预期输出,并将其添加到规范中。 使用原始测试来验证生成的。 此更改会将预期输出更改为与规范不一致的值。 例如,如果预期输出为 true,则突变会将其更改为 false。 同样,如果预期输出是正整数,它将变异为负数,差异很大。 直观地说,由于偏离自然语言规范,误导性的输入和输出会进一步降低 LLM 的性能。
仅在 MBPP 和 Humaneval 程序上执行此实验。 **humaneval 中的提示也经过预处理,最初包含输入和输出样本。 表 3 中的结果表明,在规范中加入测试数据可使 LLMs7 的生成性能得到平均改善36%。在规范中引入欺骗性测试(相对于合法测试)会对 LLM 的生成性能产生负面影响(平均下降 10%)。 然而,所有模型和程序的平均性能下降仅为 265%。无论如何,这些结果证明了LLM推理和利用规范中测试数据的能力。
2.3.4 对结果进行深入分析。
*对 IER 结果的进一步分析,评估 LLM 的一般推理能力。 在第一步中,你想知道 LLM 是否知道不同的结构是如何工作的。 如果你不理解每个结构的逻辑,你就无法推理执行。
为此,根据实现中使用的构造,每个 5395 程序都使用以下标记进行标记:for、while、if、try、switch、嵌套循环、嵌套 if 和 basic。标记为基本程序没有特殊的 ** 结构。 接下来,按标签对程序进行聚类,并计算每个聚类的LLM的CRR。 图 5 显示了对 5 个表现最好的 LLM 的分析结果。 可以看出,该模型对条件语句的处理比递归更好,但 try-catch 或 try-except 语句除外。 此外,当涉及到嵌套结构时,CRR 值会显着下降。
循环特性的影响:鉴于该模型在递归构造方面最困难,因此在下一步中将重点放在带有 for、while 和嵌套循环标签的程序上。 假设是,这种斗争是由于周期的长度或决定周期的长度。 前者质疑的是,随着循环时间的变长,模型是否更难跟踪程序数据流。 后者质疑模型推理一个块应该重复多少次的能力,无论它有多长。 图 6 绘制了 J**A 程序中每个周期长度的正确与错误情况的分布以及 CRR 值。 子图标签显示周期长度和 CRR 之间的 ROC 系数。 可以观察到周期长度与模型的CRR之间存在中度至强负相关,即随着周期长度的增加,CRR降低。 通过手动调查 IER 的错误情况,还注意到 LLM 大多无法正确推理循环条件。 如果不知道循环条件和迭代次数,就不可能正确地推理执行。 此外,还发现一些情况,尽管模型可以推理循环条件和迭代次数,但它会丢失循环中的数据流,从而错误地输出输出。
在下面的 ** 代码段(来自 CodeNet (j**a) 的 P03059)中,循环条件取决于常量变量 (c) 和变量 (time),其值在循环内发生变化。
我是技术创作者 输入:3 5 7,预期输出:10int a, b, c = scnextint();int amount = 0, time = a;for(int i = 2; time <= c + 0.5; i++)println(amount);
在这个相对简单的程序中,所有模型都失败了。 参见 COT 分析,GPT-35 知道循环条件,可以推导出前两次迭代中的所有变量值。 但是,它再次停留在循环中。 starcoder 无法正确地推理循环条件,并在 ** 块上迭代了六次。 magiccoder cot 只解释了 **(正确的解释),并没有传达它如何推理变量。
gpt-3.5, predicted output:15
analysis: enters for loop and iterates from 2 onwards
until the value of time exceeds c + 0.5. in first
iteration, amount becomes 5 and time becomes 6. in
second iteration, amount becomes 10 and time becomes
9. in third iteration, amount becomes 15 and time
becomes 12. 12 is greater than 7+0.5, loop exits.
starcoder, predicted output:105
analysis: it enters a for loop and it iterates from 2
to 7 to check each integer i in this range. in each
iteration, the value of i is passed to variable time.
the condition is met when i is 2,3,4,5,6 and 7.
magiccoder, predicted output:15
enters for loop and iterates from 2 to infinity. inside
the loop, it adds the value of b to variable amount.
then it calculates new value of time by multiplying a
with current iteration i. the loop continues until time
is greater than c+0.5. after the loop finishes, print
the final value of amount as output, which is 15.
下面的 ** 代码段中的循环条件很简单(来自 CodeNet (j**a) 的 P02994)。 因此,大多数模型对迭代次数进行了正确的推理。
input: 5 2, expected output: 18
int n = scanner.nextint();
int l = scanner.nextint();
list diff = new arraylist();
for(int i = 1; i < n+1; i++)
diff.add(value);
removek = diff.indexof(collections.min(diff)) 1;
println(n*l + n*(n+1)/2 - n - l+ removek -1));
尽管如此,一些 LLM 仍然难以在循环中正确执行推理**。 Codellama 可以正确地推理循环迭代的次数,但它无法计算 diff 数组中的值,从而导致错误的输出。 Magiccoder 还可以正确地推理循环长度,并且与前面的例子类似,它可以正确地解释 ** 的作用。 但是,它不能正确输出(输出为 10),因此无法判断它是否像解释的那样被理解。
if-else 属性:** 的手动调查显示,LLM 难以处理条件结构有两个原因:(1) 对分支的混淆和 (2) 对条件谓词的错误推理。 关于前者,据观察,LLM有时难以识别条件语句。 例如,无论采用哪个分支,它们总是进入“if”和“else”分支来推理执行。 然而,这种情况很少发生,在大多数情况下,LLM 很难正确解析条件谓词,采用错误的分支,并错误地输出。
数学和逻辑运算符的影响:了解数学和逻辑运算符的工作原理对于推断输入通过执行演变为输出至关重要。 前面分析的观察结果也强调了它们对推理程序控制流的重要性。 **对失败的 IER 案例的手动调查揭示了程序中算术和逻辑运算符的普遍性,前者占主导地位。 LLM 比算术运算符(例如,+ 和 -)和比较运算符(例如,、 和 &)更难推理位运算符(例如,例如,&)。
以下代码片段来自 MBPP(任务 311),包含多个算术和逻辑运算符。
尽管无法输出,但 Starcoder 正确地知道大多数操作员是如何工作的。 例如,它可以推断 n 和 n+1 的按位与用于确定整数 n 是否为 2 的幂。 它还可以推理循环条件,以检查 n 的最低有效位是否设置为 0。 但是,它似乎不理解 return 语句的含义(将最低有效位设置为 1),因此无法生成正确的输出。
codellama, predicted output:24
analysis: in the given inputs n is 5 and l is 2. the
sequence of numbers from 1 to 5 is [1,2,3,4,5]. the
differences between l and each number in the sequence
are [1,0,1,2,3]. the smallest difference is 0 at index
1. so, the index 1 is removed from the sequence. the
new sequence becomes [1,3,4,5]. the sum of the original
sequence [1,2,3,4,5] and the new sequence [1,3,4,5] is
calculated as (5*2+5*(5+1)/2-5-(2+1-1))=15+15-5-2=24.
输出类型的效果:** 根据输出类型对程序进行分类,并检查 (1) LLM 是否能够正确地 ** 输出类型(类型匹配)和 (2) 它们是否能够正确地推理主题程序中的输出值(值匹配),以识别七种类型,即 int(例如 2)、decimal(例如 2)。34)、字符串(例如,“codemind”)、二进制(例如,true 或 false)、列表(例如,[1,3,4,7])和元组(特定于 python,例如,(2,7))。图 7 显示了这些结果的详细信息。 总体而言,LLM 实现了高类型匹配 (>80%),尽管它们很难获得正确的值(值匹配)。 在不同的类型中,模型更难包含元组列表和十进制类型的输出值。 元组和列表由多个项目组成,每个项目都可以在程序执行期间更改。 因此,该模型难以通过可能不同的执行路径跟踪输入流,并对整个复杂输出进行推理也就不足为奇了。 此外,由于此类操作涉及 API 调用,例如 min()、next()、charat(),因此对更改进行推理需要 LLM 了解 API 的工作原理,这需要额外的努力。
input: 10, expected output:14
def set_left_most_unset_bit(n):
if not (n & n + 1)):return n
pos, temp, count = 0, n, 0
while temp:
if not (temp & 1): pos = count
count += 1
temp>>=1
return (n | 1
analysis: the variable n is initialized to 10. the code
checks if n is a power of 2. if it is, the code returns
n. if it is not, the code calculates the position of
the leftmost unset bit. the code then returns the
result of n | 1 <
*贡献是:
1)使用CodeMind框架进行推理,正式定义了三个归纳推理任务。CodeMind 是开源的,接受研究人员的贡献,以将更多的推理任务集成到其中;
2)使用Codemind对LLM的推理进行大规模的基础理论评估;
3)对结果进行全面深入的分析,列出了对LLM**推理能力产生负面影响的根本原因。该目录将是一个有价值的指南,用于开发更好的基准,以真正评估 LLM 编程能力。
*题目:Codemind: A Framework to Challenge Large Language Models for Code Reasoning