谷歌提出最新的基于规则和机器学习混合的代码补全方法
日益复杂的代码对软件工程的生产率提出了关键挑战。代码补全是一种重要工具,有助于缓解集成开发环境(IDE)中的这种复杂性。通常,代码完成建议使用基于规则的语义引擎(semantic engines,SE)实现,这些引擎通常可以访问完整的存储库并理解其语义结构。最近的研究表明,大型语言模型(例如Codex和PaLM)可以实现更长更复杂的代码建议,因此,出现了有用的产品(例如Copilot)。然而,由机器学习(ML)支持的代码补全如何影响开发人员的生产力,而不仅仅是感知的生产力和可接受的建议,这个问题仍然悬而未决。
今天,我们将介绍如何将ML和SE结合起来,开发一种新的基于Transformer的混合语义ML代码补全,现在可供内部谷歌开发人员使用。我们讨论了如何通过(1)使用ML对SE单标记建议重新排序,(2)使用ML应用单行和多行补全并使用SE检查正确性,或(3)使用单标记语义建议的ML的单行和多行延拓来组合ML和SE。我们将10k以上的Googler的混合语义ML代码完成情况(跨越八种编程语言超过三个月)与对照组进行比较,发现当暴露于单行ML完成时,编码迭代时间(构建和测试之间的时间)减少了6%,上下文切换(即离开IDE)减少了7%。这些结果表明,ML和SE的结合可以提高开发效率。目前,3%的新代码(以字符为单位)是通过接受ML完成建议生成的。
补全transformers
代码补全的一种常见方法是训练transformer模型,该模型使用自注意力机制进行语言理解,以实现代码理解和完成预测。我们处理类似于语言的代码,用子词标记和句子段词汇表表示,并使用TPU上运行的编码器-解码器-转换器模型进行完成预测。输入是围绕光标的代码(约1000-2000个令牌),输出是一组完成当前或多行的建议。序列是通过解码器上的波束搜索(或树探索)生成的。
在谷歌monorepo的训练期间,我们屏蔽了一行的其余部分和一些后续行,以模拟正在积极开发的代码。我们在八种语言(C++、Java、Python、Go、Typescript、Proto、Kotlin和Dart)上训练单个模型,并观察到所有语言的性能都得到了改善或相同,从而消除了对专用模型的需要。此外,我们发现,约0.5B参数的模型大小可以在低延迟和资源成本的情况下很好地权衡高预测精度。该模型极大地受益于单一回购协议的质量,这是由指导方针和审查强制执行的。对于多行建议,我们迭代应用具有学习阈值的单行模型来决定是否开始预测下一行的完成情况。




