代码补全漫谈(1) - 从TabNine说起

简介: # 代码补全漫谈(1) - 从TabNine说起 前不久,基于GPT-2模型的TabNine横空出世,在程序员界再次引起轰动。此前,国产的aixcoder,还有获得github ceo天使投资的Python编程利器kite等,已经收获了一轮又一轮的眼球。人工智能代替人编写代码的忧虑不时在知乎等网站上出现。 从程序语言处理的近亲 - 自然语言处理NLP的发展来看,这样的乐观不是没有道理的。从

代码补全漫谈(1) - 从TabNine说起

前不久,基于GPT-2模型的TabNine横空出世,在程序员界再次引起轰动。此前,国产的aixcoder,还有获得github ceo天使投资的Python编程利器kite等,已经收获了一轮又一轮的眼球。人工智能代替人编写代码的忧虑不时在知乎等网站上出现。
从程序语言处理的近亲 - 自然语言处理NLP的发展来看,这样的乐观不是没有道理的。从进入深度学习时代后,基于RNN的NLP技术不断发展进步,比如Attention机制引入RNN,到仅需要Attention的Transformer模型,到GPT, BERT, XLNet等预训练模型不断刷榜,借鉴NLP的经验,程序语言处理没有道理不取得大进步。TabNine的成功,也是对这种想法的印证。

但是,与外表的光鲜不同,程序语言处理学界却是处于纠结之中。NLP界的论文题目是这样的《Attention is all you need》,而程序语言的论文是这样的《Are Deep Nerual Networks the Best Choice for Modeling Source Code?》

Are Deep Neural Networks the Best Choice for Modeling Source Code?

就在这篇《Are Deep Neural Networks the Best Choice for Modeling Source Code?》中,作者Vincent J. Hellendoorn和Premkumar Devanbu认为,在程序语言处理方面,早日封神的深度神经网络的效果还不如基于传统统计方法的效果。
究其原因,他们提出三点:
第一,开发人员特别能造新词。这也没办法,变量名是造新词,函数名是造新词,面向对象设计方法就是造新词的助推器。这与自然语言完全不同,只有学术作品里才充满了术语,大部分人正常交流的词汇表非常有限,而且更新很慢。因为新词造出来没有用,得流行起来才有用,这个门槛可不低。而开发人员造词太容易了。但是,词造太多了,其实对人来说也同样是挑战,比如接手别人的代码,或者使用别人发明的API,都是令人头疼的事。
第二,开发人员造的新词局部性很强,出了一定范围重名很正常,然后每个人的风格还不一样。这也是自然语言中非常少见的情况,但是在写代码太正常了,新词有作用域,跨文件,跨模块都不一样。这是为了避免全局变量重名的一个重要手段,比如每个类中可以有局部变量,公有变量可以通过不同的类来区分,类重名可以用包来区分,如果包名加类名都一样,还可以加个容器来隔离各用各的。这样的要求,确实难为神经网络了。
第三,造词数量不但多,如果一次性批量造出来可以做训练也可以,但是随着代码编写,这是一个动态的过程。代码还可能错了重新修改。这样对于计算的实时性要求很高。这导致了基于大型NLP模型的改进算法,基本上没有能在程序员本机上运行的,都需要远程服务器的支持。

听起来是不是很有道理?确实是有道理的,我们将来介绍更多的背景知识后大家就会觉得更有道理。于是,两位作者提出了自己的解决方案,细节我们后面再讲,代码在这里:https://github.com/SLP-Team/SLP-Core
以上的三个问题,我们总结一下给它起个名字,OOV(Out Of Vocabulary)问题.

Maybe Deep Neural Networks are the Best Choice for Modeling Source Code

不过,硬币总是有两面的。《Are Deep Neural Networks the Best Choice for Modeling Source Code?》发表于2017年,2年后,隔空应答的论文《Maybe Deep Neural Networks are the Best Choice for Modeling Source Code》发表了。
该文作者Rafael-Michael Karampatsis和Charles Sutton承认OOV是个问题。不过他们认为,对于罕见词的处理也是机器翻译中的老问题了,2015年的论文《Neural Machine Translation of Rare Words with Subword Units》已经开始讨论采用subword的办法来解决这样的问题。

于是,Karampatsis和Sutton实现了一套基于开放词典的神经网络系统,有兴趣的同学可以关注下他们的代码实现:https://github.com/mast-group/OpenVocabCodeNLM

为了详细说明程序语言处理中遇到的问题和前人的解法,我们还是回到故事的起点,从代码的自然性说起。

代码的自然性

如果同学们对于源代码处理的技术想有一个整体的概念的话,不妨可以先读一篇综述论文:《A Survey of Machine Learning for Big Code and Naturalness
)》。
所谓的"Big Code",论文中原文是这么讲的『The scale of available data is massive: billions of tokens of code and millions of instances of meta-data, such as changes, bug-fixes, and code reviews (“big code”).』,也就是说,元数据,如代码修改的记录,bug修复的记录,代码评审的记录等等。

而Naturalness自然性,我们需要看另一篇论文《On the naturalness of software》。
这篇文章的主旨是说,虽然语言可以千变万化,但是落实到日常生活中,由于认知的限制和实际的需要,我们日常交流所有的语言是重复性的,有规律的,可预测的。这个统计上的结果,导致了统计机器学习方法在语音识别、机器翻译等领域的巨大成功。于是这篇论文的作者们假设程序代码也是自然的,因为它们也是人类在工作中创建的,受到硬件的软件的各方面的限制,它们也应该是有其统计规律的。
作者们研究的成果是非常正面的,他们证明,代码不但是有自然性的,而且比自然语言的自然性还要好。为此,他们实现了一套基于统计方法的代码补全系统,并成功应用于eclipse IDE中。

