e4exp / paper_manager_abstract

0 stars 0 forks source link

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

Open e4exp opened 3 years ago

e4exp commented 3 years ago

BERT や GPT のような自然言語(NL)の事前学習モデルは、最近、プログラミング言語(PL)への移行が良好であることが示されており、広範なコード関連タスクに大きく貢献しています。 しかし、現在のほとんどの手法は、生成(理解)タスクには最適ではないエンコーダのみ(またはデコーダのみ)の事前学習に依存しているか、トークンの種類などのPLの特殊性を無視してNLと同じ方法でコードスニペットを処理しています。 CodeT5は、開発者に割り当てられた識別子から得られるコードセマンティクスをより有効に活用するために、事前に学習されたエンコーダとデコーダのトランスフォーマーを統合したモデルです。 このモデルは、コードの理解と生成の両方のタスクをシームレスにサポートする統一フレームワークを採用し、マルチタスク学習を可能にしています。 また、識別子を意識した新しい事前学習タスクを提案し、どのコードトークンが識別子であるかを識別し、マスクされた場合にそれらを回復することを可能にしています。 さらに、ユーザが書いたコードのコメントを利用して、NL-PLアライメントを改善するための双対生成タスクを提案する。 総合的な実験の結果、CodeT5は、コードの欠陥検出やクローン検出などの理解タスクや、PL-NL、NL-PL、PL-PLを含む様々な方向の生成タスクにおいて、先行する手法を大幅に上回ることがわかった。 さらに、このモデルはコードの意味的情報をよりよく捉えることができることが明らかになりました。 当社のコードと学習済みモデルは、https: //github.com/salesforce/CodeT5 で公開しています。

https://github.com/salesforce/CodeT5

e4exp commented 3 years ago

image

1 はじめに

BERT(Devlin et al., 2019)、GPT(Radford et al., 2019)、T5(Raffel et al., 2020)などの事前学習済みの言語モデルは、広範囲の自然言語処理(NLP)タスクのパフォーマンスを大幅に向上させてきました。 これらの研究では、大規模なラベルなしデータを用いた自己教師付きトレーニングによって汎用的な言語表現を導き出すことを目的とした「pre-train→fine-tune」パラダイムが採用されており、このパラダイムは、特にデータのアノテーションが限られているような下流の複数のタスクに利益をもたらすことができます。 これらの成功に触発されて、これらの事前学習法をプログラミング言語(PL)に適用しようとする多くの試みが最近行われており(Svyatkovskiy et al.2020; Kanade et al.2020; Feng et al.2020)、コード関連のタスクで有望な結果を示している。

しかし、成功しているにもかかわらず、これらのモデルのほとんどは、BERT (Svyatkovskiy et al., 2020; Feng et al., 2020) のようなエンコーダのみのモデル、またはGPT (Kanade et al., 2020) のようなデコーダのみのモデルのいずれかに依存しており、生成および理解のタスクにはそれぞれ最適ではありません。 例えば、CodeBERT(Feng et al., 2020)は、コード要約タスクに適用する場合、追加のデコーダを必要とし、このデコーダは事前訓練の恩恵を受けることができない。 また、ほとんどの既存の手法は、ソースコードをNLのようなトークンの並びとみなして、従来のNLP事前学習技術を単純に採用しています。 これは、コードの意味を完全に理解するために不可欠な、コードの豊富な構造情報をほとんど無視しています。 本研究では、コード内のトークンタイプ情報を考慮した、事前学習済みのエンコーダ・デコーダモデルであるCodeT5を発表します。 我々のCodeT5は、Denoising sequence-to-sequence (Seq2Seq)の事前学習を採用したT5アーキテクチャ(Raffel et al., 2020)をベースとしており、自然言語の理解と生成の両方のタスクに恩恵をもたらすことが示されている。 さらに、コード内の開発者が割り当てた識別子を活用することを提案しています。 プログラムを作成する際、開発者はコードをより理解しやすくするために情報量の多い識別子を使用する傾向があります。 そのため、これらの識別子は一般的にリッチなコードセマンティクスを保持しています。 このようなコード固有の知識を融合するために、我々は、どのトークンが識別子であるかを区別し、それらがマスクされたときにそれらを回復するようにモデルを訓練する、新しい識別子認識目的を提案する。

