在软件研发过程中,“代码补全”至关重要,它可以有效的提升开发效率、减少拼写错误和输入代码量。本期《云效说码》分享邀请斑马网络技术专家旭伦分享了《技术红利下的代码补全》,介绍了深度学习革命带来的技术红利,在代码补全业务中对于这些“红利”的应用,以及在阿里云上低成本落地的方法。
【以下为旭伦分享实录,有删减】
深度学习革命带来的三个技术红利
2012年ImageNet竞赛冠军Hinton和他的学生Alex Krizhevsky设计出AlexNet,从而引领了以深度全连接网络、深度卷积网络、循环网络为代表的第一次深度学习革命,其成果是在图像识别领域人工智能超越人类。
深度学习和强化学习结合形成了第二次深度学习革命,其代表事件是:2016年阿尔法围棋(AlphaGo)打败韩国围棋九段棋手李世石;2017年,阿尔法围棋以总比分3比0战胜世界排名第一的中国棋手柯洁。从此,人工智能在围棋上打败人类。
“预训练模型”的出现和发展带来了第三次深度学习革命,其成果是在自然语音处理方面人工智能战胜人类,目前该技术已经在机器翻译和智能回答机器人领域得到广泛应用。
其中“预训练模型”可能是大家了解最少的,但是跟代码补全最相关,我简要介绍一下,其实目前“各大厂”都在训练自己的预训练模型,大家可以登录“GLUE”网站进行查看,排名几乎每天都在变化,这张截图是阿里巴巴达摩院的“StructBERT”登顶时截取的。
目前,深度学习中的预训练模型已经在很多任务上超越人类,比如CoLA数据集是判断一个句子是不是符合语法规则;SST-2情感分析数据集用于判断一条影评语句是正面还是负面的;MRPC数据集用于判断两条新闻句子描述的是不是同样的意义等。这些通过BERT等预训练模型都可以处理,其最新改进版都可以超越人类标注的值。除此之外,还有GPT2等生成模型,可以实现自动写作功能。
预训练模型与代码补全技术的结合
前面我们提到了“预训练模型”不仅可以判断语句是否符合语法规则,分析影评语句是正面还是负面,甚至可以实现自动写作文。那么“预训练模型”是否可以帮助我们做“代码补全”呢?回答是肯定的。
代码补全的基础理论是:代码大数据理论。“代码大数据”包含了代码和代码元信息,代码元信息,包括注释信息,代码提交时的信息,测试、review时的信息,BUG信息等。这个理论要起作用,需要基于一个公理:基于代码的自然性原理。
虽然语言可以千变万化,但是落实到日常生活中,由于认知的限制和实际的需要,我们日常交流所有的语言是重复性的,有规律的,可预测的。这个统计上的结果,导致了统计机器学习方法在语音识别、机器翻译等领域的巨大成功。于是我们可以假设程序代码也是自然的,因为它们也是人类在工作中创建的,受到硬件的软件的各方面的限制,它们也应该是有其统计规律的。
经过研究证明,代码不但是有自然性的,而且比自然语言的自然性还要好。为此,人们实现了一套基于统计方法的代码补全系统,并成功应用于eclipse IDE中。
有了理论之后,大家迅速将其应用于解决自己手头的问题,代码智能一片繁荣:
2014年代码智能技术被用于代码提示与补全和提升代码可读性;
2015年用于推荐方法名和类名以及语法错误修复;
2016年用于bug修复和源代码总结和查找代码克隆;
2018年被用于预测bug和自动为代码生成注释以及用于反混淆。
代码补全的局限性及解决方案
正在看起来岁月静好的时候,Vincent J. Hellendoorn和Premkumar Devanbu发表了《深度神经网络是建模程序源代码的最佳选择吗?》,认为OOV(Out-of-vocabulary)问题导致深度学习处理程序语言的效果还不如传统机器学习方法。
除此之外,代码补全系统还有3个要求:总是要给出补全结果,速度要跟上程序员打字速度 ,资源占用不能太高。
从程序员的视角看,本地发生的开发与最终提交的开发顺序和上下文环境非常不同,动态集成本地数据的模型比静态模型运行得好得多,针对重复典型模式进行了优化,但可能无法提供新的见解。
为了解决此问题,在实践上,需要实现补全算法,我们需要进行混合模型处理,既要有本地传统算法引擎,也要有远程的算法模型。
从落地方法上,我们采用huggingface的Transformers库,因为其针对多个模型有良好的封装。
在阿里云上低成本落地的方法
如下图所示,这是一张代码补全系统的架构图,除了需要有一个主算法引擎外,我们还需要一个带离线缓存更新的超大规模引擎。为什么要有超大规模引擎?因为前面也提到了,程序员希望代码补全系统可以提供他们不知道内容。这样的结构需要很强的算力,普通的个人笔记本跑不起来。如果要在个人笔记本中实现,就还必须有快速引擎、RNN引擎和注意力引擎。
为了节省成本,我们采用抢占式GPU的方式进行训练。但问题是“抢占式GPU”虽然便宜,但是GPU资源随时可能被别人抢走。“计算”被抢走了,你的“存储”存在哪里呢?这个时候就需要一个本地的存储,我选择的是用“本地NAS”。大家可以简单理解“NAS”就是一个网盘,存储速度很快,但是费用也很高。为了节省预算,我们还需要配一个“本地OSS”,这样我们就构成一个训练服务器集群。
因为我们用到的“模型”太大了,如果直接从国外的服务器上下载,速度很慢,可能几天也无法下载一个“模型”。于是,我们再次发挥云计算的优势。我们可以先在香港租用了临时ECS,然后通过“香港OSS”再转移到“本地OSS”中,从而实现下载加速。
以上内容来自旭伦在“云效开发者交流群”中的视频直播分享,有删节,您可以钉钉搜索群号(23362009)入群,观看完整视频。
关于云效:
云效,企业级一站式DevOps平台,源于阿里巴巴先进的管理理念和工程实践,致力于成为数字企业的研发效能引擎!云效提供从“需求 ->开发->测试->发布->运维->运营”端到端的在线协同服务和研发工具,通过人工智能、云原生技术的应用助力开发者提升研发效能,持续交付有效价值。