机器之心报道
编辑:陈萍、杜伟
来自 Facebook 的研究团队将迁移学习用于代码自动补全,提出的方法在非常小的微调数据集上提高 50% 以上的准确率,在 50k 标记示例上提高了 10% 以上的准确率。
代码自动补全功能(应用程序预测文本输入中的下一项)已成为消息传递等任务中便捷且广泛使用的工具,也是用于计算机编程所需的集成开发环境(IDE)最重要功能之一。
最近的研究表明,代码自动补全可以通过深度学习来实现,训练数据来自程序员使用 IDE 编码行为的真实数据,使软件语言模型能够获得显著的准确率提升。然而,对于不太流行的编程语言来说,经常会遇到一个问题,即可用的 IDE 数据集可能不足以训练出一个模型。
近日,来自 Facebook 的研究团队在论文《Improving Code Autocompletion with Transfer Learning》中展示了迁移学习如何在自动补全预测任务上进行微调之前,实现在非 IDE、非自动补全和不同语言示例代码序列上的预训练。实验结果表明,该方法在非常小的微调数据集上提高了超过 50% 准确率,在 50k 标记示例上提高了超过 10% 准确率。
论文链接:https://arxiv.org/pdf/2105.05991.pdf
本文的贡献主要包括以下几个方面:
- 该研究从版本控制提交获得的源代码文件,预训练了两个 transformer 软件语言模型 GPT-2 和 BART,结果显示它们在自动补全预测方面的性能,比直接使用实际 IDE 代码序列的微调提高了 2.18%;
- GPT-2 模型在两个真实数据集上进行了训练:IDE 编写程序期间和代码补全选择期间记录的代码序列。预训练和针对特定任务的微调相结合能够使模型性能更好,高出基准模型 3.29%;
- 该研究显示,与仅对 Python 实例进行训练的模型相比,与在 Hack 实例上进行了预训练并在 10k Python 实例上进行了微调的模型进行比较,在不同编程语言上进行预训练可将准确率提高 13.1%;
- 通过在线 A/B 测试,该研究证明了在三个迁移学习维度(任务、领域和语言)上的改进,自动补全工具的使用率分别提高了 3.86%、6.63% 和 4.64%。
实验设置
该研究的数据集(如下表 1 所示)来源于 Facebook 的真实开发者活动。研究者专注于两种开发语言 Hack 和 Python,这两种语言在 Facebook 拥有大量的开发者群体。
在本文中,研究者使用两种模型(都结合了 Transformer 架构)评估迁移学习的效果。由于本文的重点是研究迁移学习的影响,因此实验将重点集中在了这两种模型上,并且没有与其他 SOTA 模型进行比较。实验用到的模型包括:
- GPT-2:一种解码器 transformer 模型,由于 transformer 具有同时观察所有序列元素及其自注意力块的能力,因此在代码预测中达到了 SOTA 性能;
- PLBART:一种双向模型,该模型利用编码器对代码完成点周围的上下文进行编码,并使用类似 GPT-2 的解码器进行自动回归生成。
每个软件语言模型分两个阶段进行训练,分别是预训练阶段和微调阶段。所有模型都使用 Nvidia Tesla V100 GPU、20 epoch 进行训练(在融合时提前终止)。预训练以及微调前学习率分别设置为 5^−4 和 5^−6。
研究者通过离线和在线的方式评估模型性能。
离线评估:研究者使用 10% 的 HackAutocompletion、PythonAutocompletion 作为测试数据集。HackAutocompletion 示例平均有 99.5 条候选建议可供选择,pythonautomplection 示例平均有 26.3 条。候选建议列表允许将评估作为一个排名问题。对于每个离线测量,研究者报告 top-1 和 top-3 的准确率以及 k=3 的平均倒数排名(MRR@)。MRR 定义为:
在线评估:该研究旨在提高开发者 IDE 体验。虽然离线评估速度更快、成本更低,但必须使用真实用户测试改进。在线评估中,对来自 Facebook 的数千名 Hack 开发者进行了多次实时 A/B 实验。在每个实验中,开发者被随机分配到一个实验组或控制组,测量每个用户的每日完成量(DCPU)。使用这个指标,A/B 测试观察值是指其中一个组(实验组或控制组)中给定开发者在给定日期使用自动补全的次数。研究人员对每个组进行实验,直到达到至少 95% 的统计数据。
实验结果
离线评估:在标记数据上进行微调的自动补全模型在离线和在线评估中的性能优于没有特定任务微调的模型。在离线评估中,下表 III 显示微调使得 top-1 的准确率从 39.73% 提高到 41.91%。将标记样本加入预训练(HackAll)后,top1 的准确率从 40.25% 上升到 41.6%。在训练 Python 自动补全模型时也观察到了同样的趋势(表 IV)。
在线评估:在 HackIde 上训练了一个自动补全模型。实验变量在 HackAutocompletion 上进行微调,而控制变量没有进行微调。下表 II 中的实验 1 表明,在 p=0.0238 时,实验组的每位用户每日完成量(daily completions per user, DCPU)增加了 3.86%。
研究者进行了第二个 A/B 实验,比较了前一个实验(HackIde 的预训练和 HackAutocompletion 的微调)中更好的模型和没有预训练的 HackAutocompletion 训练模型。实验 2 显示没有进行预训练模型的巨大改进,实验组的 DCPU 在 p=0.017 时,增加了 6.63%。
在线评估:研究者进行了 A / B 实验,以探讨预训练对代码提交的现实影响。上表 II 中的实验 3 表明,在 p = 0.049 时,预训练模型可提高 3.62%的 DCPU。
下图 4 显示了在 HackAll 上预训练模型具有更好的性能,这与在微调中使用的 PythonAll 示例的数量无关。当将模型限制为仅 10k (top1 准确率 13.1%,37.11% vs. 24.01%)和 25k (top1 准确率 12.6%,41.26% vs. 28.66%)时,边际影响最大。
这表明在自动补全中跨编程语言的知识迁移的明显证据。在 HackAll 上预训练并使用 25k 和 50k PythonAll 示例进行微调的模型的性能与使用 50k 和 100k PythonAll 示例从头训练的性能相似。这表明,在使用其他语言的数据集进行预训练后,所需的样本数量只有原来的一半。
下表 V 展示了对 HackAutocompletion 、PythonAutocompletion 微调后,性能分别提高了 0.5%、1.34%。然而,与最好的单一语言模型相比,多语言模型没有表现出这种显著改进。最优的多语言模型的 top-1 准确率比最优的 Python 模型高 0.53%,但比最优的 Hack 模型低 0.02%。结合其他研究结果并假设,随着每种语言中可用示例数量的增加,跨语言组合编程语言示例的边际效益(marginal benefit)递减。
上表 III 显示,使用 HackAutocompletion 微调进行的 HackCommit 预训练的性能优于 HackAutocompletion,提高 3.29%top-1 准确率(39.61%VS36.32%)。PLBART 的 top-1 准确率提高幅度更大(表 VI):6.52%(51.06%VS44.54%)。