NL2Code综述:神经网络方法在自然语言到代码任务中的应用

释放双眼,带上耳机,听听看~!
本文综述了神经网络方法在自然语言到代码(NL2Code)任务中的应用,提供了一个全面的框架,并对现有的研究进行了深入调查,同时列出了未来的研究方向。

导语

最近调研到一篇NL2Code领域比较全面的综述文章,是上个月挂到Arxiv的,总结了很多最新的内容,这篇论文涉及的方面还算是比较广,然而文章稍有冗余,给人感觉像是在凑字数撑篇幅,很多关键的地方又是浅尝辄止。不过,整体而言,还是可以拓展眼界的综述文章。

1 简介

自然语言到代码(NL2Code)任务的提出是为了评估人工智能编程的能力,其目的是生成针对给定自然语言的代码。在实际编程中,如何用NL2Code的NL描述自己的需求并不是唯一的,它可能是极其多样的。例如,对于一个需求,NL可以用不同的语言(英语、中文等);不同的形式(代码注释、编程比赛问题等);不同的粒度来描述(即用户可以根据其背景知识、功能、算法过程等来描述需求)。此外,NL需求需要一些编程约束,例如编程语言、代码库、时空复杂性等。如上所示,NL2Code任务本身就具有高度的通用性、多样性和复杂性,本文在2022年末对NL2Code的发展进行了调查。

本文首先为NL2Code任务总结了一个整体框架,然后将现有的论文合并到框架中。NL2Code任务最初是在软件工程(software engineering,SE)和编程语言(programming language,PL)领域提出的。最近,神经网络(NN)凭借其令人印象深刻的代码生成能力在NL2Code中赢得了广泛的关注。本文主要研究NN如何求解NL2Code。本文发现这些基于神经网络的方法通常基于SE和PL领域的见解使用神经网络进行建模。本文从交叉领域的角度对这些方法进行了深入的调查。除了方法,NL2Code还涵盖了许多模型、产品、数据集和指标。本文也分别调查了它们并总结了NL2Code的框架,如图1所示。该框架能够覆盖所有NL2Code论文,便于研究者快速掌握一篇新的NL2Code论文并定位其创新思想。基于此框架,本文对现有的NL2Code论文进行了解析。此外,本文还建立了一个在线网站来展示分析结果,进一步方便研究人员。

NL2Code综述:神经网络方法在自然语言到代码任务中的应用

本文贡献如下:

  • 本文首次在任务输入和输出(I/O)、方法、数据集、评估指标、模型和产品方面为NL2Code提供了一个全面的框架。
  • 基于该框架,本文对大量NL2Code论文进行了深入调查,并开发了一个在线网站来展示调查结果,以便随时了解NL2Code的最新进展。
  • 基于框架和调查结果,本文列出了现有的挑战,以及NL2Code未来的研究方向。

2 框架

框架如图1所示,本文首先介绍了NL2Code(§3,即第三章,下同),这是软件工程(SE)和编程语言(PL)中长期具有挑战性的任务。在这项任务下,产生了许多方法。本文特别关注这些基于神经网络(NN)的方法(§4),这些方法通常用作NL2Code任务的主要方法。因此,该框架结合了来自SE和PL的见解来研究基于NN的方法。除了方法,本文还包括NL2Code的模型(§5)、产品(§6)、数据集(§7)以及评估指标(§8)。图1描绘了上述每个模块之间的相关性,而图2为每个模块提供了更详细的信息。

NL2Code综述:神经网络方法在自然语言到代码任务中的应用

3 何为NL2Code?

给定一种描述用户需求的自然语言(NL), NL2Code的目标是生成处理需求的代码。在本文中,我们重点研究了神经网络(NN)方法来面对NL2Code。因此,这个任务可以形式化为:Code=M(NL)Code = textbf{M} (NL),其中Mtextbf{M} 表示NN模型。在NL2Code定义之上,如图2的上半部分所示,有两个关键点需要明确:

  1. 用户如何使用NL描述他们的需求?
  2. 用户对代码的编程约束包括什么?

对于第一个问题,我们提出了几个维度来衡量如何描述需求。具体而言,这些维度包括NL使用的自然语言(如英语、中文)、描述格式(如代码注释、竞争问题)和描述粒度(如功能、算法过程)。此外,NL2Code任务的输入,除了需求的描述之外,有时还有额外的信息,例如代码上下文、类、文件和存储库。这也模拟了人类在编程时也可能引用这些附加信息。

