选自Google AI博客
作者:Maxim Tabachnyk等人
机心编译
机器之心编辑部
自从Copilot出来以后,AI代码补全工具越来越普遍。在最近的一篇博客中,谷歌介绍了他们开发的混合代码完成方法,并进行了数万人的内部测试。测试结果表明,这种方法可以提高开发者6%的编码效率,有趣的是,模型相当小,只有0.5B的参数。目前他们3%的新代码是通过接受ML代码补全建议生成的。
越来越复杂的代码对软件工程的生产力提出了关键的挑战。代码完成是一种基本工具,有助于减轻集成开发环境(IDE)中的这种复杂性。
通常,代码完成的建议由基于规则的语义引擎(SE)实现,它通常可以访问完整的知识库并理解其语义结构。最近的研究表明,大型语言模型(如Codex和PaLM)可以提供更长、更复杂的代码建议,这加速了实用产品(如Copilot)的出现。然而,由机器学习(ML)支持的代码自动完成如何影响开发人员的生产力仍然是一个没有明确答案的问题。
在最近发表的一篇博客中,谷歌介绍了他们如何将ML和SE结合起来,开发了一种新的基于Transformer的混合语义ML代码完成方法,现在谷歌内部开发人员可以使用这种方法。
在文章中,他们讨论了如何将ML和SE结合起来:
使用ML来建议SE单个令牌的重新排序;
使用ML应用单行和多行补全,使用se检查正确性;
ML建议对单标记语义使用单行和多行延续。
跨越八种编程语言,耗时三个多月。Google将超过10000名内部开发人员的混合语义ML代码的完成情况与对照组进行了比较,发现当单线ML可用时,他们的编码迭代时间(构建和测试之间的时间)减少了6%,上下文切换(即离开IDE)的时间减少了7%。这些结果表明,ML和se的结合可以提高开发效率。Google表示,目前他们3%的新代码(以字符为单位)是通过接受ML代码补全建议生成的。
用于代码完成的转换器
一种常见的代码完成方法是训练transformer模型,该模型使用语言理解的自我注意机制来实现代码理解和完成预测。Google的代码处理方式类似于语言,采用子词token和句子片词汇表示,使用运行在TPU上的编解码transformer模型来完成完成预测。输入是光标周围的代码(大约1000-2000个token),输出是一组可以用来完成当前一行或多行代码的建议。由序列解码器上的束搜索(或树搜索)生成。
在谷歌monorepo的训练中,研究人员掩盖了一行代码的剩余部分和一些后续行,以模拟正在积极开发的代码。他们用八种语言(C++、Java、Python、Go、Typescript、Proto、Kotlin和Dart)训练了一个模型,并观察到模型的性能在所有语言中要么有所提高,要么相同,这消除了对专用模型的需要。此外,他们发现参数约为0.5B的模型可以在低延迟和低资源成本的情况下实现高预测精度。这种模式极大地受益于monorepo的质量。对于多行建议,他们迭代地应用具有学习阈值的单线模型来决定是否开始下一行的完整预测。
编码器-解码器的变换器模型用于预测代码行的剩余部分。
建议用ML 重新排列单个标记
当用户在IDE中键入代码时,后端ML模型和SE将同时交互地请求代码完成。SE通常只预测单个令牌。Google的ML模型预测了多个标记,直到行尾,但是他们只考虑第一个匹配SE预测的标记。他们确定了前三个ML建议,这些建议也包含在SE建议中,并将他们的排名提升到第一位。然后,重新排序的结果将作为建议显示在IDE中。
实际上,Google的SE运行在云中,提供开发者熟悉的语言服务(例如语义补全、诊断等。),所以他们将SE配置为在与执行ML推理的TPU相同的位置运行。SE基于内部库,提供类似编译器的功能和低延迟特性。由于上述设计,请求是并行完成的,ML通常可以更快地提供服务(中值约为40ms)。他们不会给完工增加任何延误。
谷歌的研究人员观察到,在实际使用中,代码完成的质量得到了显著提高。在28%的被接受建议中,完成结果明显受益于上述boost操作,其排名更高是因为boost的存在,只有0.4%的被接受结果与这一规律相悖。此外,研究人员发现,用户在接受补全建议前输入的字符数减少了10%以上。
检查单行/多行ML补全的语义正确性
在推理时,ML模型通常不知道输入窗口外的代码,训练时看到的代码可能会遗漏完成动态变化的知识库所需的新添加的代码。这就导致了ML支持的代码补全应用的一个普遍缺点,就是模型可能会建议看起来正确但无法编译的代码。根据内部用户体验研究,随着时间的推移,这个问题可能会导致用户信任度和工作效率的降低。
Google研究人员使用se在给定的延迟预算内(端到端完成小于100ms)进行快速语义正确性检查,并使用缓存的抽象语法树实现“完整”的结构化理解。的典型语义检查包括回指解析(即对象是否存在)、方法调用检查(如确认方法是用正确数量的参数调用的)和可赋值性检查(确认类型是否是预期的)。
举个例子,对于编码语言Go来说,语义检查之前大概有8%的建议包含编译错误,但是语义检查的应用过滤掉了80%的无法处理的建议。在加入这个功能后的前六周,一行完成的接受率已经提升到了1.9倍,这可能是因为用户信任度的提升。相比之下,对于没有语义检查的语言,研究人员只看到接受度提高了1.3倍。
可以访问源代码的语言服务器和ML后端并列在云端。它们都对ML完成建议执行语义检查。
结果
当超过10,000名谷歌内部开发人员使用其IDE中的完成功能时,研究人员测量的用户接受率为25-34%。他们确定,基于transformer的混合语义ML代码完成工具完成了超过3%的代码,同时将谷歌员工的编码迭代时间减少了6%(在90%的置信水平下)。ML有扩展到大多数主要语言和工程师的潜力。
基于10000多名Google内部开发者获得的一行代码补全验收结果。
基于5000多名Google内部开发者获得的多行代码完成验收结果。
在探索API时提供更长的建议
谷歌在博客中表示,他们还将语义补全和整行补全紧密结合。当带有语义单标记完成的下拉列表出现时,它们将内联显示从ML模型返回的单行完成结果。后者表示作为下拉焦点的项目的延续。例如,如果用户查看API的可能方法,内联整行完成显示完整的方法调用,其中也包含调用的所有参数。
ML的多行补全建议。
结论和今后的工作
在博客中,谷歌研究人员演示了如何利用基于规则的语义引擎和大型语言模型的结合来实现更好的代码完成效果,从而显著提高开发人员的工作效率。
接下来,他们希望通过在推理时向ML模型提供额外的信息来进一步利用se。一个例子是ML和SE之间的长预测,其中SE迭代地检查正确性并为ML模型提供所有可能的完成。当添加ML支持的新特性时,他们不仅要关注“智能”结果,还要确保对生产力的积极影响。
原文链接:https://ai . Google blog . com/2022/07/ml-enhanced-code-completion-improvements . html
剧终
授权请联系本微信官方账号。
投稿或寻求报道:content@jiqizhixin.com