持续交付2.0

谷歌软件工程中的 AI 应用研究:进展和未来之路

Image

“AI 代码补全对开发者生产力的影响,除了感知到的生产力和被接受的编码建议之外,其它还仍然是一个开放的问题。”

1

谷歌如何将ML与SE相结合

谷歌结合ML和SE开发了一种新的基于Transformer的混合语义ML代码补全工具,现已向其谷歌内部开发者开放。

谷歌通过以下方式结合ML和SE:

(1)使用ML重新排列SE的单个标记建议;

(2)应用ML进行单行和多行补全,并用SE检查正确性;

(3)使用ML继续SE的单个标记语义建议进行单行和多行补全。

谷歌将10000多名谷歌员工(在三个月内跨越八种编程语言)的混合语义ML代码补全与对照组进行比较,发现在接触到单行ML补全时,编码迭代时间(构建和测试之间的时间)减少了6%。这些结果表明,ML和SE的结合可以提高开发者的生产力。

目前,接受ML补全建议生成的新代码占3%(以字符计)。

2

补全用的Transformers

谷歌将代码视为类似于语言的实体,用子词标记和SentencePiece词汇表表示,并使用在TPUs上运行的编码器-解码器Transformer模型来进行补全预测。

输入是光标周围的代码(约1000-2000个词元),输出是一组建议以补全当前或多行代码。序列是通过在解码器上进行束搜索(或树探索)生成的。

在谷歌的单一代码库上训练期间,谷歌遮蔽了一行的其余部分和一些后续行,以模仿正在积极开发的代码。

在八种语言(C++、Java、Python、Go、Typescript、Proto、Kotlin和Dart)上训练了一个单一模型,并观察到所有语言的性能都有所提高或保持不变,消除了对专用模型的需求。

此外,谷歌发现大约5亿参数的模型大小为高预测准确性和低延迟及资源成本提供了良好的折衷。

该模型从单一代码库的质量中获益匪浅,后者通过指南和审查得到强制执行。对于多行建议,我们迭代地应用单行模型,并学习阈值以决定是否开始预测下一行的补全。

Image

3

使用ML重新排列单个标记建议

当用户在IDE中输入时,会同时在后端从ML模型和SE请求交互式代码补全。


SE通常只预测单个标记。我们使用的ML模型预测直到行尾的多个标记,但我们只考虑与SE预测相匹配的第一个标记。我们找出也包含在SE建议中的前三名ML建议,并将它们的排名提升至顶部。然后,重新排列后的结果将作为IDE中的建议显示给用户。

在实践中,我们的SE在云端运行,提供开发者熟悉的语言服务(例如,语义补全、诊断等),因此我们将SE与执行ML推理的TPU在同一位置运行。

SE基于一个内部库,提供具有低延迟的类似编译器的功能。根据设计要求,请求是并行完成的,而ML通常更快地提供服务(中位数约40毫秒),我们没有给补全添加任何延迟。

我们观察到在实际使用中质量有显著提升。在28%的接受补全中,由于提升,补全的排名更高,但是会有0.4%的情况更糟。此外,我们发现用户在接受补全建议之前输入的字符减少了超过10%。

4

检查单行/多行ML补全的语义正确性

在推理时,ML模型通常不知道输入窗口之外的代码,并且在训练期间看到的代码可能缺少在活跃变化的代码库中进行补全所需的最新添加。这导致了ML驱动的代码补全的一个常见问题,即模型可能建议看起来正确的代码,但实际上无法编译。

基于内部用户体验研究,这个问题随着时间的推移可能会导致用户信任的侵蚀,同时减少生产力收益。

我们使用SE在给定的延迟预算内(端到端补全的<100ms)执行快速的语义正确性检查,并使用缓存的抽象语法树来实现“完整”的结构理解。典型的语义检查包括引用解析(即,这个对象是否存在)、方法调用检查(例如,确认方法是否以正确数量的参数调用)和可赋值性检查(以确认类型符合预期)。

例如,对于编程语言Go,约8%的建议在语义检查之前包含编译错误。然而,应用语义检查可以过滤掉了80%无法编译的建议。所以,在引入该功能的前六周内,单行补全的接受率提高了1.9倍,可能是由于用户信任度的提高。

相比之下,对于我们没有添加语义检查的语言,我们只看到了1.3倍的接受率增长。

Image

5

结果

在超过10,000名谷歌内部开发者在他们的IDE中使用这种补全设置后,我们测量到用户接受率在25-34%之间。

我们确定,基于Transformer的混合语义ML代码补全完成了超过3%的代码量,同时将谷歌开发者的编码迭代时间减少了6%(在90%的置信水平上)。

这种变化的幅度对应于变革性特性(例如关键框架)通常观察到的效果,这些特性通常只影响一小部分人群,而ML有潜力为大多数主要语言和工程师提供普遍的改进。

Image

Image

6

结论与未来工作

我们刚刚展示了如何结合基于规则的语义引擎和大型语言模型,显著提升开发者的生产力,提供更优质的代码补全服务。

作为下一步,我们希望进一步利用SE,在推理时为ML模型提供额外的信息。例如,有一个例子是在进行长预测时,在ML和SE之间来回迭代,SE 将迭代检查正确性并为 ML 模型提供所有可能的续写选项。

在添加由ML驱动的新功能时,我们希望不仅超越“智能”结果,还要确保对生产力产生积极影响。

原文链接:https://research.google/blog/ml-enhanced-code-completion-improves-developer-productivity/