Facebook 转码器
转码器是 Facebook 的研究人员于 2020 年 9 月在题为“无监督编程语言的翻译”的论文中提出的。该项目的目标是训练 AI 理解不同语言的代码,并能够将代码从一种语言转换为另一种语言。许多公司的代码库使用的是 COBOL 等旧编程语言,如果他们想将代码库转移到Java、C++ 或Python等较新的编程语言,他们需要大量的资金和精力来做到这一点。在这种情况下,转码器可以节省大量资源。
模型 :
对于 TransCoder,作者使用了带有注意力的序列到序列 (seq2seq) 模型。 seq2seq 架构由一个编码器和一个具有转换器架构的解码器组成。作者对所有编程语言使用单一共享模型。为了训练模型,他们提出了三个原则:
- 跨编程语言模型 (XLM) 预训练:预训练是一个重要的部分,因为它确保表达相同指令的不同代码段是否应该映射到相同的表示,而不管编程语言如何。作者观察到,使用掩码语言建模目标进行预训练可以显着改善单语源代码的预训练
- 去噪自动编码:由于 XLM 预训练为编码器架构生成了高质量的嵌入,但解码器仍然缺乏翻译代码的训练。因此,使用 Demising -Encoding 目标训练模型,其中模型被训练以预测给定序列的损坏版本的令牌序列。
- 反向翻译:在实践中,仅 XLM 预训练和去噪自动编码就足以生成翻译。然而,这些翻译的质量往往较低,因为该模型从未接受过将函数从一种语言翻译成另一种语言的训练。为了解决这个问题,作者使用了反向翻译方法。这种反向翻译方法通常用于我们拥有大型单语(一种语言)数据集的情况。在这种方法中,模型被训练以并行地将源转换为目标,反之亦然。
数据集和训练细节:
- 训练架构:作者使用具有 6 层、8 个注意力头的转换器架构,并将模型的维度设置为 1024。他们对所有编程语言使用单个编码器和单个解码器。预训练后,作者交替使用降噪自动编码和反向翻译目标训练模型。为了优化模型,作者使用了 Adam Optimizer。
- 预处理:作者对Java使用 javalang 分词器,对Python使用标准库的分词器,对 C++ 使用 clang 分词器。这些分词器确保代码中的无意义修改不会对分词序列产生任何影响。
- 使用的数据集:对于训练,作者使用 Google BigQuery 上可用的 Github 公共数据集并过滤允许重新分发部分项目的存储库,并选择Java、 Python和 C++ 代码。作者使用函数级代码进行训练评估,因为它们足够短以适合单个批次,并且可以通过使用该函数生成的输出轻松进行评估。为了验证和测试,作者在GeeksforGeeks平台上使用了多种语言解决方案来解决问题。
执行:
Python3
# First clone the git repository for transcoder
# in local environment
! git clone https: // github.com/facebookresearch/TransCoder transcoder/
# Download the model files (link given in official
# git repository)
! wget https: // dl.fbaipublicfiles.com/transcoder/model_1.pth /
# Since transcoder is implemeneted in pytorch,
# we need to install pytorch first
! pip install torch torchvision
# Now install other required documentations
! pip install numpy fastBPE Moses Apex libclang submitit six sacrebleu == 1.2.11
# Now we run the translate.py file with following arguments:
# src_lang = source language file
# tgt_lang = target language file
# model_path = path of the model which we downloaded above
# > file.java/cpp/py = file which we want to convert
# the command below may take some time to run
! sudo python transcoder/translate.py - -src_lang java - -tgt_lang python - -model_path model_1.pth > code2.java
Input | TransCoder Output |
---|---|
C++ void worstFit(int blockSize[], int m, int processSize[], int n) { int allocation[n]; memset(allocation, -1, sizeof(allocation)); for(int i = 0; i < n; i ++){ int wstIdx = – 1; for(int j = 0; j < m; j++){ if(blockSize[j] >= processSize[i]){ if(wstIdx == – 1) wstIdx = j; else if(blockSize[wstIdx] < blockSize[j]) wstIdx = j; } } if(wstIdx != -1){ allocation[i] = wstIdx; blockSize[wstIdx] -= processSize[i]; } } cout << “\nProcess No.\tProcess Size\tBlock no.\n”; for(int i = 0; i < n; i++){ cout << ” ” << i+1 << “\t\t” << processSize[i] << “\t\t”; if(allocation[i] != -1) cout << allocation[i] + 1; else cout << “Not Allocated”; cout << endl; } } | Python def worstFit(blockSize, m, processSize, n): allocation = [-1] * n for i in range(n): wstIdx = -1 for j in range(m): if blockSize[j] >= processSize[i]: if wstIdx == -1: wstIdx = j elif blockSize[wstIdx] < blockSize[j]: wstIdx = j if wstIdx != -1: allocation[i] = wstIdx blockSize[wstIdx] -= processSize[i] print(“\nProcess No.\tProcess Size\tBlock no.\n”) for i in range(n): print(” ” + str(i+1) + “\t\t” + str(processSize[i]) + “\t\t”) if allocation[i] != -1: print(allocation[i] + 1) else: print(“Not Allocated”) print() |
Java public static int max(int a, int b){ return a > b ? a : b; } public static void createDirectory(Path path) throws IOException { if(!Files.exists(path)) { Files.createDirectories(path); } } | Python def max(a, b): return a if a > b else b def create_directory(path): if not os.path.exists(path): os.makedirs(path) |
结果和评价方法:
- 评估指标:在大多数研究中,作者使用了BLEU 分数,这是作者使用的另一个指标,称为参考匹配,它仅表示与真实参考完全匹配的翻译百分比。但是,这些指标并不能确保程序的语法正确性。作者使用了另一个称为Computational Accuracy 的度量,它比较了源函数和假设函数的输出。
- Beam Search:作者尝试了两个评估指标,要么采用模型只返回对数概率最高的假设(贪婪搜索),要么采用前 N 个对数概率。作者发现使用波束搜索时准确率显着提高,在Java → Python高达 33.7%,波束为 N=25。
- 以下是他们使用贪婪搜索时的结果。
C++ → Java | C++ → Python | Java →Python | Java → C++ | Python → C++ | Python → Java | |
---|---|---|---|---|---|---|
Reference Match | 3.1 | 6.7 | 24.7 | 3.7 | 4.9 | 0.8 |
BLUE score | 85.4 | 70.1 | 97.0 | 68.1 | 65.4 | 64.6 |
Computational Accuracy | 60.9 | 44.5 | 80.9 | 35 | 32.2 | 24.7 |
- 下面是基于N=25的BEAM搜索的评估结果:
Beam Search (N=25) | C++ → Java | C++ → Python | Java →Python | Java → C++ | Python → C++ | Python → Java |
---|---|---|---|---|---|---|
Computational Accuracy | 74.8 | 67.2 | 91.6 | 68.7 | 57.3 | 56.1 |
- 作者将 Transcoder 与两个现有框架 j2py(java-to-python)进行了比较,计算精度为 38.3,Tangible 软件的 C++-to-Java 转换器计算精度为 61%。转码器明显优于这两者。
参考:
- 转码纸
- 转码器 GitHub 官方仓库