さらに、より良いNL-PLアライメントを学習するために、コードとそれに付随するコメントを活用することを提案する。 開発者は、ソフトウェアのメンテナンスを容易にするために、プログラムのドキュメントを提供することが多く(de Souza et al., 2005)、そのため、このようなPL-NLペアはほとんどのソースコードで広く利用可能である。 具体的には、NL→PLの生成とPL→NLの生成を2つのタスクとみなし、同時にモデルを最適化する。 我々は、6つのPLに関するユニモーダル(PLのみ)とバイモーダル(PL-NL)の両方のデータからなるCodeSearchNetデータ(Husain et al. それに加えて、C/C#の追加データをオープンソースのGithubリポジトリから収集しています。 CodeXGLUEベンチマーク(Lu et al., 2021)のほとんどのタスクでCodeT5を微調整しました。 コードの欠陥検出とクローン検出の2つの理解タスクと、コードの要約、生成、翻訳、洗練などの生成タスクを含みます。 また、図1に示すように、タスク制御コードをソースプロンプトとして、一度に複数のタスクでCodeT5を微調整するマルチタスク学習を模索しています。 要約すると、以下のような貢献をしています。

image

e4exp commented 3 years ago

3 CodeT5

当社のCodeT5は、T5と同じアーキテクチャのエンコーダ・デコーダフレームワークをベースにしています(Raffel et al., 2020)。 CodeT5は、ラベルのないソースコードを用いた事前学習により、プログラミング言語(PL)と自然言語(NL)の汎用的な表現を導出することを目的としている。 図2に示すように、我々はT5のSeq2Seqのノイズ除去を拡張し、識別子のタグ付けと予測の2つのタスクを提案することで、開発者によって割り当てられた識別子であるPLからのトークンタイプ情報をモデルがよりよく活用できるようにする。 さらに、NL-PL間のアライメントを改善するために、NL-PL間の双方向の変換を行うための二峰性のデュアル学習目的を提案します。 以下では、CodeT5がPLとNLの入力をどのように符号化するか(§3.1)と、我々が提案する識別子を考慮した事前学習タスク(§3.2)を紹介し、続いてタスク固有の伝達学習とマルチタスク学習による微調整(§3.3)を行う。

3.1 NLとPLのエンコード

事前学習の段階で、我々のモデルは、コードスニペットに付随するNL記述があるかないかに応じて、PLのみ、またはNL-PLのいずれかを入力として受け取る。 NL-PLの二峰性入力については、それらをデリミタートークン[SEP]でシーケンスに連結し、入力シーケンス全体をx = ([CLS], w1, ..., wn, [SEP], c1, ..., cm, [SEP])の形式で表現する。 ここで、nとmはそれぞれNL単語トークンとPLコードトークンの数を示す。 PLのみの単峰性入力の場合、NL単語列は空となる。

コード固有の特徴をより多く捉えるために、我々はコードのトークンタイプ情報を活用することを提案する。 ここでは、最もPLにとらわれない特徴の1つであり、豊富なコードセマンティクスを保持している識別子のタイプ(関数名や変数など)に注目します。 具体的には、PLセグメントを抽象構文木(AST)に変換し、各コードトークンのノードタイプを抽出します。 最後に、PLセグメントのバイナリラベルy∈{0, 1} mのシーケンスを構築し、各yi∈{0, 1}はコードトークンciが識別子であるかどうかを表します。

3.2 事前学習タスク

CodeT5がPLのみ、またはNL-PLの2モーダルデータから有用なパターンを学習するために提案する事前学習タスクを紹介します。

識別子を考慮したデノイジングの事前学習。

Denoising Sequence-to-Sequence (Seq2Seq)の事前トレーニングは、幅広いNLPタスクにおいて非常に効果的であることが示されている(Song et al., 2019; Raffel et al., 2020; Lewis et al., 2020)。 このノイズ除去の目的は、典型的には、まずソースシーケンスをいくつかのノイズ関数で破損し、その後、デコーダが元のテキストを回復することを要求する。 本研究では、T5 (Raffel et al., 2020)に類似したスパンマスキング目的を利用する。 この目的は、任意の長さのスパンをランダムにマスクし、デコーダでこれらのマスクされたスパンといくつかのセンチネルトークンを組み合わせて予測する。 このタスクを、図2(a)に示すように、Masked Span Prediction (MSP)と呼びます。 具体的には、T5と同じ15%の破損率を採用し、1から5トークンのスパンを一様にサンプリングすることで、平均スパン長を3にします。 さらに、サブワードのトークン化の前にスパンをサンプリングすることで、単語全体のマスキングを採用しています。 これは、部分的なサブトークンのマスキングを避けることを目的としており、有用であることが示されています(Sun et al. 注目すべきは、ロバストな多言語表現を学習するために、様々なPLのための共有モデルを事前に学習することです。 我々は、マスクされたスパンの予測損失を次のように記述する。

image

ここで、θはモデルのパラメータ、x ▷maskはマスクされた入力、x maskはデコーダから予測されるマスクされたシーケンスであり、kはx maskのトークン数を表し、x mask <tはこれまでに生成されたスパン シーケンスである。 より多くのコード固有の構造情報(ASTにおける識別子のノードタイプ)をモデルに融合させるために、2つの追加タスクを提案する。 識別子タグ付け(Identifier Tagging: IT)とマスクド識別子予測(Masked Identifier Prediction: MIP)の2つのタスクを提案し、ノイズ除去の事前学習を補完する。.

識別子タグ付け(IT) このタスクは、コードトークンが識別子であるかどうかをモデルに通知することを目的としており、開発者支援ツールのシンタックスハイライトと同様の精神を持っています。図2(b)に示すように、CodeT5エンコーダにおけるPLセグメントの最終的な隠れた状態を、確率p = (p1, ..., pm)のシーケンスにマッピングし、シーケンスラベリングのためのバイナリクロスエントロピー損失を計算します。

image

ここで、θeはエンコーダのパラメータである。 なお、タスクをシーケンスラベリング問題とすることで、モデルはコードのシンタックスとデータフロー構造を捉えることが期待されます。

Masked Identifier Prediction (MIP)

MSPのランダムスパンマスキングとは異なり、PLセグメント内の全ての識別子をマスクし、ある特定の識別子の全ての出現に対してユニークなセンチネルトークンを採用します。 ソフトウェア工学の分野では、識別子の名前を変更してもコードのセマンティクスに影響を与えないことを難読化(obfuscation)と呼びます。 Rozièreら(2021)にヒントを得て、図2(c)に示すように、センチネル・トークンを持つ固有の識別子をターゲット・シーケンスIに配列します。 そして、それを自動回帰的に予測します。

image

ここで、x Đ はマスクされた入力です。 難読化は、難読化されたコードの意味を理解し、同じ識別子の出現箇所を結びつける必要があり、より困難なタスクです。 この3つの損失を同じ確率で交互に最適化することで、識別子を考慮した難読化の事前学習を提案しています。

バイモーダル・デュアル・ジェネレーション(Bimodal Dual Generation)

事前学習の段階では、デコーダはマスクされたスパンと識別子のみを見ています。 これは、デコーダが流暢なNLテキストや構文的に正しいコードスニペットを生成する必要がある下流のタスクとは異なります。 そこで、図2(d)に示すように、NL-PL双方向データを活用して、双方向変換のモデルを学習することを提案しました。 具体的には、NL→PL生成とPL→NL生成を2つのタスクとみなし、それらに対して同時にモデルを最適化する。 各NLPL二峰性データポイントに対して、逆方向の2つの学習インスタンスを構築し、言語IDを追加する(例えば、Java PLと英語のNLに対して、それぞれ)。 この操作は、T5のスパンマスキングの特殊なケースとも言え、バイモーダル入力から完全なNLまたはPLセグメントをマスクすることができる。 このタスクは、NLとPLの対応関係のアライメントを改善することを目的としています。

3.3 CodeT5の微調整

大規模なラベルなしデータでの事前学習の後、CodeT5をタスク固有の伝達学習またはマルチタスク学習のいずれかによって下流のタスクに適応させる。

タスク固有の伝達学習。 生成タスクと理解タスク

コードに関連するタスクは、生成タスクと理解タスクに分類されます。 前者については、我々のCodeT5はそのSeq2Seqフレームワークと自然に適合させることができる。 理解タスクについては、ラベルをユニグラムのターゲットシーケンスとして生成する方法(Raffel et al., 2020)と、Lewis et al. (2020)に従って最後のデコーダの隠れた状態に基づいてクラスラベルの語彙からラベルを予測する方法の2つを検討する。

マルチタスク学習。

共有モデルを同時に複数のタスクで学習することで、マルチタスク学習の設定も検討しています。 マルチタスク学習は、モデルの重みのほとんどを多くのタスクに再利用することで計算コストを削減することができ、NLの事前学習においてモデルの汎化能力を向上させることが示されている(Liu et al., 2019a)。 我々はRaffel et al. (2020)に従い、タスク固有のネットワークを追加することなく、全てのタスクに対して同じ統一モデルを採用するが、タスクごとに異なる最適なチェックポイントを選択できるようにする。 どのタスクを扱っているかをモデルに通知するために、図1に示すように、タスク制御コードの統一フォーマットを設計し、ソース入力の前に付加する。 例えば、JavaからCSharpへのコード変換タスクでは、ソースプロンプトとして「Translate Java to CSharp: 」を採用しています。 タスクによってデータセットのサイズが異なるため、Conneau and Lample (2019)に従い、バランスの取れたサンプリング戦略を採用します。 N個のデータセット(またはタスク)に対して、確率{qi}で N i=1の場合、以下の多項分布を定義し、そこからサンプリングします。

image

ここで、niはi番目のタスクの例数、αは0.7に設定されています。このバランスのとれたサンプリングは、高リソースのタスクへの偏りを緩和することを目的としている。