当前位置: 首页 > 科技观察

参数数量仅0.5B,谷歌代码补全新方法内部生产效率提升6%

时间:2023-03-14 14:20:56 科技观察

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