当前位置:   article > 正文

从文本使用大模型自a动生成代码:Codex

从文本使用大模型自a动生成代码:Codex

OpenAI Codex是由OpenAI开发的人工智能模型。它能解析自然语言并生成相应的代码。该模型驱动了GitHub Copilot,一个为选定的IDE(如Visual Studio Code和Neovim)提供的编程自动补全工具。Codex是OpenAI的GPT-3模型的后代,经过微调以用于编程。

摘要

我们介绍Codex,这是一种在GitHub上公开可用的代码上进行Fine-tuned的GPT语言模型,并研究其Python编写能力。Codex的一个特定生产版本支持GitHub Copilot。在HumanEval上,这是我们发布的新的评估集,用于衡量从文档字符串中合成程序的功能正确性,我们的模型解决了28.8%的问题,而GPT-3解决了0%,GPT-J解决了11.4%。此外,我们发现,重复从模型中采样是一个出人意料的有效策略,用于产生解决困难提示的有效解决方案。使用这种方法,我们对每个问题使用100个样本,解决了70.2%的问题。对我们模型的仔细调查揭示了其局限性,包括描述长操作链的文档字符串和将操作绑定到变量的困难。最后,我们讨论了部署强大的代码生成技术可能产生的更广泛影响,涵盖安全性、安全和经济等方面。

1 介绍

可扩展的序列预测模型已经成为许多领域中的通用生成和表示学习方法,包括自然语言处理、计算机视觉、音频和语音处理、生物学,甚至跨多种模态。最近,语言模型也推动了程序合成这一长期挑战的进展,这得益于大型数据集中存在的代码以及在这些数据集上训练的语言模型的编程能力。像掩码语言建模和跨度预测等流行的语言建模目标也已经被改编用于训练它们的编程对应物CodeBERT和PyMT5。

类似地,我们对GPT-3的早期调查显示它可以从Python的文档字符串生成简单的程序。虽然初级,但这种能力令人兴奋,因为GPT-3并没有明确针对代码生成进行训练。鉴于大型语言模型在其他模态取得的相当成功以及公开可用代码的丰富性,我们假设一种专门的GPT模型,称为Codex,可以在各种编码任务中表现出色。本文描述了几种早期的Codex模型,它们的后代支持GitHub Copilot和OpenAI API中的Codex模型。

图1. 我们模型在HumanEval数据集上的通过率与模型规模的关系。

图1. 我们模型在HumanEval数据集上的通过率与模型规模的关系。

当针对每个问题生成单个样本时,GPT-12B解决不了任何问题,但Codex(在代码上进行Fine-tuned)解决了28.8%的问题,Codex-S(进一步在正确实现的独立函数上进行Fine-tuned)解决了37.7%的问题。在此基础上,通过针对每个问题生成100个样本并选择平均对数概率最高的样本可以实现进一步的提升(解决率为44.5%),或者通过选择通过单元测试的样本(解决率为77.5%)。所有样本均使用温度为0.8进行生成。

在这项工作中,我们专注于从文档字符串中生成独立的Python函数的任务,并通过单元测试自动评估代码样本的正确性。这与自然语言生成形成对比,后者的样本通常通过启发式方法或人工评估进行评估。为了准确评估我们的模型,我们创建了一个包含164个原始编程问题和单元测试的数据集。这些问题涵盖语言理解、算法和简单数学,其中一些类似于简单的软件面试问题。我们发布了这些数据以及一个评估框架,链接在 https://www.github.com/openai/human-eval 。

为了解决测试集中的问题,我们从模型中生成多个样本,并检查其中是否有任何一个通过了单元测试。仅使用单个样本,一个拥有12B参数的Codex解决了28.8%的这些问题,而一个拥有300M参数的Codex解决了13.2%的这些问题。相比之下,拥有6B参数的GPT-J在同一数据集上达到了11.4%,而所有GPT模型几乎都达不到1%。为了提高我们的模型在从文档字符串中合成函数任务上的性能,我们对Codex进行了对独立、正确实现的函数进行Fine-tune。得到的模型Codex-S,在单个样本下解决了37.7%的问题。图2展示了我们数据集中不同难度的问题,以及模型生成的正确解决方案。

实际的编程任务通常涉及多次尝试和错误修复的迭代过程,我们通过从模型中生成大量样本并选择通过所有单元测试的样本来近似这个过程。在100个样本内,Codex-S能够为77.5%的问题生成至少一个正确的函数。这个结果表明,可以通过启发式排名选择准确的代码样本,而不是完全评估每个样本,后者在部署中可能不可行或不实际。事实上,我们发现具有最高平均对数概率的样本通过了44.5%的问题的单元测试。

最后,我们讨论了这些Codex模型的局限性和潜在的更广泛影响,以及越来越强大的代码生成模型可能带来的影响。

2 评估框架

在本节中,我们讨论评估框架的细节。我们首先定义了pass@k指标,并解释了它相对于标准匹配度量的优势。接下来,我们描述了手写问题的数据集,“HumanEval”,这个数据集是我们创建的,用于评估我们的模型。最后,我们讨论了我们用来安全执行模型生成代码的沙盒环境。

2.1 功能正确性

针对代码的生成模型主要通过将样本与参考解决方案进行匹配来进行基准测试,其中匹配可以是精确的或模糊的(如BLEU分数)。然而,最近的研究表明,基于匹配的代码度量存在一些不足之处。例如,Ren等人(2020)发现BLEU在捕捉特定于代码的语义特征方面存在问题,并提出了对分数进行若干语义修改。

