©作者 | 昝道广,AINLPer

单位 | 中国科学院软件研究所

研究方向 | 代码生成

引言

 

对于 NL2Code 任务相信大家都不陌生。它主要目的就是将自然语言转换成可执行代码来提高开发人员的工作效率,终极目标就是干翻所有程序员,最近,随着大模型的出现,距离这一天又稍稍进了一步。

基于该背景,分享中科院和微软亚洲研究院合作在 ACL 2023 国际顶会上发表的一篇综述:他们调研了 NL2Code 领域中的「27 个大型语言模型以及相关评价指标」,分析了「LLMs 的成功在于模型参数、数据质量和专家调优」,并指出了「NL2Code 领域研究的 5 个机遇挑战」,最后作者建立了一个分享网站「https://nl2code.github.io」来跟踪 LLMs 在 NL2Code 任务上的最新进展。

论文标题:
Large Language Models Meet NL2Code: A Survey

收录会议:

ACL 2023

论文链接:

https://arxiv.org/abs/2212.09420 

实时网站:

https://nl2code.github.io 

背景介绍

 

新手程序员,甚至是那些没有任何编程经验的程序员,是否有可能仅仅通过用自然语言描述他们的需求来创建自己想要的软件?实现这一设想将对我们的生活、教育、经济和劳动力市场产生前所未有的影响。NL2Code 因其广阔的应用场景,成为了是一项重要的任务,在学术界和工业界都引起了广泛的兴趣。

 

关于 NL2Code 的发展情况,其实和自然语言处理领域的发展类似。一开始,基本都是基于专家规则进行算法设计,但是此类方法需要对不同编程语言进行设计,泛化性差;随着技术发展,人们逐步开始使用静态语言模型,并使用向量空间来描述文字,此类方法在初期一般向量空间比较稀疏,不能建立长期的依赖关系;再后来,就用到了我们比较熟悉的神经网络,例如 CNN、RNN、LSTM,此类方法通过标记数据进行训练来构建自然语言(NL)和代码(Code)之间的关系。

 

虽然这类方法能够在标准数据集上提升一些,但是其实际效果远远不能够服务于实际编码;现在,在 ChatGPT 风靡全球的背景下,越来越多的大型语言模型(LLMs)如雨后春笋一样出现,通过语言指令,它们可以在零样本状况下生成代码,并在NL2Code 任务上中取到了惊人的成绩。具有标志性的一个 LLM 模型就是 Codex [1],它可解决 72.31% 的 Python 编程问题,并且该模型已经商用(Copilot)可在实践中提高开发人员的工作效率。

 

由于 Codex 的在 NL2Code 上的“成功”,各种各样的 LLMs 被提出。例如AlphaCode,InCoder,CodeGen,PaLM-Coder,PanGu-Coder,CodeGeeX,StarCoder 等。我们可以观察到,随着模型参数量的增加,LLMs 展现了一些很有意思的突现能力,例如在一定程度上它们具有和和人一样的编码能力,甚至可以调试代码。

27个流行的代码大模型

 

对于 NL2Code 任务,其主要目的是基于给定自然语言问题描述生成所需要的代码。以下是一个关于 Python 编程问题的示例。其中灰色块部分表示问题描述,绿色块部分表示模型生成代码,黄色块部分表示测试样例。

针对 NL2Code 任务对 27 个具有代表性的 LLMs 进行了全面调研,下表总结了每个模型的详细信息,其中主要包括:模型架构、模型大小、模型层数(L)、注意力头数量(A)、隐藏维度(H)、模型参数是否开放(P)等五个方面。

为了更好地可视化,下图按时间顺序展示了这些模型,绘制了最大的模型大小。观察到的一个趋势是,随着研究领域的发展,这些大型语言模型的规模也在不断扩大。此外,只有解码器的架构更适合于规模较大的预训练模型。

代码大模型“成功”的因素

 

