《CodeBERT: A Pre-Trained Model for Programming and Natural Languages》论文笔记
这篇论文介绍了CodeBERT模型及其预训练方法与应用。CodeBERT是一个双模态的大型预训练模型,在自然语言(NL)和编程语言(PL)之间结合了上下文表示学习能力。其架构基于RoBERTa-base,并在混合目标函数下进行联合优化:Masked Language Modeling(MLM)任务用于填充丢失的词或符号;Replaced Token Detection(RTD)任务通过生成器学习替换token以增强对齐能力。实验表明,在代码搜索与文档生成等下游任务上表现优异,并推广至其他编程语言如C#。该研究为多模态预训练模型的应用提供了新方向,并提出了未来的研究方向如RTD损失函数改进及AST融入等问题。
论文来源 :EMNLP-2020
论文链接 :https://arxiv.org/abs/2002.08155
可从Hugging Face官网获取的预训练模型在官方网站上公开,并且对应的GitHub仓库中也提供了论文的公开链接。
🚀主要内容:
传统的BERT属于基于自然语言处理的预训练模型,在这一领域具有重要地位。相比之下,CodeBERT则是一种新型双模态预训练模型,并基于transformer架构设计而成。它主要应用于自然语言处理及6种编程语言领域。其预训练过程采用混合损失函数进行优化,并结合执行MLM任务以及RTD任务(replaced token detection)。具体而言,在RTD机制中,通过从生成器中采样合理的替代token来部分替换输入token以破坏输入结构;接着培训一个判别器来判断损坏后的输入中每一个token是否被生成器提供的样本所替代。
训练数据包含双模态形式的数据(如自然语言与编程语言代码对)以及单一领域代码数据(如仅代码形式的数据)。单一领域数据有助于从抽象层面提取更有价值的token表示信息。
类似于BERT模型,在CoderBERT的基础上提取代码嵌入表示并应用于多种下游应用(包括代码错误检测、复制 paste检测以及文档生成等)。研究者通过微调预训练好的CoderBERT模型完成了两项实验(自然语言编码搜索与代码文档生成),均实现了最佳水平(State-of-the-Art performance)。进一步探索了CoderBERT的学习特性,在保持pre-trained model参数不变的前提下,在NL-PL领域进行了评估测试,并发现其性能超越了传统的RoBERTa模型(一种仅基于自然语言处理领域的预训练方法)
🚀主要贡献:
- CodeBERT是首个专门针对多种编程语言的大型NL-PL预训练模型。
- 实验数据验证了CodeBERT在代码搜索(Code-Search)和代码转文本生成(Code-to-Text Generation)任务中表现出色。
- 我们开发了一个新的数据集,旨在评估基于代码的预训练模型的能力。
🚀背景介绍:
大型预训练模型如BERT、GPT、XLNet等在自然语言处理任务中发挥了巨大的推动作用。这些模型都是通过从无监督数据中进行自监督学习来获得高效的上下文表示(例如 masked language modeling任务)。
此外,在这些模型的成功带动下,多模态预训练模型也得到了快速发展。例如ViLBert便是其中一员,在其预训练过程中采用了language-image pairs这种双模态数据进行自监督学习。多模态模型通过学习不同模态输入之间的隐式对齐关系来提升性能。
在同一时期发表的相关研究论文中,《Learning and Evaluating Contextual Embedding of Source Code》一文中作者同样采用了BERT进行预训练工作,并延续了MLM(Masked Language Modeling)和NSP(Next Sentence Prediction)等经典的预训练任务。然而该论文的数据集仅局限于Python编程语言的语料库。
值得注意的是这篇论文与前人工作的不同之处在于:
- 采用了双模态数据与单模态数据相结合的方式
- 数据集包含了六种不同的编程语言
- 在预训练过程中增加了RTD(Random Token Dropping)任务这一创新性步骤
🚀CodeBERT
⭐模型结构
CodeBERT 的结构完全和 RoBERTa-base 一样,模型的全部参数量大小为125M。
⭐输入/输出表示
输入采用[CLS]、w1、w2,…wn,[SEP],c1,c2,…cm,[EOS]的形式进行分割。
其中前一部分属于NL(采用WordPiece方式进行分割),后一部分属于PL(即Pointwise Learning)。
值得注意的是,在此过程中,
[CLS]
与BERT中的处理一致,
并将其最后一层的隐藏状态作为序列聚合表示来用于分类或排序任务。
- 每个token所对应的上下文向量表示。
- [CLS]位置上对整个序列进行聚合的表示。
⭐预训练数据
基于Husain等人的2019年论文中获取的大规模数据集,在github平台上进行了系统性的预处理工作(包括但不限于文本清洗、特征提取等具体操作),这些数据经github平台获取后进行了系统性的预处理。该研究仅采用了该数据集中所包含的训练样本作为模型训练的数据源,在自然语言编码任务中进行评估为目标的研究方案下,并未包含该数据集中所属的测试样本以及验证集合用于模型性能评估阶段。

⭐预训练
预训练涵盖两个关键任务:MLML与RTD;在整个预训练过程中,其总目标是这两个核心任务损失函数的总和。具体而言,请参考论文中的详细说明。
预训练涵盖两个关键任务:MLML与RTD;
在整个预训练过程中,
其总目标是这两个核心任务损失函数的总和。
具体而言,
请参考论文中的详细说明。
1. Masked Language Modeling (MLM)
在MLM预训练过程中所使用的数据集具有双模态特性,在每个样本中都会对语言部分或视觉部分进行随机标记处理。具体而言,在生成mask标记时有15%的概率作用于语言部分而非视觉部分。
2.RTD(Replaced Token Detection)
在预训练过程中,RTD采用双模态与单模态数据的结合。在RTD任务中分别为NL(自然语言)和PL(编程语言)生成器创建,并用于合理地将mask掉位置上的token替换为相应的替代token。随后序列处理流程如下:使用CodeBERT作为区分器来判断被mask替换后的token是否为原mask位置的正确替换(即一个二分类问题)。

该生成器具有多种实现方案。该论文针对NL与PL分别采用了基于双向上下文的n-gram语言模型,并通过从相应的单模态数据进行训练与学习完成了模型构建工作。其中PL指的是上表所示的单模态数据集,而NL则对应于双模态数据分析中的代码文档部分。
⭐Fine-Tuning CodeBERT:
可以根据不同的设置来应用该模型进行下游任务。具体来说,在自然代码搜索任务中,在自然代码搜索任务中
🚀实验部分
主要通过与各模型在两个下游任务上的性能比较达到了SOTA。此外,在探究CodeBERT学习效果的过程中,我们采用了固定预训练模型参数的方法,在NL-PL任务上取得了显著成绩(该方法基于纯自然语言预训练)。同时将覆盖包括C#在内的额外六种编程语言,并对这些情况进行对比测试。
🚀未来方向
可选择性地将生成器扩展至双模态数据领域,并采用更为复杂的网络架构以优化RTD性能。