更根本的是,基于匹配的度量无法考虑到与参考解决方案功能上等价的大而复杂的程序空间。因此,最近在无监督代码翻译和伪代码到代码翻译方面的工作转向了功能正确性,其中如果样本通过一组单元测试,则被视为正确。

我们认为这个度量标准也应该适用于文档字符串条件下的代码生成。

也许评估功能正确性最具说服力的原因是它是人类开发人员用来评判代码的方法。一种称为测试驱动开发的框架规定,在任何实现开始之前,软件需求应该转化为测试用例,并且成功是指通过这些测试的程序。虽然很少有组织采用完全的测试驱动开发,但集成新代码通常依赖于创建并通过单元测试。

Kulal等人(2019)使用pass@k指标评估功能正确性,其中对于每个问题生成k个代码样本,如果任何样本能够通过一组单元测试,则认为该问题已解决。

图2. 来自HumanEval数据集的三个示例问题,单个来自Codex-12B的样本通过单元测试的概率分别为0.9、0.17和0.005。提供给模型的提示显示为白色背景,成功的模型生成完成显示为黄色背景。尽管不保证问题的新颖性,但所有问题都是手写的,而不是通过程序复制自现有来源。附录B中可以找到随机问题和样本。

图2. 来自HumanEval数据集的三个示例问题,单个来自Codex-12B的样本通过单元测试的概率分别为0.9、0.17和0.005。提供给模型的提示显示为白色背景,成功的模型生成完成显示为黄色背景。尽管不保证问题的新颖性,但所有问题都是手写的,而不是通过程序复制自现有来源。附录B中可以找到随机问题和样本。

但是,以这种方式计算pass@k可能会有很高的方差。相反,为了评估pass@k,我们为每个任务生成n ≥ k个样本(本文中,我们使用n = 200和k ≤ 100),计算通过单元测试的正确样本数c ≤ n,并计算偏差估计值。

直接计算这个估计量会导致非常大的数值和数值不稳定性。在图3中,我们包含了一个数值稳定的NumPy实现,简化了表达式并逐项评估乘积。有人可能会尝试用 来估计 pass@k,其中 是 pass@1 的经验估计值,但我们在附录A中展示了它是有偏的。

图3. 一个数值稳定的脚本,用于计算pass@k的无偏估计。

图3. 一个数值稳定的脚本,用于计算pass@k的无偏估计。

随后,我们提供了证据表明BLEU分数可能不是功能正确性的可靠指标,因为我们展示了由我们的模型生成的功能不等价的程序(在某些输入上保证与参考解决方案不一致)往往具有比功能等价的程序更高的BLEU分数。

2.2 HumanEval: 手写评估集

我们评估功能正确性的数据集包括164个手写编程问题,我们称之为HumanEval数据集。每个问题包括函数签名、文档字符串、主体以及若干单元测试,平均每个问题有7.7个测试。这些任务需要手写,因为我们的模型是在GitHub的大量数据上训练的,GitHub已经包含了来自各种来源的问题解决方案。例如,有超过十个公共仓库包含着Codeforces问题的解决方案,这些问题构成了最近提出的APPS数据集的一部分

HumanEval数据集中的编程任务评估语言理解、推理、算法和简单数学。我们发布了HumanEval数据集,以便其他人可以评估功能正确性并衡量他们模型的问题解决能力。该数据集可以在 https://www.github.com/openai/human-eval 找到。

2.3 执行生成程序的沙盒环境

由于公开可用的程序具有未知的意图,并且生成的程序通常不正确,执行这些程序存在安全风险。事实上,已知GitHub包含恶意程序,这些程序会更改其环境。

因此,我们开发了一个沙盒环境,可以安全地对生成的程序执行单元测试。我们的目标是防止这些程序修改、获得对主机或网络的持久性、访问敏感资源或从主机或网络中泄露数据。由于OpenAI的训练基础设施是建立在Kubernetes和云服务上的,我们设计了我们的沙盒环境以解决这些环境的局限性,同时保持其使用模式的惯用性。

我们选择了gVisor容器运行时作为主要的主机保护组件。由于像Docker这样的容器运行时可以与容器共享主机资源,恶意容器可能会潜在地危害主机。gVisor通过模拟主机资源来保护主机,为主机和其容器之间引入安全边界。基于eBPF的防火墙规则保护了网络相邻的主机和服务,阻止除了实验控制所需的入站和出站连接之外的所有连接。

3 代码Fine-Tuning

我们对包含高达12B参数的GPT模型进行代码Fine-Tuning,以生成Codex。与GPT相比,Codex在HumanEval数据集上展现出非常不错的性能。实际上,如果我们针对每个问题生成并评估100个样本,并选择通过单元测试的样本,Codex就能够解决HumanEval中的大多数问题。当限制每个问题只进行一次评估时,使用Codex生成多个样本并选择平均对数概率最高的样本会带来显著的收益。

3.1 数据收集

我们的训练数据集是从GitHub上托管的5400万个公共软件仓库中收集的,数据集包含179GB的唯一Python文件,大小在1MB以下。我们筛选掉了可能是自动生成的文件,平均行长度大于100、最大行长度大于1000或包含少量字母数字字符的文件。在筛选后,我们的最终数据集总共为159GB。