上面总结了 NL2Code 现有的大型语言模型(LLMs),但是这些模型在架构、模型规模等方面各不相同,无法进行统一的评估。为此,作者在 HumanEval 和 MBPP 基准数据集上进行了统一评估。文章使用 pass@k 作为评估指标,即通过 k 次尝试可以正确回答的问题的比例。下表显示根据模型大小进行分组,在 HumanEval 的测试结果。

 

从上表可以看出,这些 LLM 在该数据集上的性能差异很大,尽管模型参数相似但效果差异也是很大。可以发现 Codex 在各种尺寸上都处于领先地位。为什么会存在这个问题呢?影响模型效果的关键因素是啥呢?过分析给出的结论有:模型大小、数据质量、专家调优。

模型大小

根据前面的整理用于 NL2Code 的 LLMs 时间发展图可以发现,只要模型参数越多性能就越好。为了进一步说明模型参数大小和模型效果之间的关系,整理了 10 个比较有代表性的模型,在 HumanEval 基准上的 pass@1 结果,如下图所示:

根据上图,很明显的可以「发现较大的模型通常会产生更好的结果」。此外,「当前模型无论大小,仍然可以通过进一步增加模型参数来实现性能的提升」。

数据质量

随着 LLMs 模型参数的增加,其训练数据规模也在不断的增加。这在数据选择和预处理方面也有更高的要求。早期的模型,例如 CodeSearchNet、CoST、XLCoST 等都是基于人工标注数据对进行训练(耗时耗力);GPT 系列模型(GPT-3 、GPT-Neo、GPT-J )开始在大规模无监督数据集上进行训练,但是由于代码数据限制,并没有显示出很强的代码生成能力。由于 LLMs 模型的出现,它们可以在更大规模的未标记代码数据集上进行训练,最终模型效果惊人。

在惊叹于 LLMs 效果的同时,也要知道 LLMs 在训练之前通常会对数据进行预处理。为此作者调研了 Codex、AlphaCode、CodeGen、InCoder 和 PyCodeGPT 等 5 个强大模型的数据预处理方法。发现它们具有几个共同的特点:一是删除可能自动生成或未完成的代码文件,二是使用特定的规则来过滤不常见的代码文件。「总之,这些预处理策略的目标是实现一个不重复的、完整的、正确的、干净的和通用的代码语料库」。

专家调优

训练一个优秀的模型需要认真考虑模型训练阶段的各个参数。通过对 27 个 LLMs 模型的研究发现,它们都有一些共同的设置,比如都应用了 Adam 相关优化器并在初始化阶段相差不大。除此之外,还有需要调节的超参数,如 lr、batch、窗口大小、预热、梯度累积和 temperature。对于学习率来说,随着模型的增大,学习率会逐步变小。如下图所示:

对于 temperature,这里对比了两个模型在 HumanEval 任务上使用不同 temperature 后模型的性能。结果发现,更高的 temperature 产生更低的 pass@1 和更高的 pass@100,这表明更高的 temperature 使 LLM 产生更多样化的预测,反之亦然。如下图所示:

此外,有研究表明窗口大小也是一个关键因素,具有大窗口的小模型会有时优于具有小窗口的大模型。此外,强大的 LLMs 通常主要使用两种技术在代码语料库上训练新的标记器:字节级字节对编码和 sentencepece 。新的标记器可以更有效和准确地将代码内容拆分为 Tokens。这些经过验证的调优技术将为培训更强大的 LLMs 提供有价值的参考。

代码生成的数据集

「对 NL2Code 任务的评估,高质量的基准和可靠的度量是基础和必要的」。作者总结了 17 个 NL2Code 基准测试,每个基准测试在大小、语言、复杂性和场景方面都有自己的特点,如下表所示:

但大多数基准测试只包含有限数量的实例。例如,HumanEval 和 MBPP 分别有 164 和 974 个实例。这是因为这些基准通常是手写的以防数据泄露。「在大型语言模型时代,在创建新基准时避免数据泄漏至关重要」。此外,大多数当前的基准测试都有英文的问题描述和 Python 的代码解决方案。

