来看一道经典的编程题目:
已知一个论文引用量序列,其中每个引用量都是非负整数,请编写一个输出为 h_index 的同名函数 h_index()。其中 h_index 指至多有 h 篇论文分别被引用了至少 h 次。
一种解答代码如下:
这段代码虽然在细节上存在一些问题,却能够顺利通过部分样例测试。而它居然是 AI 写的!
上述代码顺利通过了部分样例测试。
随着深度学习的兴起,AI 让许多行业实现了自动化,包括将 AI 用于编程。人们在编程时通常会使用大量的有意识和潜意识思维机制发现新问题并探索不同的解决方案,然而大多数机器学习算法都需要定义明确的问题和大量带有注释的数据才能够开发出解决相同编程问题的模型,因此用 AI 编程并非易事。此外,准确地评估模型的代码生成性能可能是很困难的,并且很少有既灵活又严格的方式来评估代码生成的研究。
基于此,来自 UC 伯克利等机构的研究者提出了 APPS(Automated Programming Progress Standard),一个代码生成基准,该基准测试能够衡量模型的代码生成能力,并检查代码是否符合问题要求。与公司评估候选软件开发人员的方式类似,该研究通过检查生成的代码在测试用例上的结果来评估模型。基准测试包括 10000 个问题,包含单行代码解决的简单问题和具有大量代码的复杂算法挑战等多多种问题。上述 AI 生成代码示例在 APPS 数据集中被视为「面试级别」的问题。
对此,有网友说道:「如果我不能通过编码面试,但我写的算法通过了,那么会怎样?」
那大概会录用「算法」?
我们再来看一个例子:
问题:已知两个整数 n 和 m。计算数组(a,b)对数,使两个数组的长度都等于 m;每个数组的元素都是 1 到 n 之间的整数;对于任意索引 i 从 1 到 m,都有 a_i≤ b_i;数组 a 按非降序排列;数组 b 按非升序排序。结果可能很大,应该打印它的 modulo10^9+7。输入:唯一的行包含两个整数 n 和 m(1≤ n≤ 1000,1≤ m≤ 10)。输出:打印一个整数,满足上述 modulo10^9+7 所述条件的数组 a 和 b 的数量。
根据问题描述,AI 自动生成代码,尽管生成的代码通过了 0 个测试用例,但第一眼看起来似乎是可行的:
研究者在 GitHub 和训练集上对大型语言模型进行了微调,并发现微调后语法错误率呈指数级下降。在 GPT-Neo 等模型上可以通过大约 15% 的入门问题测试用例。
APPS 数据集
APPS 数据集包括从 Codeforces、Kattis 等不同的开放编码网站收集的问题。APPS 基准试图通过以不受限制的自然语言提出编码问题并评估解决方案的正确性来反映人类程序员的评估方式。问题的难度范围从入门到大学竞赛水平,用来衡量编码能力和解决问题的能力。
APPS 总共包含 10000 个编码问题,其中包括 131836 个用于检查解决方案的测试用例和 232444 个由人类编写的真实解决方案。里面的问题可能是很复杂,因为平均长度为 293.2 个词。数据集被平均分为训练集和测试集,每部分都有 5000 个问题。在测试集中,每个问题都有多个测试用例,平均测试用例数为 21.2。每个测试用例都是针对相应问题而专门设计的,能够严格评估程序功能。
为了创建 APPS 数据集,研究者手动处理了来自开放网站的问题,在这些网站中程序员可以相互分享问题,包括 Codewars、AtCoder、Kattis 和 Codeforces。为了提高数据集的质量和一致性,研究者对每个问题源使用自定义 HTML 解析器。必要时,研究者使用 MathPix API 将图像转换为 LaTeX。此外研究者还使用具有 SVD 降维和余弦相似度的 tf-idf 特征执行重复数据删除。
在数据分级上,数据集被分为三个难度。例如,Kattis 难度小于 3 的问题被归类为「入门级难度」,难度在 3 到 5 之间的问题被归类为「面试级难度」,难度大于 5 的问题被归类为「竞赛级难度」。
实验
研究者使用 APPS 基准分析了各种 Transformer 模型。结果发现,微调和增加模型尺寸可以提高准确率,而准确率随着难度的增加而下降。此外,实验发现语法错误正在减少,生成的代码在质量是合理的。模型采用 GPT-2、GPT-3、GPT-Neo。GPT 体系架构特别适合于文本生成,因为它是自回归的。
评估指标
为了全面评估模型的代码生成能力,研究者使用了 APPS 提供的大量测试用例和实用的解决方案。测试用例允许自动评估,即使可能程序的空间组合起来可能很大。因此,与许多其他文本生成任务不同,不需要手动分析。将生成的代码在测试用例上的性能汇总为两个指标,即「测试用例平均值」和「严格准确性」。
模型性能分析
定性输出分析。模型有时可以生成正确的或表面上合理的代码。图 2 显示了通过所有测试用例的 GPT-2 1.5B 生成的代码。当模型没有通过测试用例时,有时乍一看它们生成的代码似乎仍然是合理的。例如,在图 3 给出了 1.5B 参数模型生成与问题陈述相关的代码,并进行了合理的尝试来解决它。
测试用例评估。表 2 显示了主要结果。研究者观察到,模型能够生成通过一些测试用例的代码,这意味着许多生成的程序都没有语法错误,并且可以成功处理输入测试用例以产生正确答案。请注意,对于入门性问题,GPT-Neo 通过了大约 15%的测试用例。研究者将图 4 中的「测试用例平均」结果可视化。这演示了模型在代码生成方面显示出明显的改进,并且现在开始对代码生成产生吸引力。
语法错误。研究者评估了语法错误的频率,这些语法错误导致程序无法解释,包括间距不一致,括号不平衡,冒号丢失等。如图 5 所示,语法错误存在普遍性。虽然 GPT-3 针对入门问题生成的解决方案中大约有 59%存在语法错误,但 GPT-Neo 语法错误发生率约为 3%。请注意,Yasunaga 和 Liang(2020)等最近的工作创建了一个单独的模型来修复源代码以解决编译问题,但是该研究的结果表明,由于语法错误频率会自动降低,因此将来可能不需要这样做。
BLEU。为了评估 BLEU,研究者采用生成的解并针对给定问题用每个人工编写的解计算其 BLEU,然后记录最高的 BLEU 得分。在图 6 中观察到,即使模型在处理更棘手的问题上实际上表现较差,随着问题来源变得越来越困难,BLEU 也会增加。此外,较差的模型可能具有相似或更高的 BLEU 得分。
论文发布后,有网友表示他们使用相似的数据集训练模型解答 LeetCode 中的题目,其中最优的模型是 GPT-2,准确率高达 80%。
项目链接:https://github.com/gagan3012/project-code-py
AI 的编程能力日渐提升,新一轮「内卷」又要开始了吗?