3.2 方法

由于Codex是基于自然语言提示进行评估的,我们假设从已经包含强大自然语言表示的GPT-3(Brown et al., 2020)模型家族Fine-Tuning会很有帮助。但令人惊讶的是,当从预训练的语言模型开始时,我们并没有观察到改进,可能是因为Fine-Tuning数据集太大。尽管如此,从GPT Fine-Tuning的模型更快地收敛,所以我们在所有后续实验中都采用了这种策略。

我们使用与相应GPT模型相同的学习率训练Codex,采用175步线性预热和余弦学习率衰减。我们总共训练了1000亿个tokens,使用Adam优化器, , , ,权重衰减系数为 0.1 。

为了最大程度地利用来自GPT的文本表示,我们将我们的代码词法分析器基于GPT-3文本分词器。由于GitHub代码中单词的分布与自然文本不同,该分词器对于表示代码并不是很有效。最大的低效性来源于编码空格,因此我们添加了一组额外的token来表示不同长度的空白间隔。这样可以使我们使用大约少30%的token来表示代码。

为了计算pass@k,我们将每个HumanEval问题组合成一个提示,其中包括标题、签名和文档字符串,如图2所示。我们从Codex中采样token,直到遇到以下停止序列之一:‘\nclass’、‘\ndef’、‘\n#’、‘\nif’或‘\nprint’,因为否则模型将继续生成其他函数或语句。在本文的所有采样评估中,我们都使用top p = 0.95的nucleus采样。

3.3 结果

在图4中,我们绘制了在一个保留的验证集上的测试损失与Codex模型大小的关系。我们发现,就像语言模型一样,Codex在不同规模下展现出更好的性能,这表明Fine-Tuning对其性能有明显影响。

图4. 在我们的Python GitHub代码语料库的保留分割上测量的模型交叉熵测试损失。观察到的模型大小与性能的平滑幂律缩放现象似乎在代码Fine-Tuning后仍然存在,这与GPT-3中观察到的情况相似。

图4. 在我们的Python GitHub代码语料库的保留分割上测量的模型交叉熵测试损失。观察到的模型大小与性能的平滑幂律缩放现象似乎在代码Fine-Tuning后仍然存在,这与GPT-3中观察到的情况相似。

模型测试损失随模型大小遵循幂律规律,代码Fine-Tuning后的测试损失也以类似的幂律形式呈现,其函数形式为 ,其中N是模型中非嵌入参数的数量。

在评估pass@k时,优化采样温度针对特定的k值非常重要。在图5中,我们绘制了pass@k与样本数k以及采样温度的关系。我们发现,对于较大的k值,较高的温度是最优的,因为生成的样本集具有更高的多样性,而该度量只关注模型是否生成了任何正确的解决方案。

图5。在顶部面板中,我们绘制pass@k与样本数(k)在不同温度设置下的关系。当样本数较大时,较高的温度更为适宜,可能是因为样本多样性增加所致。在底部面板中,我们绘制了每个k的最佳温度设置,通过获取顶部面板的上凸壳得到。

图5。在顶部面板中,我们绘制pass@k与样本数(k)在不同温度设置下的关系。当样本数较大时,较高的温度更为适宜,可能是因为样本多样性增加所致。在底部面板中,我们绘制了每个k的最佳温度设置,通过获取顶部面板的上凸壳得到。

特别是,对于一个679M参数的模型,pass@1的最优温度是,pass@100的最优温度是。使用这些温度,我们发现pass@1和pass@100随着模型大小的变化呈现平滑的趋势(图6)。

图6。使用pass@1和pass@100的最优温度0.2和0.8,我们将这两个指标作为模型大小的函数进行绘制。性能似乎在对数参数中以Sigmoid函数平稳扩展。

图6。使用pass@1和pass@100的最优温度0.2和0.8,我们将这两个指标作为模型大小的函数进行绘制。性能似乎在对数参数中以Sigmoid函数平稳扩展。

Pass@k也可以解释为对k个样本进行评估后选取最佳样本的结果,其中最佳样本是由具有单元测试先验知识的Oracle选择的。从实际角度来看,我们也对必须从k个样本中选择单个样本的情况感兴趣,而没有访问Oracle的情况。例如,当模型用作自动完成工具时,用户提供提示,我们没有单元测试,但希望仅返回一个完成结果供用户评估,以免使其不知所措。

受到语言建模中类似工作的启发,我们发现选择具有最高平均token对数概率的样本优于评估随机样本,而基于总对数概率选择样本可能比随机选择稍微差一些。图7展示了将这些启发式方法应用于Codex-12B(温度为0.8)的样本所带来的好处。

图7。在我们可以生成多个样本但只能评估一个样本的情况下,模型的表现。通过选择具有最高平均对数概率(红色)或最高反向翻译得分(橙色)的解决方案,我们可以比随机选择样本表现更好,这些方法在第5节中有描述。蓝线代表使用具有先验单元测试知识的Oracle所获得的理论最佳性能。

图7。在我们可以生成多个样本但只能评估一个样本的情况下,模型的表现。通过选择具有最高平均对数概率(红色)或最高反向翻译得分(橙色)的解决方案,我们可以比随机选择样本表现更好,这些方法在第5节中有描述。蓝线代表使用具有先验单元测试知识的Oracle所获得的理论最佳性能。

