CodeT5: Identifier-aware Unified Pre-trained Encoder-Decoder Models for Code Understanding and Generation笔记

Motivation

  • 以前的模型大多都只依赖于encoder或关注于decoder,分别对于生成和理解任务是次优的;
  • 此外,大多数现有的方法把code看作是像NL这样的标记序列,只是在其上采用传统的NLP预训练技术,这在很大程度上忽略了代码中丰富的结构性信息,而这对于完全理解代码的语义至关重要

Introduction

在这项工作中,我们提出了CodeT5,一个预先训练的编码器-解码器模型,它考虑了代码中的令牌类型信息。

模型框架基于T5,此外,我们提出在代码中利用developer设计的标识符。为了融合这种特定于代码的知识,我们提出了一种新的标识符感知目标函数,它训练模型来区分哪些令牌是标识符,并在它们被屏蔽时恢复它们。

另外,我们还利用代码中的注释来让模型学习代码和文本的对齐属性。

我们将NL-PL和PL-NL视为dual task,同时优化这两个任务。

Contribution

  • 我们提出了第一个统一的编码解码器模型CodeT5,以支持编码相关的理解和生成任务,也允许多任务学习
  • 提出了一种新的基于标识符感知的预训练目标,它考虑了代码中的关键令牌类型信息(标识符)。此外,我们建议利用源代码中自然可用的NL-PL对来学习更好的跨模态对齐。
  • 大量的实验表明,CodeT5在CodeXGLUE中的14个子任务上产生了最先进的结果。进一步的分析表明,我们的CodeT5可以更好地捕获代码语义,提出的识别符感知预训练和双模态dual generation主要有利于NL-PL任务。

CodeT5

Encoding NL and PL

两个序列通过\(\verb|[SEP]|\)token拼接起来:\(x = ([\verb|CLS|], w_1, \dots, w_n, \verb|[SEP]|, c_1, \dots, c_m, \verb|[SEP]|)\)

为了捕捉代码特征,我们提取每个token的type(是否是identifier),用序列\(y \in {0, 1}^m\)来表示\(c_i\)是否是identifier。

预训练任务

Identifier-aware Denoising Pre-training

  • Masked Span Prediction (MSP)
    • 通过某个噪声函数给序列加噪音,然后让解码器恢复原始文本
    • \[ \mathcal{L}_{MSP}(\theta) = \sum_{t=1}^k - \log P_{\theta} (x_t^{mask} | x ^{\backslash mask}, x^{mask}_{<t}) \]

  • Identifier Tagging (IT)
    • 它的目的是通知模型,并知道这个代码标记是否是一个标识符,这在一些开发辅助工具中具有类似的语法突出显示精神。
    • \[\]

      \[\]

    • 我们屏蔽了PL段中的所有标识符,并对一个特定标识符的所有出现使用一个唯一的哨兵令牌。在软件工程领域中,这被称为混淆,因为更改标识符名称不会影响代码的语义。
    • \[\]

      \[ \]

Bimodal Dual Generation

在训练前阶段,解码器只看到离散的mask span和identifiers,这和下游任务有gap。为了减小这种gap,我们同时优化\(\text{PL} \rightarrow \text{NL}\)\(\text{NL} \rightarrow \text{PL}\)。对于每一个NL-PL的实例对,我们反转顺序,并且添加语言id。这种操作可以看作span mask的一种特殊情况。

fine tune

  • Task-specific Transfer Learning: Generation vs. Understanding Tasks.
    • 与代码相关的任务可以分为生成任务和理解任务。对于前者,我们的CodeT5可以自然地适应其Seq2Seq框架。对于理解任务,我们研究了两种方法,要么将标签生成为单组目标序列,要么根据最后一个解码器隐藏状态从类标签的词汇表中预测它。
  • Multi-task Learning
    • 采样频率
    • \[\]

    \[- $\alpha$设置为0.7 \]

posted @ 2022-04-25 15:34  TABball  阅读(762)  评论(0编辑  收藏  举报