对于第二个问题,即Code的编程约束,作为一个特定的用户需求,也可以包括许多维度。具体来说,我们可以使用不同的编程语言(如Python、Java)和代码库(如pandas、NumPy)来实现面向不同领域(如通用、数据科学)的不同级别的代码(如行、函数)。

4 方法

4.1 现存方法的概述

在NL2Code研究之初,出现了大量基于强规则或专家系统的方法。例如,领域特定语言(DSL)引导方法要求专家灌输深入的领域知识,如抽象语法树或语法规则,以产生我们想要的结构化代码,这极大地限制了他们的灵活性。此外,基于概率语法的方法能够生成高质量的程序。然而,这种方法严重依赖于预定义的规则,因此它们的可伸缩性也较差。

除了上述基于规则的方法外,还有其他使用静态语言模型的方法,如n-gram和Hidden Markov。尽管它们不需要领域知识和复杂的规则,但它们不能建模长期依赖关系,而且它们的向量表示是稀疏的。

与上述静态语言模型需要显式计算每个token的概率不同,基于神经网络(NN)的方法首先将每个token编码为中间向量,然后解码。整个过程是端到端的学习,不依赖于任何特征工程。随着训练语料库计算能力和规模的增加,神经网络的参数越来越多,这使得其代码生成能力日益强大。

4.2 基于神经网络的方法

与其他类型的方法相比,神经网络(NN)在NL2Code任务中表现出惊人的能力,并且可以在实践中部署以提高编码效率。

NL2Code综述:神经网络方法在自然语言到代码任务中的应用

4.2.1 NN的视角

自然语言处理(NLP)领域提出了许多使用NN的方法,被广泛应用于各种其他领域,如NL2Code。本文总结了几种常见的神经网络视角,并确保这些视角可以覆盖所有的神经网络方法。更多的细节可以在图2的左下角找到。从这些角度出发,基于作者分析了2016年至2022年在顶级会议上使用相关方法、技术的NL2Code出版物数量的趋势,作者提出了一些见解:

  • 神经网络体系结构。这种视角将NL2Code方法分为以下几个方面:CNN,RNN ,LSTM,GAN,Transformer等等。如图3 (a)所示,Transformer在提出后迅速应用于NL2Code,并且呈指数级增长。而CNN和RNN/LSTM均有下降趋势。这表明Transformer在建模代码方面优于其他架构。
  • 模型学习方式。NL2Code的学习方法分为有监督学习,无监督学习,强化学习(RL),多任务学习(MTL),对比学习(CL) ,基于检索的学习等。如图3的(b)和(c)所示,与有监督学习相比,无监督学习在解决NL2Code问题上的增长趋势。与此同时,越来越多的努力集中在利用人类反馈(如RL)、额外的知识和额外的任务(如MTL、CL、基于检索的学习)等来提高生成代码的可靠性。
  • 模型范式。它们包括非预训练,预训练-微调,Zero-shot学习,Few-shot学习,Prompt tuning,In-Context learning等。如图3 (d)所示,随着神经网络语言模型变得越来越强大,Zero-shot,Few-shot、In-Context learning受到越来越多的关注。此外,它们正逐渐超越预训练-微调,成为主导范式。
  • 社会偏见、模型压缩和模型可解释性。研究者们对NL2Code的目标是逐渐将其应用于实际场景,而不仅仅是玩具场景。

4.2.2 SE&PL视角

NN方法基于SE和PL的见解求解NL2Code。本文也从SE和PL的角度考察了NL2Code方法。

软件工程(SE)是一门使用工程实践研究软件开发和维护的学科。所以它主要包括以下几个维度:软件开发、软件维护、集成开发环境(IDE)。NL2Code的目标是通过设计更好的IDE来提高软件开发和维护的效率。