最后,我们对所有Codex-12B HumanEval样本(温度为0.8)与其参考解的BLEU分数进行计算。对于每个问题,当我们绘制正确和不正确解的BLEU分数分布时,我们注意到存在显著重叠(图8)。由于不正确的解决方案保证在功能上与参考解决方案不等效,我们得出结论,BLEU分数的提高可能并不表明在实践中提高了功能正确性的比率。

图8。来自Codex-12B的正确(蓝色)和错误(绿色)解决方案的BLEU分数概率密度,针对HumanEval中的4个随机任务。请注意,这些分布并非完全可分,这表明优化BLEU分数并不等同于优化功能正确性。

图8。来自Codex-12B的正确(蓝色)和错误(绿色)解决方案的BLEU分数概率密度,针对HumanEval中的4个随机任务。请注意,这些分布并非完全可分,这表明优化BLEU分数并不等同于优化功能正确性。

3.4 相关模型和系统的比较分析

与Codex类似的两个最近的工作是GPT-Neo和GPT-J,它们是在The Pile上进行训练的,该数据集包含来自各种来源的文本以及8%的GitHub代码。更广泛的研究社区发现,这些模型在定性编程评估中优于现有的GPT系统。

我们使用HumanEval数据集证实了这些发现,显示GPT-Neo在pass@1方面达到了6.4%,pass@100方面达到了21.3%,而具有相似规模的GPT模型在这两个指标上接近0%。我们看到了功能能力的显着进展,GPT-Neo-2.7B大致相当于Codex-85M(参数减少30倍)。同样,GPT-J-6B达到了11.6%的pass@1和27.7%的pass@100,这大致相当于Codex-300M(参数减少20倍)。通过评估温度为0.2、0.4和0.8的最佳结果来获得通过率,对于GPT-Neo,以及通过温度为0.2和0.8来获得GPT-J的最佳结果。可以在表1中找到跨多个模型尺寸的详细结果。

最后,我们将Codex与Tabnine的最大免费模型进行了基准测试,Tabnine是一款领先的代码自动完成系统,其在pass@1(在T = 0.4时)方面达到了2.6%,在pass@100(在T = 0.8时)方面达到了7.6%。这大致相当于我们套件中最小的模型之一,即Codex-12M。

3.5 APPS数据集的结果

最近,Hendrycks等人引入了APPS数据集,用于衡量语言模型在编码挑战中的能力。APPS数据集包含5000个训练和5000个测试编码问题示例,每个示例都有一组单元测试,并且对于训练数据,还有一组正确的解决方案。大多数APPS测试问题不是以单函数合成任务的形式提出的,而是作为整个程序的合成,从stdin读取输入并将输出打印到stdout,与主要的Codex训练数据形成对比。

在介绍APPS的论文中,作者对几种语言模型进行了基准测试,并报告了两个指标:模型找到正确解决方案的问题的百分比(称为“严格准确性”)和通过的单元测试的百分比,即使解决方案是不正确的。后一项指标仅用于减少测量的方差,因为第一个指标的结果非常低。我们避免了这个指标,只专注于“严格准确性”,如表1所示。Codex、GPT-Neo和TabNine在HumanEval上的评估。我们发现,GPT-J的pass@1介于Codex-85M和Codex-300M的性能之间。

表一

表一

在前面的章节中,我们针对不同的 k 报告了 pass@k 的数值(见表2)。我们考虑了编程竞赛中已知的两个额外因素,并且这些因素也存在于APPS数据集中:

• 在编程竞赛和APPS数据集中,任务描述中通常包含3个输入/输出示例。我们利用这一点,从模型中采样1000个解决方案,仅保留通过这3个单元测试的解决方案(如果存在这样的解决方案)。然后我们在这个筛选后的集合中计算 pass 率,并将其称为筛选后的 pass@k。我们还报告了未经筛选的原始 pass@k 结果。
• 在编程竞赛中,以及Codex的结果中,通常会找到一个正确的解决方案,但其算法效率不足以被视为合格。虽然这在竞赛中是不可接受的,但我们还会报告Codex生成的解决方案中没有在任何单元测试上失败,但在其中一些单元测试上超时的数量。我们在评估中设置了3秒的超时时间。

为了弥补Codex没有在APPS上进行微调的事实,我们在docstring中附加了任务描述中的一个输入/输出示例作为格式提示。在表2中,我们将这种设置称为“1-shot”,发现Codex-12B的1-shot评估达到了与在APPS上进行微调的GPT-Neo模型相当的性能。与我们之前的发现一致,对于每个任务生成和评估多达1000个样本带来了巨大的好处,尽管对于更困难的问题,解决方案通常不够高效以满足时间限制。最后,对每个问题评估通过了前3个公共单元测试的第一个样本的性能要优于原始的100个样本。

表2. APPS论文中引用的经过微调的GPT-Neo数据。对于Codex-12B,括号中的数字表示在某些测试中超时的通过程序数量。我们在采样中使用了温度0.6,以覆盖所有pass@k中的k,因此可以通过降低温度来改善原始的pass@1结果。

表2. APPS论文中引用的经过微调的GPT-Neo数据。对于Codex-12B,括号中的数字表示在某些测试中超时的通过程序数量。我们在采样中使用了温度0.6,以覆盖所有pass@k中的k,因此可以通过降低温度来改善原始的pass@1结果。

4 监督微调