从那时起,各种对编程语言模型的研究百发齐放,如2013年Allamanis和Sutton的《Mining Source Code Repositories at Massive Scale Using Language Modeling》,2013年Nguyen的《A Statistical Semantic Language Model for Source Code》,2014年Tu, Su和Devanbu的《On the localness of software》,2016年Bielik等人的《PHOG: Probabilistic Model for Code》,Dam等人的《A deep language model for software code》等。

有了理论之后,大家迅速将其应用于解决自己手头的问题:
比如2014年《Code Completion with Statistical Language Models》用于代码提示与补全;
2014年的《Learning Natural Coding Conventions》和2015年的《Predicting Program Properties from "Big Code"》用于提升代码可读性;
2016年的《On the "Naturalness" of Buggy Code》用于bug修复;
2015年的《Suggesting Accurate Method and Class Names》用于推荐方法名和类名;
2016年的《A Convolutional Attention Network for Extreme Summarization of Source Code》和《Summarizing Source Code using a Neural Attention Model》用于源代码总结;
2018年的《DeepBugs: A Learning Approach to Name-based Bug Detection》用于预测bug;
2016年的《Deep Learning Code Fragments for Code Clone Detection》用于查找代码克隆;
2018年的《Deep Code Comment Generation》用于自动为代码生成注释;
2015年的《DeepFix: A Fully Convolutional Neural Network for predicting Human Eye Fixations》用于语法错误修复;
2018年提《A Deep Learning-Based Approach to Infer Natural Variable Names from Usage Contexts》用于反混淆;等等

正在看起来岁月静好的时候,Vincent J. Hellendoorn和Premkumar Devanbu发表了《Are Deep Neural Networks the Best Choice for Modeling Source Code?》,认为OOV问题导致深度学习处理程序语言的效果还不如传统机器学习方法。

P. Devanbu是加州大学戴维斯分校的老师。他参与了上面介绍的多篇论文的发表,如《On the "Naturalness" of software》《On the Localness of Software》《On the "Naturalness" of Buggy Code》《A Survey of Machine Learning for Big Code and Naturalness》。

Vincent Hellondoorn是Devandu老师的博士生。他今年的另外两篇论文《Deep Learning Type Inference》和《When Code Completion Fails: a Case Study on Real-World Completions》也是我们这一系列文章的主角。

目录
相关文章
|
2月前
|
人工智能 分布式计算 大数据
碾压级优势!阿里云AI云市场份额超过2-4名总和,2026新晋AI时代”领导者“
阿里云以35.8%的中国AI云市场份额稳居第一,远超第二至第四名总和,是亚太唯一在生成式AI四大领域均获最高评级的云服务商。全栈自研“云+大模型+芯片”,通义千问成全球第一开源大模型,下载超6亿次。
|
10月前
|
监控 搜索推荐 Java
Java 多线程最新实操技术与应用场景全解析:从基础到进阶
本文深入探讨了Java多线程的现代并发编程技术,涵盖Java 8+新特性,如CompletableFuture异步处理、Stream并行流操作,以及Reactive编程中的Reactor框架。通过具体代码示例,讲解了异步任务组合、并行流优化及响应式编程的核心概念(Flux与Mono)。同时对比了同步、CompletableFuture和Reactor三种实现方式的性能,并总结了最佳实践,帮助开发者构建高效、扩展性强的应用。资源地址:[点击下载](https://pan.quark.cn/s/14fcf913bae6)。
539 3
|
域名解析 网络协议 虚拟化
|
监控 安全 项目管理
『软件工程3』你应该知道的三种原型实现模型:抛弃式、演化式、增量式
该文章详细解释了三种原型实现模型——抛弃式、演化式、增量式模型的特点、流程、优缺点及适用场景。
『软件工程3』你应该知道的三种原型实现模型:抛弃式、演化式、增量式
|
机器学习/深度学习 人工智能 持续交付
利用AI进行代码审查:提升软件质量的新策略
【10月更文挑战第28天】本文探讨了AI在代码审查中的应用,介绍了AI如何通过静态代码分析、代码风格检查和实时反馈提升代码质量。文章还讨论了将AI工具集成到CI/CD流程、定制化规则和结合人工审查等进阶技巧,并推荐了SonarQube和DeepCode等实用工具。未来,AI代码审查工具将更加智能,助力软件开发。
扩展uview表单组件标题文本支持两端对齐
扩展uview表单组件标题文本支持两端对齐
619 2
|
监控 Oracle 数据可视化
深度解析JVM性能监控工具:推荐与详细用法
深度解析JVM性能监控工具:推荐与详细用法
1849 0
|
数据采集 机器学习/深度学习 人工智能
算法金 | 一个强大的算法模型,多项式回归!!
```markdown # 多项式回归简述 - 多项式回归是线性回归扩展,用于处理非线性关系。 - 通过添加高次项来拟合复杂模式,但可能引发过拟合。 - 示例中展示了如何用Python创建模拟数据,使用`PolynomialFeatures`生成多项式特征,训练线性回归模型并可视化结果。 - 优点:灵活捕捉非线性关系,易于理解。 - 缺点:易过拟合,计算复杂度高。 - 相关概念:正则化(岭回归、Lasso回归)及其他非线性模型(如支持向量回归)。 - 注意事项:选择合适阶数,避免过拟合,重视数据预处理和模型评估。 ```
516 0
算法金 | 一个强大的算法模型,多项式回归!!

热门文章

最新文章

下一篇
开通oss服务