Facebook AI Researchは、教師なし(unsupervised)ディープラーニングを使用して、プログラミング言語のコードを別のプログラミング言語に変換するシステムであるTransCoderを発表した。TransCoderは280万以上のオープンソースプロジェクトを使用してトレーニングされており、ルールベースの手法を用いた既存のコード変換システムを能力的に凌駕する。
このシステムは、arXivで公開された論文上で発表された。TransCoderは、ディープラーニングを使用して自然言語のテキストを別の言語に変換する、他のニューラルマシントランスレーション(NMT)システムからヒントを得たもので、単一言語のソースデータのみを使用してトレーニングされている。モデルのパフォーマンスを比較するためにFacebookのチームは、システムのターゲットであるJava、Python、C++で記述された852の関数と、関連するユニットテストからなる評価セットを収集した。既存システムとの比較結果としてTransCoderは、このバリデーションセットにおいて、Java-Pythonトランスレータのj2pyに対して最大33パーセントと、既存の商用ソリューション以上のパフォーマンスを示した。開発作業の対象は上記の3言語のみに制限されているが、"ほとんどのプログラミング言語に対して拡張するのは容易"だ、とチームは主張している。
ソースコードをひとつの言語から別の言語に変換する自動ツールは、ソース・ツー・ソースコンパイラ、トランスコンパイラ、あるいはトランスパイラとも呼ばれており、1970年代から存在している。これらのツールの大部分は、標準的なコードコンパイラと同じように動作する。まずソースコードを抽象構文木(AST)に解析する。そのASTを別の言語のソースコードに変換するのだが、一般的にはここで書き直し(re-write)ルールが使用される。トランスパイラが有用なシナリオはいくつかある。例えばCoffeeScriptやTypeScriptなど一部の言語は、開発者寄りの言語からより広くサポートされる言語へと、トランスパイラを使って変換することを意図して設計されている。時代遅れや推奨されないソース言語で記述されたコードベース全体をトランスパイルすることが有用な場合もある — 例えば2to3トランスパイルツールは、Pythonのコードを、非推奨のバージョン2からバージョン3に移植するために使用される。一方で、トランスパイラは完璧には程遠いものである上、ひとつ作成するために大きな開発労力(場合によってはカスタマイズ)を必要とする。
TransCoderは自然言語処理(NLP)、特に教師なしNMTの進歩に立脚して開発されている。モデルにはTransformerベースのソース・ツー・シーケンスアーキテクチャを使用しており、アテンションベースのエンコーダとデコーダで構成されている。教師付きラーニングのためのデータセットを用意することが困難 — ソース言語とターゲット言語の両方で内容の等価なコードサンプルが多数必要になる — であるため、開発チームは、単一言語のデータセットによる教師なしラーニングを採用した上で、3つのストラテジを使用することにした。まず、トークンをランダムにマスクしたインプットシーケンスを使ってモデルをトレーニングする。これによってモデルは、マスクされたトークンの正しい値を推測することを学習しなければならない。次に、ランダムなマスクや入れ替え、トークンの削除によって破損したシーケンスでモデルをトレーニングする。これにより、正しいシーケンスを出力することを学習しなければならない。最後に、2つのモデルを並列的にトレーニングして逆変換を行った。つまり、ひとつのモデルがソースからターゲット言語への変換を学習し、もうひとつがソースに戻すことを学習するのである。
イメージ提供: https://arxiv.org/abs/2006.03511
モデルをトレーニングするためにチームは、GitHubの280万を越えるオープンソースリポジトリからサンプルコードを採掘した。その中から対象とする言語(Java、C++、Python)のファイルを選択し、個々の関数を取り出した。関数レベルでの作業を選択した理由は2つある。ひとつのトレーニング入力バッチに格納するのに十分な小ささであることと、関数を変換することでユニットテストを使用した評価が可能になることだ。多くのNLPシステムでは、変換結果を評価するためにBLEUを使用しているが、このメトリクスはトランスパイラの評価には適していない、とFacebookの研究者たちは述べている。構文的に似通った結果であれば、BLEUスコアは高くなるが、"コンパイルや実行結果がまったく異なっている場合がある"ためだ。それとは逆に、同じ結果を生成する別実装のプログラムでは、BLEUスコアは低くなる。そこでチームは、トランスパイラの結果を評価する手段として、ユニットテストスイートの使用を選択した。テストはGeeksforGeeksサイトから、全3言語で記述されたソリューションを含む問題を収集することで入手した。この結果、852の関数セットが完成したのだ。このテストセットの上で、TransCoderのパフォーマンスを既存のトランスパイラソリューションと比較した。対象としたのは、j2py Java-to-Pythonコンバータと、Tangible Software SolutionsのC++-to-Javaコンバータの2つである。その結果、TransCoderのスコアはC++-to-Java、Java-to-Pythonでそれぞれ74.8パーセント、68.7パーセントとなり、2つの商用ソリューションの61パーセントと38.3パーセントを"大幅に"凌駕した。
Redditでの議論の中では、ひとりのコメンタが、複数の言語を単一ランタイムでサポートするGraalVMの戦略とこのアイデアを対比させている。別のコメンタは、次のような意見を述べている。
[TransCoderは]面白いアイデアですが、構文の変換は難しい部分ではないと思います。メモリ管理やランタイムの違い、ライブラリの違いなどは、どうなるのでしょうか?
TransCoderの論文には"コードとトレーニング済モデル"をリリースするチームの意向が述べられているが、現時点では実施されていない。