导语
- 会议:EMNLP 2020 Findings
- 链接:arxiv.org/abs/2002.08…
1 前言
随着NLP大型预训练语言模型的广泛应用,越来越多的多模态PLM出现,例如ViLBERT、VideoBERT等。本文提出了CodeBERT,一个针对编程语言PL和自然语言NL的双模态预训练模型。CodeBERT捕获了自然语言和编程语言之间的语义联系,并生成通用表示,可以广泛支持NL-PL理解任务(例如自然语言代码搜索)和生成任务(例如代码文档生成)。CodeBERT在预训练时,除了利用了NL-PL的并行双模态数据外,也充分利用了大量PL、NL的单模态数据。整体来说,本文的主要贡献如下:
- CodeBERT是第一个用于多种编程语言的大型NL-PL预训练模型。
- 实验结果表明,CodeBERT在代码搜索和代码到文本生成任务中都是有效的。
- 我们进一步创建了一个数据集,这是第一个调查基于代码的预训练模型的探测能力的数据集。
2 背景
略
3 CodeBERT
3.1 模型架构
模型整理框架与RoBERTa一致。
3.2 输入、输出表示
输入由NL和对应的PL拼接而成,中间使用[SEP]分隔开。
3.3 预训练数据
使用Husain et al.等人发布的一个数据集进行预训练,其中包括2.1M的双模态数据和6.4M的单模态数据。数据集的统计信息如下:
其中的一个数据示例如下图所示:
3.4 预训练CodeBERT
CodeBERT的预训练目标有两个:
- Objective #1: Masked Language Modeling (MLM)
即传统的MLM任务,这里只有一种[MASK],不区分code的[MASK]和自然语句的[MASK]。
- Objective #2: Replaced Token Detection (RTD)
这个借鉴了ELETRA模型的训练思路,即有一个Generator和Discriminator来共同训练,其训练流程如下图所示:NL和代码生成器都是语言模型,它们基于周围的上下文为mask位置生成合理的token。NL-code Discriminator是目标的预训练模型,它通过检测从NL和PL生成器采样的合理替代token来训练。NL-Code鉴别器用于在微调步骤中生成通用表示。在微调步骤中,只使用Discriminator。
3.5 Fine-tuning CodeBERT
在下游NL-PL任务中使用CodeBERT有不同的设置。例如,在自然语言代码搜索中,我们以与预训练阶段相同的方式提供输入,并使用[CLS]的表示来衡量代码与自然语言查询之间的语义相关性,而在代码到文本生成中,我们使用编码器-解码器框架,并使用CodeBERT初始化生成模型的编码器。细节在实验部分给出。
4 实验
4.1 Natural Language Code Search
给定一种自然语言作为输入,代码搜索的目标是从一组代码中找到语义上最相关的代码。本文在CodeSearchNet语料上进行实验。本文遵循官方评估度量来计算在固定的999个干扰码集合上的每对测试数据(c, w)的Mean Reciprocal Rank(MRR)。我们进一步计算所有语言的宏观平均MRR作为整体评估指标。
实验结果如下表所示:
其中,init=S表示train from scratch,init=R表示从RoBERTa初始化。
4.2 NL-PL Probing
本小节中,将进一步研究在不修改参数的情况下,在CodeBERT中学习什么类型的知识。
本文定义了NL-PL探测问题,并创建了数据集。给定一个NL-PL对(c, w), NL-PL探测的目标是测试模型在干扰物中正确预测/恢复感兴趣的掩码令牌(cic_ici或wjw_jwj)的能力。有两种主要类型的干扰因素:一种是用于掩蔽语言建模目标的整个目标词汇,另一种是基于专家对测试能力的理解筛选或策划的候选词汇。我们遵循第二个方向,将NL-PL探测制定为一个选择题回答任务,其中问题是完形填空式的,其中某个token被[MASK]取代,干扰者候选答案将根据我们的专业知识进行策划。
具体来说,我们分别在NL侧和PL侧进行评估。本文自动从CodeSearchNet的验证集和测试集中的NL-PL对中收集数据。为了在NL方面进行评估,选择关键字(max, min, less, greater)之一的NL-PL对,任务是要求PLM选择正确的一个。也就是说,这个设置中的输入包括完整的代码和屏蔽的NL文档。目标是从四个候选人中选出正确答案。对于PL方面,我们选择包含关键字max和min的代码,并将任务制定为一个两选答案选择问题。在这里,输入包括完整的NL文档和屏蔽的PL代码,目标是从两个候选项中选择正确答案。由于代码补全是一个重要的场景,我们想测试模型仅仅基于前面的PL上下文预测正确token的能力。因此,我们为PL端添加了一个额外的设置,其中输入包括完整的NL文档和前面的PL代码。
表3的前两行给出了数据统计。
4.3 Code Documentation Generation
本节涉及 code-to-NL 生成任务,报告了在 CodeSearchNet 语料库上六种编程语言的文档生成任务结果。
下表 5 展示了不同模型的代码-文档生成任务结果:
4.4 Generalization to Programming Languages NOT in Pre-training
这里作者测试一个不在预训练语料中出现的编程语言 C# 的数据集CodeNN来测试性能表现,得到Code-to-NL任务的性能表现如下:
5 总结
本文提出了CodeBERT,据我们所知,这是第一个用于自然语言和编程语言的大型双模态PLM。我们在双模态和单模态数据上训练CodeBERT,并展示了对CodeBERT进行微调在下游任务(包括自然语言代码搜索和代码到文档生成)上实现了最先进的性能。为了进一步研究预训练模型中包含的知识,我们制定了NL-PL探测任务,并创建了用于探测的数据集。我们将探测任务视为完形式的答案选择问题,并为NL和PL部分安排干扰。结果表明,当模型参数固定时,CodeBERT的性能优于RoBERTa和仅使用代码的连续训练模型。
这一领域有许多潜在的研究方向。首先,可以使用双模态或更复杂的神经结构来学习更好的生成器,以改进替换的token检测目标。其次,CodeBERT的损失函数主要针对NL-PL理解任务。尽管CodeBERT在代码到文档的生成方面获得了很高的BLEU分数,但CodeBERT本身可以通过与生成相关的学习目标进一步改进。如何成功地将AST融入到预训练步骤中也是一个很有吸引力的方向。第三,我们计划将CodeBERT应用于更多与NL-PL相关的任务,并将其扩展到更多的编程语言。灵活而强大的领域/语言适应方法是很好的泛化所必需的。
本文转载自: 掘金