编程语言(PL)是一种用于定义计算机程序的形式语言。此外,NL2Code让NN方法学习如何使用PL来构建用户想要的软件。因此,就像人类一样,NN方法需要学习PL所涉及的内容,如果他们希望正确编程。因此,本文将PL划分为PL特性、PL资源和代码托管平台等多个维度。

  • 神经网络方法可以使用PL特征进行学习,例如可执行、动态/静态、过程/对象/面向方面。但随着模型参数数量呈指数级增加,模型对这些精心设计的特征的依赖程度逐渐降低,如图3 (e)所示。这可能是因为模型可以从大量的代码文件中学习PL特征。
  • 训练NL2Code模型需要一个大规模的语料库。语料库可以是代码文件、测试用例、NL-代码对、存储库、API文档,甚至抽象语法树(AST)、数据流(DF)或控制流(CF)。如图3的(f)和(g)所示,近年来,代码文件作为PL的重要资源,越来越多地用于以无监督的方式训练模型。此外,由于无监督方式不需要手动标记NL-代码对,这些对显示出下降趋势。最近提出的方法利用了额外的资源来提高代码质量。例如,Li等人使用测试用例来产生更好的代码;Shrivastava等人利用存储库信息来提高API的准确性;Zhou等人使用API文档生成私有API;Paik等人利用AST、DF、CF来建模更稳健的向量。
  • 大量的代码语料库存在于各种平台上,GitHub作为最大的代码托管平台,为训练神经网络模型贡献了大量的代码语料库。此外,图3的(h)中观察到,StackOverFlow中的问答帖子正在逐渐被挖掘出来以训练神经网络模型。此外,编程竞赛网站(如CodeForces和LeetCode)上的语料库被用于训练模型,期望它们能够自动生成任何编程问题的解决方案。

5 预训练模型

表1比较全面的总结了近几年的一些NL2Code模型。

NL2Code综述:神经网络方法在自然语言到代码任务中的应用

NLP中生成模型由两种主要的神经网络架构组成:Encoder-decoder结构,如T5,BART和Decoder-only,如GPT。这些体系结构应用于NL2Code后的工作有PyMT5、CodeT5、PLBART、GPT-C、CodeGPT和ERNIE-Code。由于上述模型相对较小(百万级参数),它们在生成代码方面没有表现出强大的能力。

Codex是一个拥有十亿级参数的大型语言模型,通过在大规模和高质量的代码语料库上进行训练,它显示出惊人的性能。不幸的是,Codex仅通过OpenAI的API提供访问,而不发布其数据、代码和模型。DeepMind也很快提出了AlphaCode,它的性能与Codex相当,但同样不可用。

后续的许多工作如CodeClippy, CodeParrot和PolyCode都致力于训练一个公开可用的模型。虽然这些模型是完全可用的,甚至包括它们的训练数据,但它们的性能仍然不如Codex和AlphaCode。随后,CodeGen、PyCodeGPT、PanGuCoder、CodeRL等模型的表现令人印象深刻,但他们只发布他们的模型,而不公开他们的训练数据。以上是NL2Code预训练模型的路线图。

此外,研究者还提出了一些模型来解决NL2Code中的更多场景。例如,CodeGeeX经过训练,可以支持多种自然语言和编程语言;InCoder和FIM不仅支持从左到右的代码预测,而且还支持填充代码的任意区域。

6 产品

预训练模型作为底层技术,被包装到产品中,提高用户的编程效率。2021年,GitHub和OpenAI联合推出了Copilot ,这是一种编程辅助工具,使用Codex实时提供建议,方便代码补全。它支持多种编程语言和集成开发环境(ide)。它可以帮助程序员使用一种新的编程语言,甚至解决bug。表2列出了目前流行的产品。大多数商业产品逐个支持更多的编程语言和ide,这反映了商业竞争仍然激烈的事实。这些产品通常是由大公司推出的,这意味着人工智能驱动的编程产品在计算能力、核心技术等方面具有极高的门槛。

NL2Code综述:神经网络方法在自然语言到代码任务中的应用

最近的研究对这些产品的实用性进行了深入调查,研究发现这些产品也有一系列缺点,即使它们可以推荐用户无法编写的代码。例如,产品生成的一大块代码可能包含一些小错误,这使得用户很难发现。这可能会导致调试代码比从头编程花费更多的时间。因此,在使用这些产品时,应该彻底调查其优点和缺点。产品开发人员不仅要提高模型的性能和速度,还要考虑如何设计出好的产品,比如如何利用用户反馈进行持续学习。

7 数据集

一些数据集提供了训练集和测试集,其中模型需要在训练集上学习,然后在测试集上验证。随着模型的强大,它可以在不需要任何额外训练集的情况下很好地工作。因此,许多后续数据集只提供了测试集而没有训练集。

早期提出的数据集,如Django、CoNaLa、CONCODE和CodeSearchNet,往往是通过BLEU和准确性等硬性指标来评估的,而不是通过在测试用例上执行。这是因为早期的模型不能生成通过任何测试用例的代码,所以它们必须用前者进行评估。相比之下,最近的数据集,如HumanEval、MBPP、APPS、P3、CodeContests和DS-1000,其中通常每个编程问题都配备了多个测试用例。与没有测试用例的数据集相比,这些配备了测试用例的数据集通常包含相对较少的实例,因为为编程问题编写测试用例极具挑战性。

