软件工程在大型模型时代的新视角:现状与未来

发表时间: 2024-03-01 09:22

A Survey on Large Language Models for Software Engineering

Quanjun Zhang1, Chunrong Fang1, Yang Xie1, Yaxin Zhang1, Yun Yang2, Weisong Sun1, Shengcheng Yu1, Zhenyu Chen1

1State Key Laboratory for Novel Software Technology, Nanjing University, China

2Department of Computing Technologies, Swinburne University of Technology, Australia

引用

Zhang Q, Fang C, Xie Y, et al. A Survey on Large Language Models for Software Engineering[J]. arXiv preprint arXiv:2312.15223, 2023.

论文链接:

https://arxiv.org/abs/2312.15223

项目地址:

https://github.com/iSEngLab/AwesomeLLM4SE

摘要

本文对大模型在软件工程中的应用进行了系统性的概述和整理,具体收集了截至2023年11月的185篇高质量研究论文,讨论了三种模型架构下的30种代表性大模型,四大类15种预训练任务,五大类16种下游代码任务,以及四大软工阶段43种重要的应用场景。

引言

大语言模型,简称大模型,泛指基于 Transformer 架构开发的预训练文本语言模型。大模型通过自监督预训练从超大规模的真实世界数据中学习通用知识,并通过非常庞大的模型参数量将其应用到多个下游任务。在软件工程社区,大模型展现了令人惊叹的结果,对多个领域带来了重大的影响和革命性的变革。

在软件工程(SE)领域中,一些早期的模型,如BERT、T5与GPT,和他们在代码领域的变体,如CodeBERT、CodeT5与CodeGPT,以及最近的超大规模模型,如ChatGPT、GPT4与CodeLLama,已经在推动代码自动化处,如代码摘要生成与代码检索等关键任务上展现了令人瞩目的结果。这些模型通过在海量无标注数据集上进行自监督式预训练,获得通用语言表征,随后通过监督式微调技术,适配于特定的下游任务。然而,由于SE场景的复杂性,结合持续涌现的、架构多样化的LLMs,以及各异的模型利用方式,导致了将大模型应用到软工中是一项具有挑战性的任务。

大语言模型正向软件工程社区掀起一场前所未有的风暴,从处理范式到结果表现均改变了现有的研究格局。本文主要从大模型和软件工程两个角度展开,RQ1总结了30种代表性的大模型,涵盖了三个主要发展方向,以及相应的15种预训练任务和16种下游任务,此外还讨论了 LLMs在开源方面的情况,强调了在软件工程领域使用LLMs面临的独特挑战和机遇;RQ2详细回顾了近期使用大模型进行的软工研究,特别关注它们在软件开发生命周期的四个关键阶段(需求、开发、维护和测试)中43种具体任务中的使用,这一部分突出了利用LLMs自动化和增强这些阶段特定任务的各种研究进展;RQ3总结了对基于大模型的软工研究中实证性探索,如评估基准和实证研究;RQ4讨论了将大模型在软件工程中进行优化和应用的工作。最后本文讨论了基于大模型的软件工程研究的现有挑战和展望前景。

研究问题

为了全面概述现有大模型及其在软件工程中的进展,本文探索以下研究问题(RQs):

1. RQ1(大模型): 大模型是如何设计来支持代码相关任务的?

  • RQ1.1: 目前发布了哪些代表性大模型?
  • RQ1.2: 目前使用了哪些预训练任务来训练大模型
  • RQ1.3: 目前大模型被应用到哪些下游代码任务中?
  • RQ1.4: 目前大模型是如何开源以支持开放科学社区的?

2. RQ2(软工): 大模型是如何被应用到软件工程研究中的?

3. RQ3(评估): 大模型的软件工程研究是如何进行实证评估的?

4. RQ4(应用): 如何加强和优化大模型在软件工程中的应用?

结果分析

本研究收集了185篇关于LLMs在软件工程领域的应用的相关论文。如Figure 1所示,从2019年至2023年论文数量稳步上升,特别是2022年以后增长显著。这反映了LLMs在自动化软件工程任务中的应用日益受到重视。如Table 1 所示,这些论文来自多个研究领域,尤其集中在SE和NLP。顶级会议(如ICSE、FSE、ASE和ICLR)发表的论文数量表明了该领域对高质量学术交流的重视。研究还观察到自ChatGPT模型发布以来,未经同行评审的研究数量有所增加,表明了该领域发展迅速且开放性增强。

RQ1: LLMs是如何设计来支持代码相关任务的?

RQ1整理了目前代表性的代码相关大模型,主要分为三个方面,RQ1.1模型架构,RQ1.2预训练任务和RQ1.3下游任务,如Figure 2所示。

RQ1.1归纳了已发布的LLMs,包括不同类型的模型架构,模型规模,是否开源和来源团队,详见Table 2。目前,主流的LLMs主要发展三个方向:由Google的T5代表的编码器-解码器模型,由Microsoft的BERT代表的仅编码器模型,以及由OpenAI的GPT代表的仅解码器模型。虽然不同的模型架构在各自领域有优异的表现,但要确定一个对所有任务都是最佳的LLM是非常有挑战性的。例如,仅编码器模型(如BERT)专注于表示输入文本,通常不用于序列生成任务;而仅解码器模型(如GPT)主要用于生成文本序列,无需独立的编码步骤。

