软件工程(SE)是软件应用的系统化设计、开发和维护,构成了我们现代主世界的数字基础设施。最近,SE社区迅速增加了许多使用大型语言模型(LLMs)来自动化广泛SE任务的技术。然而,LLMs在SE中的应用、效果和可能的限制的现有信息仍未得到充分研究。在这篇论文中,我们提供了一个系统的综述,总结了基于LLM的SE社区当前的最先进研究。我们总结了三种模型架构中的30个代表性LLMs源代码,四个类别中的15个预训练目标,以及五个类别中的16个下游任务。接着,我们详细总结了LLMs常用的近期SE研究,包括SE工作流程中四个关键阶段的43个特定代码相关任务的155项研究。此外,我们总结了在SE中实证评估LLMs的现有尝试,如基准测试、实证研究和SE教育的探索。我们还讨论了LLMs在SE中优化和应用的几个关键方面,如安全攻击、模型微调和模型压缩。最后,我们强调了将LLMs应用于未来SE研究的几个挑战和潜在机会,如探索领域LLMs和构建干净的评估数据集。总体而言,我们的工作可以帮助研究人员全面了解现有基于LLM的SE研究的成就,并促进这些技术的实际应用。我们的工件公开可用,并将在活生生的存储库中持续更新:https://github.com/iSEngLab/AwesomeLLM4SE。
1 引言
软件工程(SE)是一项至关重要的追求,专注于系统化和可预测地设计、开发、测试和维护软件系统 [1]。随着软件日益成为各行各业(例如交通、医疗和教育)的基础设施,SE通过确保以系统化、可靠和高效的方式构建软件系统,在现代社会中扮演着关键角色 [2]。作为一个非常活跃的领域,SE已经在文献中被广泛研究,并且几十年来一直受到学术和工业界的关注 [3],[4]。最近,在SE领域最具变革性的进展之一是大型语言模型(LLMs)的出现。先进的LLMs(例如BERT [5],T5 [6] 和 GPT [7])在广泛的自然语言处理(NLP)任务中显著提高了性能,如机器翻译和文本分类。这些模型通常通过自监着学习在大规模无标签数据上预训练以获得通用语言表征,然后通过在有限标签数据上的监督微调转移到多个下游任务中。受LLMs在NLP中成功的启发,许多最近的尝试已经采用LLMs来提升众多代码相关任务(例如代码摘要和代码搜索),如CodeBERT [8] 和 CodeT5 [9]。LLMs在SE中的应用对该领域产生了深远的影响,改变了开发者自动处理代码相关任务的方式。例如,具有数十亿参数的最著名LLMs之一ChatGPT [10] 在多种任务中展示了卓越的性能,展示了LLMs改变SE行业的潜力。总的来说,SE社区已经看到了使用LLMs的广泛SE研究数量迅速增加,已经带来了实质性的好处,并进一步展示了后续研究中的有希望的未来。
然而,复杂的SE工作流程(例如软件开发、测试和维护)和大量特定的代码相关任务(例如漏洞检测、故障定位和程序修复)使得有兴趣的研究人员难以了解基于LLM的最新SE研究并对其进行改进。此外,不断涌现的具有不同架构、训练方法、来源和大量微调方法的先进LLMs带来了跟上和有效利用这些进展的挑战。例如,研究人员进行了各种研究,广泛调查LLMs在程序修复领域的有效性 [11],[11],[12]。这些研究涵盖了不同的研究方面(例如实证和技术研究 [13])、LLMs的类型(例如开源或闭源 [11])、模式架构(例如编码器-解码器或仅编码器 [12])、模型参数(例如CodeT5-60M 和 InCoder-6B [14])、错误类型(例如语义错误和安全漏洞 [15])和利用范式(例如微调 [16],少量样本 [17] 和零样本 [18])。在本文中,我们总结了现有工作,并在经过多年快速发展后对基于LLM的社区领域进行了回顾。社区研究人员可以充分了解现有基于LLM的SE技术的优势和局限性。我们讨论了LLMs如何集成到SE研究的典型工作流程中的特定任务。基于我们的分析,我们指出了当前的挑战,并建议了LLM基础SE研究未来可能的方向。总的来说,我们的工作提供了对当前基于LLM的SE社区进展的全面回顾,使研究人员能够获得这个蓬勃发展领域的概览,并朝着先进实践迈进。
总而言之,本文的主要贡献如下: • 综述方法论。我们对截至2023年11月的185项相关SE研究进行了详细分析,以了解出版趋势和场地分布。 • 代码的LLMs。我们根据不同方面(例如模型架构、预训练目标、下游任务和开放科学)总结了SE社区的30个代表性代码LLMs。 • 基于LLM的SE研究。我们探讨了利用最近LLMs的进展自动化SE研究的典型应用,涉及SE四个阶段的43个代码相关任务的155项相关研究,即软件需求和设计、软件开发、软件测试和软件维护。 • 实证评估。我们详细介绍了现有基准、实证研究和SE教育的探索,以更好地了解基于LLM的SE研究过程并促进未来研究。 •** SE优化**。我们讨论了LLMs在SE领域应用时的一些其他关键方面,例如安全攻击和模型调整。 • 展望和挑战。我们指出了开放研究挑战,并提供了将LLMs应用于未来SE研究的几个实际指南。
与现有综述的比较。Watson [19] 提出了SE和DL交叉领域研究的系统文献综述。最近,Zan等人 [20] 提出了一个综述,整理了27个用于源代码的LLMs。与现有综述主要覆盖DL&SE或代码的LLMs不同,我们的工作专注于LLMs在SE中的应用,特别是LLMs在软件设计、开发和维护阶段的集成,以及相应的挑战。此外,我们的综述总结了直到2023年11月的现有研究。论文组织。本文的其余部分安排如下。第2节详细阐述了进行综述所采用的四个研究问题和方法论。第3节总结了现有的源代码LLMs。第4节阐述了使用LLMs的现有SE研究。第5节总结了实证评估,第6节讨论了LLMs在SE中的优化。第7节强调了未来研究的挑战和有希望的机会。第8节得出结论。可用性。本研究的所有工件均可在以下公共存储库中获取。活生生的存储库不断更新有关LLMs、LLM4SE和相关研究的最新研究。https://github.com/iSEngLab/AwesomeLLM4SE**RQ1: LLMs是如何设计来支持代码相关任务的? **基于Transformer架构[23]的基础上,SE领域提出了许多具有创纪录参数的LLMs。在这一部分,我们在第3.1节总结了现有的代表性代码LLMs,第3.2节中的预训练任务,第3.3节中的微调任务,并在第3.4节讨论开放科学问题。详细的分类法在图2中展示,包括三个子RQs及其对应的分类。
RQ1.1: 哪些LLMs已经发布以支持SE?
总的来说,现有的LLMs主要沿着三个方向发展,即Google的T5所代表的编码器-解码器,Microsoft的BERT所代表的仅编码器,以及OpenAI的GPT所代表的仅解码器。虽然不同的模型架构在各自的领域表现出色,但要确定一个适合所有任务的最佳LLM是具有挑战性的。例如,仅编码器模型(如BERT)专注于表示输入文本,通常不用于序列生成任务,而仅解码器模型(如GPT)主要用于生成文本序列,无需单独的编码步骤。
**RQ1.2: LLMs如何用于预训练任务? **在本节中,我们总结了文献中用于训练代码LLMs的一些代表性预训练任务。表3将预训练任务分为四大类,包括第3.2.1节的代码序列建模和预测,第3.2.2节的双向理解和生成,第3.2.3节的代码结构和关系理解,以及第3.2.4节的跨模态表征学习。现在,我们列出并总结了这些预训练任务如下。 总体来看,针对代码LLMs的预训练任务的最新趋势反映出从早期NLP派生目标向更多代码意识目标的显著转变。最初,LLMs是使用来自NLP任务的语言建模目标进行预训练的,包括仅解码器LLMs的CLM(例如CodeGPT),仅编码器LLMs的MLM(例如CodeBERT),以及编码器-解码器LLMs的MSP(例如CodeT5)。随后的工作发展为特别考虑代码变量和结构特征,以及源代码和自然语言的跨模态学习。这一进展标志着LLMs的持续发展,不仅将代码作为一系列令牌进行处理,而且深入理解其语义和功能方面,弥合了源代码和自然语言之间的差距。
RQ1.3: LLMs如何用于下游任务? 一旦在大量语料库上训练了LLMs,评估LLMs在下游任务上的有效性和适用性就至关重要。微调是将预训练期间获得的知识转移到下游任务的主要方法,要求LLMs展现代码理解、推理和生成能力。下游任务可以根据任务类型(即代码理解和代码生成)或数据类型(即代码-代码、代码-文本、文本-代码和代码-标签)进行分类。我们根据一个维护良好的存储库2,总结了15个代表性的下游任务,这些任务在现有LLMs的原始论文中得到了评估,具体如下。
总体来看,作为LLMs的直接应用,这些下游任务可以根据输入-输出类型分为四类,即代码-代码、代码-测试、测试-代码和代码-标签,或者根据任务类型分为两类,即代码理解和代码生成。我们观察到大多数现有下游任务中的一些趋势,LLMs可以直接应用于这些任务。首先,这些任务只涉及代码片段或相应的自然语言注释。其次,这些任务通常使用精心设计的指标(例如生成任务的BLUE和分类任务的准确度)进行自动评估,从而支持大规模评估基准。第三,这些任务可以有效地减少开发人员的编程工作,并可以作为插件集成到现代IDE中以辅助编程。最后,这些任务已经引起了SE和人工智能领域的关注,并已在这两个领域进行了研究。LLMs在这些任务上已经显示出初步的有希望的结果,重要的是它们在更广泛和更深入的SE任务范围中的潜力,详见第4节。
**RQ2: LLMs如何用于软件工程研究? **
在本节中,我们总结了使用LLMs的现有SE研究,这些研究可以分为SE生命周期内的四个关键阶段,包括第4.1节的软件需求和设计,第4.2节的软件开发,第4.3节的软件测试,以及第4.4节的软件维护。每个SE阶段包含几个不同的代码相关任务,例如软件维护阶段的故障定位和程序修复。图15展示了本节的分类法,包括LLMs在四个子RQs和SE领域的43个代码相关任务中的应用,总结如下。总体来看,LLMs已在SE研究的各个阶段得到应用,解决了43个不同的任务。一方面,这些任务与之前的下游任务(在第3.3节中详细介绍)相一致,但它们被更全面地探索,例如程序修复。另一方面,研究人员将注意力转向了更多更复杂的SE任务。这些任务可能(1)包括LLMs无法完全处理的复杂过程,如模糊测试;(2)包括其他输入,如测试报告中的GUI测试;以及(3)SE的一些独特领域,如补丁正确性评估。研究人员需要投入更多的努力来解决这些更领域特定的问题,如设计特定的LLMs或将它们嵌入现有的研究工作流程。值得注意的是,软件测试和开发领域已经看到了LLMs的更广泛应用。这一趋势可能源于这些领域通常作为LLMs的基础下游任务,其中它们已显示出相当大的潜力。此外,这些任务可以通过现有LLMs的序列到序列代码生成形式自然地解决。然而,LLMs在软件需求方面的应用仍相对未被探索,表明这是该领域未来研究的潜在关注领域。
RQ3:如何在社会工程研究中对LLMS进行实证评估?总体而言,在基于LLM的SE不断扩展的领域内,社区也看到了越来越多的研究实证地强调不同方面现有研究的发展和细微差别。首先,数据集在塑造研究进步的轨迹中扮演着关键角色。一个典型趋势是构建人类编写的数据集来解决数据泄露问题,例如HumanEval和EvalGPTFix。另一个典型趋势是应用多任务,例如CodeXGLUE和CrossCodeBench。其次,研究人员构建了大量实证研究,从不同方面探索LLMs的实际性能。一种常见的实证方法是为特定任务设计各种设置,以深入调查LLMs的性能,在第4节中详细介绍。另一种典型方法涉及探索LLMs在多个任务中的性能,如T5Learning。第三,研究人员观察到LLMs对SE教育的革命性影响,并探索它们如何协助研究以补充编程课程。然而,考虑到存在各种任务,每个任务都可以引入各种特定的LLMs,社区迫切需要更多更深入的实证研究来阐明基于LLM的SE的格局。**RQ4:优化与应用**在快速发展的SE领域中,LLMs已经成为关键角色,为各种代码相关任务提供了前所未有的机会。然而,由于LLMs固有的特性(如创纪录的参数使其难以在实际场景中部署),LLMs在SE中的有效部署并非没有挑战。本节深入探讨了优化LLMs以用于SE的三个关键方面,重点关注增强其鲁棒性(第6.1节)、效率(第6.2节)和可用性(第6.3节)。总体而言,尽管大量研究努力已经投入到如何更有效地将LLMs适应自动化SE任务中,文献中也看到了一些讨论在适应过程中遇到的独特挑战的工作。首先,LLMs可能受到攻击,生成易受攻击的代码片段或使用不同的攻击策略返回错误的分类,如对抗性攻击、后门攻击和模仿攻击。其次,考虑到LLMs的巨大参数规模,设计调优策略以适应SE任务中的这类LLMs至关重要,如参数和持续的微调。第三,在LLMs得到良好训练后,将这类LLMs部署到开发工作流程中需要进一步考虑推理时间和资源消耗等因素。
结论
大型语言模型(LLMs)正在为软件工程(SE)领域带来重大变革,它们处理复杂代码相关任务的能力将从根本上重塑许多SE实践和方法。 在本文中,我们从LLM和SE的角度提供了现有LLM基础的SE研究的综合调查。我们总结了30个代表性的代码LLM,并讨论了它们独特的架构、预训练目标、下游任务和开放科学。我们展示了LLM已经应用于的广泛的SE任务,涉及到43个代码相关任务的155项相关研究,涵盖了四个关键的SE阶段。我们讨论了基准、实证研究以及LLM基础的SE社区中的SE教育探索。我们强调了SE研究的优化和应用的几个关键方面,包括安全攻击、模型调整和模型压缩。 最后,我们指出了一些挑战(例如数据泄漏问题)并提供了未来研究的可能方向。总的来说,我们的工作是一个有前途的未来研究路线图,对研究人员和从业者都有价值,可以帮助他们利用LLMs来改善现有的SE实践。