除了独立功能外,在GitHub上发现的Python代码包括类实现、配置文件、脚本,甚至用于存储数据的文件。这些代码似乎与从文档字符串合成函数无关,我们假设分布不匹配会降低人类评估的性能。

为了使Codex适应感兴趣任务的分布,我们从正确实现的独立功能构建了一组训练问题,并将其用于额外的监督微调。我们描述了两种收集这些示例的方法:从竞技编程网站和具有持续集成的存储库中收集。我们将经过监督微调的模型称为Codex-S,并展示它们在模型规模上产生一致的增益。

4.1 来自竞技编程的问题

编程竞赛和面试准备网站使用隐藏的单元测试来自动评判提交的功能正确性。这些问题是独立的,附有精心编写的问题陈述,并且通常具有出色的测试覆盖率。此外,这些问题测试广泛范围的核心技能和难度的算法推理。

我们从几个热门的编程竞赛和面试准备网站收集了问题陈述、函数签名和解决方案。然后,我们将这些组装成类似于HumanEval的编程任务,使用问题描述作为文档字符串。由于完整的测试套件通常是隐藏的,我们从问题陈述中找到的示例创建了单元测试,或通过提交不正确的解决方案提取了额外的测试用例。总共,我们以这种方式策划了10,000个问题。

4.2 来自持续集成的问题

接下来,我们从开源项目中策划了编程问题。利用sys.setprofile,我们能够追踪和收集集成测试期间调用的所有函数的输入和输出。然后可以使用这些数据为函数创建单元测试。
使用持续集成(CI)的项目是追踪的理想候选者。我们遵循CI配置文件中包含的命令,其中包含构建和测试命令,以设置虚拟环境,安装依赖项并运行集成测试。
我们考虑了使用travis和tox作为其CI框架的GitHub存储库,因为它们是最流行的两个CI工具。此外,我们还使用了在Python软件包索引(PyPI)中找到的pip包的公开可用源代码.由于这些项目包含不受信任的代码,运行在上述受限环境中描述的集成测试是非常重要的。

尽管存在着数百万个潜在的函数可供精选问题,但我们只收集了约40,000个,因为并非所有函数都接受输入并返回输出。即使有些函数接受输入并返回输出,大多数在运行时捕获的对象也无法被序列化并在项目未安装的情况下重新恢复。

由于我们的追踪方法为所有调用的函数产生了输入和输出,甚至被项目导入的内置和库调用也被转化为问题。因此,追踪产生的函数往往是命令行工具的构建块。为了在这些任务上表现出色,模型并不需要了解高级算法和数据结构。相反,它需要能够按照说明实现文档字符串中指定的功能。因此,追踪方法与编码竞赛问题的谜题性质相辅相成,并扩展了任务的分布范围。

4.3 筛选问题

在前面的部分中,我们介绍了两种自动生成训练问题的方法。然而,如何控制质量尚不清楚。有些提示未明确说明所实现的函数,这种情况下,一个完全有效的解决方案可能会被单元测试错误地惩罚。有些问题是有状态的,并且后续执行可能会产生不同的结果。 为了解决这些问题,我们使用Codex-12B为每个经过策划的问题生成100个样本。如果没有样本通过单元测试,我们认为该任务要么不明确,要么过于困难,并将其过滤掉。我们多次重新运行此验证以移除有状态或不确定性的问题。

4.4 方法

我们对这些训练问题进行Codex的微调,以生成一组“监督微调”模型,我们称之为Codex-S。为了从训练问题中产生示例,我们将问题组装成图2所示的格式。如果一个批次中存在不同长度的提示,我们会对较短的提示进行左填充,使得参考解决方案中的第一个标记在上下文中对齐。
我们训练以最小化参考解决方案的负对数似然,并对提示中的任何标记屏蔽损失。
我们使用比对Codex微调所用的学习率小10倍的学习率进行训练,但遵循相同的学习率计划,并训练直到验证损失趋于平稳(少于10B个标记)。

4.5 结果

与Codex类似,我们首先计算评估 pass@k(1 ≤ k ≤ 100)的最佳温度。我们发现,对于所有 k > 1,Codex-S 更喜欢稍高的温度,这可能反映了Codex-S 捕获的分布比Codex更窄。我们使用 来计算 pass@1,使用 来计算 pass@100。

接下来,我们比较Codex-S 和Codex 在 pass@1 和 pass@100 上的表现。在模型规模上,Codex-S 在 pass@1 上比相应的 Codex 平均提升了6.5个百分点,在 pass@100 上提升了更大的平均值,达到了15.1个百分点。

我们还绘制了对于 Codex-S-12B 不同样本选择启发式方法的性能与对应的 Codex-12B 启发式方法的性能图表。当按照平均对数概率对1到100个样本进行排名时,相对于随机排名,平均受益为11.6个百分点,这比对应的 Codex 的受益高出了2个百分点。

图9. 作为生成样本数量函数的最佳采样温度,适用于Codex和Codex-S。通常情况下,对于任何特定值的 k,Codex-S 需要更高的温度,可能是为了弥补其模拟较窄分布的事实。

图9. 作为生成样本数量函数的最佳采样温度,适用于Codex和Codex-S。通常情况下,对于任何特定值的 k,Codex-S 需要更高的温度,可能是为了弥补其模拟较窄分布的事实。

图10. 在第3节提出的指标上比较Codex-S和Codex。在pass@1和pass@100上,Codex-S的参数效率比Codex高出一到两个数量级,并且使用Codex-S进行对数概率样本排名与Codex相比,也能获得类似于随机抽样的收益。