NL2Code综述:神经网络方法在自然语言到代码任务中的应用

大多数现有数据集的自然语言是英语,编程语言是Python。为了测试模型面向多语言的代码生成能力,MCoNaLa将CoNaLa的英语扩展为西班牙语、日语和俄语等多种自然语言;MBXP扩展了MBPP,在多种编程语言中使用,如Java、JavaScript、TypeScript、c++和c#;HumanEval也已经从python版本扩展到多种编程语言的HumanEval-X和MultiPL-E。

这些数据集的另一个趋势是,它们越来越与现实场景相关,而不仅仅是玩具场景。HumanEval和MBPP是人工标注的,并确保在训练期间不被看到。这样的设置符合实际情况。此外,还提出了APPS和CodeContests来评估实际的编程竞争场景。随后,面向领域的数据集,如用于数据科学的DS-1000和用于数学的GSM8K-Python和MathQA-Python被提出。此外,还提出了PandasEval和NumpyEval来评估面向库的代码生成,因为我们在实践中不仅使用内置库来编码,而且经常使用第三方库。除了上面提到的内置库和公共库,我们在日常编程中也会遇到私人库。因此Zan等人提出了三个名为TorchDataEval、MonkeyEval和BeatNumEval的私有库数据集。

上述所有数据集都将每个编程问题一次性输入到模型中,而MTPB则探索了是否可以将编程问题分解为多个子问题依次向模型反馈。这也被称为多回合程序合成。虽然大多数数据集专注于评估生成代码的准确性,但它们的安全性在实际编程中同样至关重要。为此SecurityEval数据集被提出用于评估代码的安全性。

8 评价指标

8.1 人工评估

如题,在小规模数据集上还行,但无法适用于大规模数据集,费时费力。

8.2 机器翻译领域的评价指标

由于该任务广泛意义上还是Seq2seq任务,因此可以采用机器翻译领域的一些指标,如:

  • BLEU
  • ROUGE
  • METEOR
  • chrF
  • Exact match (EM)

8.3 面向Code任务的修改指标

Tran等人提出了一种新的度量标准RUBY,它考虑了程序依赖关系图和抽象语法树。此外,Ren等人还提出了一种名为CodeBLEU的复合指标,该指标不仅最大限度地发挥了BLEU的优势,而且还通过AST和数据流考虑了代码语法和语义。

8.4 基于执行结果的指标

对于一种需求,存在各种解决方案。在这种情况下,机器翻译指标及其修改后的版本无法正确地评估生成的代码。许多基于执行的度量,如pass@k, n@k等被提出。定义如下:

  • Pass@k由CodeX提出。对于每个测试实例,对n个生成的候选程序进行抽样,然后随机选择其中的k个。如果k个中的任何一个通过了给定的测试用例,则该实例可以被视为已解决。pass@k是数据集中已解决实例的比例。
  • n@k类似于pass@k。它通过特定的策略从n个程序中选择k个,而不是随机的。
  • Test case average由Hendrycks等人提出,它计算通过测试用例的平均百分比。

9 在线网站

发布和维护一个在线网站用于更新NL2Code资源,网址为:nl2code.github.io

10 挑战和机遇

总结以上内容,作者提出了若干后续面临的挑战和急需解决的问题:

  1. 用户应该以何种方式提出需求;
  2. 如何让模型更像人类一样学习;
  3. 如何编辑大型语言模型内部的知识;
  4. 如何使模型知道它可以正确回答哪些编程问题?哪些不能?
  5. 如何解释生成的代码;
  6. 语言模型如何与NL2Code中的知识图相结合?
  7. 模型如何推广到其他编程语言?
  8. 如何加快训练和推理速度?
  9. 将代码建模为纯文本是否合理?
  10. 如何更好地评估生成的代码?
  11. 模型如何处理长代码?
  12. Code LLM可以解决哪些场景?

11 总结

本文提供了NL2Code的框架,包括任务I/O、方法、模型、产品、数据集和评估指标。同时,建立了一个在线网站来记录调查结果。同时,基于框架和调查结果,作者总结了NL2Code目前面临的挑战和未来的机遇。希望本文能对NL2Code研究人员的研究工作有所帮助。

本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

Mochi Diffusion:极致性能和极低内存占用的苹果芯片Mac应用

2023-12-18 18:21:14

AI教程

计算机视觉竞赛技巧总结(一):目标检测篇

2023-12-18 18:36:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索