RQ1.2分析了用于训练LLMs的预训练任务,探讨了不同类型的预训练方法,详见Table 3。本文总结了文献中用于训练代码LLMs的代表性预训练任务。这些任务分为四大类:代码序列建模与预测、双向理解与生成、代码结构与关系理解以及跨模态表示学习。这些任务包括因果语言建模(CLM)、掩蔽语言建模(MLM)、掩蔽跨度预测(MSP)、掩蔽标识符预测(MIP)、替换令牌检测(RTD)、修改后的掩蔽序列到序列(MASS)、跨度去噪(SD)、双模态双重生成(BDG)、方法名称生成(MNG)、标识符标注(IT)、边缘预测(EP)、节点对齐(NA)、代码-AST预测(CAP)、多模态对比学习(MCL)和跨模态生成(CMG)。

近期的预训练任务趋势显示从早期NLP派生的目标转变为更加关注代码的目标。最初,LLMs使用NLP任务中的语言建模目标进行预训练,随后的工作发展为具体考虑代码变量和结构特征,以及源代码和自然语言的跨模态学习。这一进展标志着LLMs不仅处理代码令牌,而且深入理解代码的语义和功能方面,缩小了源代码和自然语言之间的差距。

RQ1.3中,我们观察到LLMs在SE的下游任务中的直接应用可以分为四类,即代码到代码、代码到测试、测试到代码和代码到标签的输入输出类型,或者根据任务类型分为两类,即代码理解和代码生成。大部分现有的下游任务呈现出一些趋势:首先,这些任务只涉及代码片段或相应的自然语言注释。其次,这些任务通常使用精心设计的评估指标(例如,对于生成任务的BLEU指标和分类任务的准确性)来进行自动评估,以支持大规模的评估基准。第三,这些任务能有效减少开发者的编程工作量,并且可以作为插件集成到IDE中,辅助编程。最后,这些任务已经在软件工程和人工智能领域都受到了关注并进行了研究。LLMs在这些任务上显示出初步的有希望的结果,重要的是,它们在更广泛和更深入的软件工程任务范围内展现出了潜力。

在回答RQ1.4时,与传统深度学习研究相比,LLMs在软件工程中的高质量成果对于复制研究和未来研究尤为重要,具体统计详见Table 4。尽管已经有许多针对代码相关任务的LLMs被引入,但在遵循开放科学原则方面仍存在显著差距。一方面,训练LLMs需要大量的时间和昂贵的设备(例如GPU),这使得重现现有工作变得更加困难。另一方面,某些LLMs还需要复杂的环境设置(例如超参数和随机种子)以及高质量的数据集。因此,我们希望研究人员能够提供高质量的开源代码和详细的说明。

RQ2: LLMs在软件工程研究中是如何使用的?

RQ2总结了LLMs在SE研究的不同阶段中的应用,包括软件需求与设计、软件开发、软件测试和软件维护,详见Figure 15。在软件需求与设计阶段,LLMs有助于从软件源代码中的注释或文档自动生成软件系统的正式描述和要求,这个过程通常涉及需要人工和领域知识的结合。在后续软件开发,测试和维护阶段,LLMs用于各种代码相关任务,如代码生成、代码搜索、代码翻译、代码摘要、代码补全和程序修复等。

总的来说,大模型已经在软件工程领域的各个阶段得到了应用,成功处理了多达43个不同的任务。尤其在一些代码理解和生成相关的任务上,研究人员对大模型与这些任务的结合进行了深入的研究,包括缺陷定位(Table 5)模糊测试(Table 6),缺陷修复(Table 10),漏洞修复(Table 12)和补丁验证(Table 13)

RQ3: LLMs在软件工程研究中是如何进行实证评估的?

测试基准测试。LLMs在SE中的使用与传统技术不同,它包括三个阶段的流程:首先是在超大规模数据集上进行无监督学习的预训练;其次使用标注数据集进行监督微调学习;最后是在少量数据集上的评估过程。由于社区的大量研究努力,已经存在多个基准来评估LLMs在支持各种代码相关任务中的效用。一个典型的趋势是构建人工编写数据集或者大模型训练时间点后的数据集来解决数据泄露问题,如HumanEval和EvalGPTFix;另一个趋势是应用多任务数据集,如CodeXGLUE和CrossCodeBench。

实证研究。研究者们进行了大量的实证研究来从不同方面探索LLMs的实际性能。一个常见的实证方法是为特定任务设计各种设置来深入调查LLMs的性能。另一个典型的方法是探索LLMs在多个任务上的性能,如Table 14 所示。

RQ4: 如何优化大模型在软件工程中的应用?

RQ4探讨了如何优化LLMs在SE中的应用,具体分为三个方面。

1. 安全攻击:LLMs可能受到攻击,生成易受攻击的代码片段或在不同的攻击策略下返回错误的分类,例如对抗性攻击、后门攻击和模仿攻击。这类研究探索了如何提高LLMs的健壮性,以抵御可能的安全攻击,确保模型在面对不同挑战时的稳定性,如Table 15所示。

1. 高效训练:考虑到LLMs庞大的参数规模,设计适应SE任务的微调策略至关重要,例如持续学习和参数微调。这类研究探索了探讨了如何提升LLMs的训练效率,以便在实际软件工程任务中快速有效地部署和使用,如Table16所示。

2. 部署应用:当LLMs训练良好后,将这些LLMs部署在开发流程中需要进一步考虑推理。这类研究讨论了如何改善LLMs的部署易用性,使其更易于在软件开发过程中集成和使用。