图10. 在第3节提出的指标上比较Codex-S和Codex。在pass@1和pass@100上,Codex-S的参数效率比Codex高出一到两个数量级,并且使用Codex-S进行对数概率样本排名与Codex相比,也能获得类似于随机抽样的收益。

5 文档字符串生成

使用Codex从文档字符串生成代码是可能的,因为代码通常在文档字符串之后,但是很难诱导Codex从代码生成文档字符串。尽管如此,出于安全考虑,我们有动力生成一个文档字符串写作模型,因为这样的模型可以用来描述生成代码背后的意图。使用前面部分描述的训练问题,我们可以轻松地为代码条件的文档字符串生成创建一个训练数据集。

具体而言,对于每个训练问题,我们通过连接函数签名、参考解决方案,然后是文档字符串来组装一个训练示例。就像我们通过最小化参考解决方案的负对数似然来训练Codex-S一样,我们通过最小化文档字符串的负对数似然来训练文档字符串生成模型Codex-D。

当我们对我们的代码生成模型进行基准测试时,我们在HumanEval数据集上衡量pass@k,其中正确性通过通过一组单元测试来定义。然而,没有类似的方法自动评估文档字符串样本。因此,我们通过手工对样本文档字符串进行评分,如果文档字符串唯一且准确地指定了代码主体,则认为文档字符串正确。由于这个过程耗时,我们每个问题只对10个样本进行评分,总共1640个问题,来自于温度为0.8的Codex-D-12B。

Codex-D通常会生成与文档字符串一起的不正确的单元测试,但我们在评分时忽略了这些。然而,当模型简单地将代码主体复制到文档字符串时,我们不认为文档字符串是正确的。我们观察到的最常见的失败模式是,文档字符串模型省略了重要细节(例如“答案必须精确到两位小数”),或者过于依赖函数名称,创造了与函数主体无关的问题。

正如表3所示,Codex-D的pass率较低,但与同一温度下Codex-S的对应pass率相当。我们对哪种方式应产生更高的通过率没有强烈的假设。虽然生成文档字符串可能更宽容,因为自然语言语法不如代码语法严格,但我们数据集中的文档字符串可能质量较低,因为开发人员倾向于花较少时间编写文档字符串。事实上,我们的模型生成了像“我刚在网上找到这个函数”和“这个测试写得不正确,这不是我的解决方案”这样的文档字符串。

最后,使用文档字符串模型,我们又有了另一种方式来从k个样本中选择单个样本。与在前两节中研究的选择具有最佳平均对数概率的样本的方式不同,我们可以选择最大化后向翻译目标P(ground truth docstring|generated sample),其中P使用Codex-D评估。不幸的是,在图7中,我们显示通过后向翻译对样本进行排名低于平均对数概率排名,尽管它优于随机排名。这种启发式方法似乎也很快过拟合。

表3. 我们的文档字符串生成模型Codex-D的通过率,在缺乏基于自动评估的真实标准的情况下,每个任务手动对10个样本进行评分。与Codex-S相比,我们发现类似但较低的通过率。

表3. 我们的文档字符串生成模型Codex-D的通过率,在缺乏基于自动评估的真实标准的情况下,每个任务手动对10个样本进行评分。与Codex-S相比,我们发现类似但较低的通过率。

6 局限性

虽然Codex能够对大多数HumanEval问题进行正确采样,但我们发现它存在一些局限性。

首先,Codex在训练时效率不高。我们的训练数据集包括GitHub上公开可用的Python代码的大量部分,总计数亿行代码。即使是经验丰富的开发人员在他们的职业生涯中也不会接触到这么多代码。实际上,完成入门计算机科学课程的优秀学生预期能够解决的问题比Codex-12B更多。

接下来,我们探讨了Codex可能失败或显示反直觉行为的提示。尽管代码生成的评估已经被深入研究过,但许多现有的指标衡量了在严格指定、受限制的问题实例中的性能(例如FlashFill中的字符串操作)。因此,我们开发了一组定性指标,用于测量代码生成模型的能力,同时控制规格的复杂性和抽象级别(附录D)。应用这个框架,我们发现Codex可能推荐语法错误或未定义的代码,并调用未定义或超出代码库范围的函数、变量和属性。此外,Codex在解析越来越长和更高级或系统级的规格时遇到困难。

为了具体说明随着文档字符串长度增加,模型性能的降低,我们创建了一个合成问题数据集,由13个基本构建块组成,每个构建块以确定性方式修改输入字符串。例如构建块有“将字符串转换为小写”或“从字符串中删除每三个字符”(完整列表在附录C中描述)。我们发现随着文档字符串中链式构建块的数量增加,模型性能呈指数级下降。这种行为与人类程序员的特点不符,如果他们能够解决长度为两个的链条,他们应该能够正确地为任意长度的链条实现程序。

图11. Codex-12B样本的通过率与合成生成的文档字符串中链接组件数量的关系。随着每个额外组件的增加,通过率大约下降了2-3倍。

图11. Codex-12B样本的通过率与合成生成的文档字符串中链接组件数量的关系。随着每个额外组件的增加,通过率大约下降了2-3倍。

此外,就像其他模态下的文本条件生成模型难以将属性绑定到对象一样,Codex在将操作绑定到变量时可能会出错,特别是当文档字符串中的操作和变量数量很大时。例如,在以下提示中,Codex-12B没有对变量w进行减量操作,并且未能返回所有数字的乘积。