最近,已经提出了几个多语言基准,例如涵盖「多种编程语言的 MBXP,HumanEvalX 和 MultiPL ,以及涵盖多种自然语言的 ODEX」。多语言基准测试的详细信息如下表所示:

「手动评估生成的代码是不切实际的,这就需要自动度量」。上述基准均提供了基于执行的评估的测试用例,其中指标如 pass@k、n@k、测试用例平均值和执行精度。

但是,「这种方法对测试用例的质量有严格的要求,并且只能评估可执行代码。对于不可执行的代码」,使用了 BLEU 、ROUGE 和 CodeBLEU 等指标,无法准确评估代码的正确性。到目前为止,「在设计指标来评估代码的各个方面(例如漏洞、可维护性、清晰度、执行复杂性和稳定性)方面存在许多开放性挑战」。

代码生成大模型的挑战和机遇

大预言模型在 NL2Code 的应用对学术界和工业界都有相当大的影响。虽然取得了惊人的进展,但仍然有很多挑战需求解决,这也为研究人员提供了充足的机会。下面作者从 LLM 和人的区别的角度总结了 NL2Code 任务的挑战和机遇。

「1. 理解能力」:人类能够理解不同抽象层次的各种描述,相比之下,当前的 LLM 往往对给定的上下文敏感,这可能会导致性能下降。一个潜在的解决方案是把复杂的问题拆分成多个简单的问题。总而言之,作者认为探索 LLM 的理解能力是一个重要的研究方向。

「2. 判断能力」:人类能够判定一个编程问题是否被解决。当前模型不论输入什么都会给出答案,而且该答案正确与否都不能确定,这在实际应用中会存在一定的问题。目前为了提高 LLM 的判断能力,需要根据用户反馈采用强化学习的方式进行调优。也有的使用 LLM 内部的知识一致性来提高模型的判断能力。不管如何,作者认为探索 LLM 自我判断能力上还有很大的可探索空间。

「3. 解释能力」:人类开发人员能够解释他们编写的代码,这对教育的和软件维护至关重要。最近的研究表明,LLM 具有自动生成代码解释的潜力。作者认为针对该能力也需要进一步的研究和探索,以充分发挥 LLM 在这方面的潜力。

「4. 自适应学习能力」:当前的大型语言模型与人类之间的一个根本区别是它们适应新知识和更新知识的能力。当遇到一些新的 APIs 时,人类开发人员能够根据文档资料实现 API 的快速开发,而 LLM 重新训练或者微调。目前,APICoder 和 DocCoder 都使用了基于检索的方法来增强模型的自适应学习外界知识的能力,但是作者认为如何提高 LLM 快速自学习能力仍需要进一步提升,也是一个比较大的挑战。

「5. 多任务处理能力」:代码大模型可以应用到各种各样和代码相关的任务中,例如代码修复,代码搜索,代码审核等。甚至代码大模型可以解决所有可以形式化为代码形式的下游任务。但是,目前的代码大模型在多任务处理方面与人类存在较大差异。人类掌握了一定的知识之后可以在任务之间无缝切换。然而,代码大模型则需要复杂的提示工程来完成不同任务之间的转换。为此作者任务提升 LLM 多任务能力同样是一个重要的研究方向。

代码大模型网站

为了持续跟踪代码生成大模型领域的实时进展,作者提供了一个任何人都可编辑的实时更新在线网站:

https://nl2code.github.io/

作者已经尽可能多地在这个网站上收集了最新的研究成果。每个人都可以通过在 GitHub 上提出请求来为该网站做出贡献。该网站还包括模糊搜索和自定义标签类别等功能,这将有助于研究者快速找到他们想要的模型或者论文。希望这个网站能够帮助相关领域的研究者和开发者,为其进步做出贡献。

参考文献

[1] Chen M, Tworek J, Jun H, et al. Evaluating large language models trained on code[J]. arXiv preprint arXiv:2107.03374, 2021.