对Codex有限的系统级合成能力的理解有助于我们评估在生成能力中使用它可能存在的潜在风险,以及这类系统可能产生的更广泛的社会影响。

7 广泛影响和危险分析

Codex有许多潜在的有用之处。例如,它可以帮助用户熟悉新的代码库,减少经验丰富的编码人员的上下文切换,使非程序员能够编写规范并让Codex起草实现,同时有助于教育和探索。然而,Codex也带来了重大的安全挑战,它并不总是生成与用户意图一致的代码,并且存在被误用的可能性。

为了更好地理解在使用Codex进行生成时的一些危险性,我们进行了一项危险性分析,专注于识别可能造成伤害的风险因素(Leveson,2019年)。我们在几个风险领域发现了一些关键结果,以下是我们的一些主要发现。

虽然我们对代码生成系统潜在社会影响的一些发现是基于对面向生产的Codex模型(它是从本文描述的研究型Codex模型衍生而来)负责任部署的工作,但本节不旨在提供任何特定产品安全功能的全面说明。除非另有说明,我们的分析基于本文描述的模型的具体特性。我们分享这项分析是因为我们相信其中的一些内容可以推广到更广泛的代码生成系统类别,并鼓励作为重大机器学习研究项目的一部分进行详细影响分析的规范。

需要注意的是,通过在本节主要关注风险,我们并不是要暗示我们预期这类技术的影响是净负面的;相反,风险在这里受到特别关注是因为它们可能是微妙的,或者需要刻意努力来解决,而我们预期的好处对大多数用户和受影响的利益相关者来说更加明显和“自动”。

7.1 过度依赖

在实际应用中使用代码生成模型所面临的一个关键风险是对生成输出的过度依赖。由于上述所描述的限制以及下面描述的对齐问题,Codex可能会建议表面上看起来正确但实际上并没有完成用户意图的解决方案。这可能特别影响初学者程序员,并且根据上下文可能会有重大的安全影响。我们在附录G中讨论了一个相关问题,即代码生成模型可能会建议不安全的代码。基于这些原因,对于类似Codex这样的代码生成系统,人工监督和警惕性是必要的,以确保安全使用。

我们在下面的风险缓解子段中指出了几种改善安全性的即时方法,尽管特别是过度依赖是我们认为值得在工业界和学术界进一步探讨的问题。虽然向用户提供关于模型限制的文档说明在概念上很简单,但根据经验来确定如何可靠地确保实践中在一系列用户体验水平、UI设计和任务中保持警惕是必要的。研究人员应考虑的一个挑战是,随着能力的提高,防范“自动化偏见”可能变得越来越困难。

7.2 不对齐

与其他训练在下一个标记预测目标上的大型语言模型一样,Codex将生成与其训练分布尽可能相似的代码。这的一个后果是,这种模型可能会做一些对用户没有帮助的事情,尽管它有能力提供更多帮助(参见图12)。例如,如果用户的代码中存在一些微妙的错误,Codex可能会“刻意”建议表面上看起来不错但实际上是错误的代码。

这是一种不对齐(misalignment)——模型与用户意图不一致。非正式地说,如果有某个任务X,我们希望它完成,它“有能力”做到X,但“选择”不这样做,那么系统就是不对齐的。相反,如果系统由于没有能力做到X而未能完成X,那么这个系统就不是不对齐的,它只是无能。

研究不对齐是重要的,因为随着我们系统能力的增加,这个问题可能会变得更严重而不是更好。例如,图12中示例的模型大小缩放趋势表明,如果数据、参数和训练时间被放大,不对齐可能会持续存在甚至变得更糟。

虽然我们预计像这样的不对齐行为在当前的模型中不太可能造成重大伤害,但随着模型能力的增强,它可能变得更加危险和难以消除。一个高度能力强大但足够不对齐的模型如果经过用户批准训练,可能会生成对用户看起来良好甚至经过仔细检查也看起来良好的混淆代码,但实际上会做一些不可取或甚至有害的事情。

图12. 当提示包含微妙的错误时,Codex倾向于生成比其能力更差的代码。即使提示中还包括编写正确代码的指示,这种情况仍然存在。这种差距随着模型规模的增加而扩大。

图12. 当提示包含微妙的错误时,Codex倾向于生成比其能力更差的代码。即使提示中还包括编写正确代码的指示,这种情况仍然存在。这种差距随着模型规模的增加而扩大。

7.3 偏见和表征

与其他训练在互联网数据上的语言模型所发现的情况相似,我们发现Codex可以在编码注释中产生种族主义、贬低和其他有害的输出,这需要进行干预,如下面风险缓解子段中所讨论的。我们还发现代码生成模型引发了更多超越有问题的自然语言的偏见和表征问题:Codex可以生成具有反映性别、种族、情感、阶级、姓名结构和其他特征的结构的代码。特别是在可能过度依赖Codex或在没有首先考虑项目设计的情况下使用它的用户群体中,这个问题可能会产生重大的安全影响,这进一步促使我们要打击过度依赖。我们在附录F中进一步讨论了偏见和表征问题。过滤或调节生成的输出、文档和其他干预措施可能有助于减轻这些风险。

7.4 经济和劳动力市场影响

代码生成及相关能力可能产生一些经济和劳动力市场影响。虽然Codex在当前的能力水平下可能会通过提高程序员的生产力来在一定程度上降低软件生产成本,但这种影响的大小可能受到一个事实的限制,即工程师并不是将他们的全部时间都用于编写代码。其他重要的任务包括与同事交流、撰写设计规范和升级现有软件堆栈。我们还发现Codex以不同的速度导入。

7.5 安全影响

Codex可能对安全格局产生各种影响。由于Codex可能产生易受攻击或不对齐的代码,3在执行或信任其生成内容之前,有资质的操作员应在适当的预防措施不存在的情况下对其进行审核。

未来的代码生成模型可能能够训练出比普通开发人员更安全的代码,尽管这还不确定。

Codex也可能被滥用来协助网络犯罪。虽然这是值得关注的,但基于我们的测试,我们认为在它们当前的能力水平下,Codex模型并没有实质性地降低恶意软件开发的准入门槛。4我们预计更强大的代码生成模型将带来未来的进步,因此有必要进一步研究减轻措施并持续研究模型的能力。

像Codex这样的系统的非确定性性质可能会促使更先进的恶意软件。这种非确定性性质使得创建完成相同任务的多样化软件变得更容易。虽然软件多样性有时可能有助于防御者,5但它对传统的恶意软件检测和反病毒系统提出了独特的挑战,这些系统依赖于对先前采样的二进制文件进行指纹识别和签名匹配。例如,一个更强大的代码生成模型可能能够推进生成多态恶意软件的技术。6我们相信应用安全和模型部署策略,包括限制访问和滥用监控,可以在短期内管理这种威胁;然而,随着更强大的模型的开发,这些减轻措施的有效性可能会呈次线性增长。

与大型语言模型类似,Codex模型可以学习其训练数据中存在的模式。源代码中存在的敏感数据可能会被模型预测到。由于Codex是在公共存储库上训练的,我们认为训练数据中存在的任何敏感数据都已经遭到泄露。同样,公共数据通常应被视为不可信,因为先前的研究发现攻击者可能能够破坏训练数据,以在运行时触发特定的模型行为。我们在附录G中进一步讨论了安全影响。

7.6 环境影响

像其他大型生成模型一样,Codex 在训练和推理方面都有能源消耗。GPT-3-12B 的原始训练消耗了数百个 petaflop/s·days 的计算资源,而将其微调为 Codex-12B 也消耗了类似数量的计算资源。此次训练是在一个购买碳信用额度并且使用大量可再生能源的平台(Azure)上进行的,从而减少了其碳足迹。计算资源消耗也在更广泛的供应链中产生成本,这些成本在某些地区可能非常集中。从更全球和长期的角度来看,如果需要大量推理来解决具有挑战性的问题,代码生成的计算需求可能会远远超过 Codex 的训练。

7.7 法律影响

生成的代码涉及到几个法律考虑因素。首先,对于在互联网数据(例如公共 GitHub 存储库)上训练 AI 系统,先前已被确定为“合理使用”的一种情况。

我们的初步研究还发现,Codex 模型很少生成与训练数据内容相同的代码。在一项研究中,检查了看似与训练数据中的代码片段匹配的代码生成的频率,这种情况发生的概率小于 0.1%。在这些罕见的情况下,生成的代码由编程语言中反复出现的常见表达式或惯例组成,这些表达式在训练数据中反复出现。我们发现,生成的代码如果与训练数据内容完全相同,是由于模型中的预测权重而不是特定代码的保留和复制。 生成的代码也是响应性的,并且根据用户的输入进行定制,用户保留对生成代码的完全控制权。这使得代码生成类似于其他创作工具的自动建议或自动完成功能(例如文档编辑器),在这种情况下,最终的作品仍然被视为作者的作品。

我们致力于负责任和安全的 AI,包括持续关注代码生成系统的广泛知识产权影响。我们打算与决策者和专家就这些问题保持联系,以便系统的用户最终可以自信地部署它们。

7.8 风险缓解

在结束时,鉴于上述情况,像Codex这样的模型应该被开发、使用,并且谨慎地探索其能力,以最大程度地增强其积极社会影响,并最小化可能造成的有意或无意的危害。在有效的危害分析和缓解中,关注上下文是至关重要的,尽管在任何代码生成模型的部署中考虑一些广泛的缓解措施也是重要的。

谨慎的文档记录和用户界面设计、代码审查要求和/或内容控制(例如,输出的过滤)可能有助于减少与过度依赖以及冒犯性内容或不安全代码生成相关的危害。在作为服务提供的模型的情境中(例如,通过 API 提供),诸如用户审查、用例限制、监控和/或速率限制等政策也可能有助于减少与恶意使用相关的危害,或防止其在模型不适合的高风险领域中使用。

结论

我们研究了是否有可能训练大型语言模型从自然语言的文档字符串中生成功能正确的代码主体。通过在来自GitHub的代码上进行微调GPT,我们发现我们的模型在一个由人类编写的问题数据集上表现出很强的性能,难度水平类似于简单的面试问题。模型性能可以通过在与评估集更相似的分布上进行训练,并通过从模型生成多个样本来改善。我们还发现,训练模型来完成从代码主体生成文档字符串的反向任务非常简单,并且这些模型的性能特征相似。最后,我们扩展了代码生成模型的更广泛影响,并讨论了模型的局限性,发现有很大的改进空间。

关于我们


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/374641
推荐阅读
相关标签