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

DL时代的代码补全工具远比语言模型有效

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

从程序员到数据工程师,编写程序代码是一项基本功,但是编写冗长代码的过程也极大地消耗了开发者的耐心。最近关于代码补全工具的消息很多,比如美国的Kite,加拿大的TabNine等等,一时间引起了很多程序员的关注。但其实很多人还不知道,在这些被媒体不断推的国外产品背后,还有一个能力更强大、更早将深度学习应用于代码补全的产品,一个来自中国的工具——aiXcoder,它的开发者来自北京大学。在这篇文章中,机器之心采访了项目负责人北京大学计算机科学与技术系副教授李戈,请他解释自动代码补全背后的技术,以及技术aiXcoder背后的特点和优势,供读者朋友们参考。aiXcoder官网:https://www.aixcoder.com/#/aiXcoder的代码补全效果下面看一下写TensorFlow时的代码补全效果:如上图,aiXcoder在TensorFlow代码环境下可以直接“猜”A系列模型建立后的代码处理。比如定义loss之后,需要定义optimizer,然后需要train_op和init方法,最后定义模型的saver,开始运行计算图。这样的过程深度学习开发者基本都知道,但是按照过程写下来就很繁琐了。有了aiXcoder的提示,开发速度得到了提升。aiXcoder支持Java、C++/C、Python、PHP、JavaScript等多种语言,以插件的形式集成到现有的IDE中,如Pycharm、AndroidStudio、VSCode、Eclipse、Webstorm、Sublime等。背后该插件是一个强大的基于云的深度学习引擎。针对开发者,产品目前分为社区版、专业版和企业版。社区版完全免费,专业版也可以通过分享免费获取。它们之间的区别在于模型是否会继续学习。社区版主要使用预训练好的公共模型进行预测,而专业版会根据用户的代码习惯和结构做进一步的调整。企业版是aiXcoder最强大的版本。可以部署在企业内部的私有云中,可以使用企业自己的代码优化模型的训练,从而有更高的准确率和性能。aiXcoder的工作原理比听的还好,机器之心也测试过aiXocder的使用。机器之心在Pycharm上试过社区版/专业版,都需要在线推理。不同的是,Pro版本还需要额外的内存,因为每个Pro用户都需要一个额外的缓冲区来存储模型“学到的”用户习惯。当然,Pro用户的缓冲区只能通过此插件访问。一般来说,当我们选择Python和PyCharm时,代码补全自然会用到IDE自带的工具。使用aiXcoder的第一感觉就是比内置的补全工具灵活多了,因为之前的补全主要体现在Python函数或者其他包的API中,aiXcoder还会预测变量名是什么,操作是,想调用什么函数。虽然代码补全的推理过程都是在云端完成的,但是在我们的使用中,一般的网络环境甚至4G都可以有实时反馈,所以补全速度基本和Pycharm自带的工具差不多。李戈教授表示,目前大部分aiXcoder都能在200ms左右得到反馈。部分地区的用户可能会因为网络延迟而感到卡顿。aiXcoder正在全国主要城市部署服务器,以提升用户体验。同时,aiXcoder团队还特别关注模型压缩技术,希望将基于CPU的推理计算时间压缩到可接受的水平,从而推出可以在CPU上运行的本地版本。总体来说,aiXcoder提供的补全函数在预测变量名、函数名或者关键字的效果方面确实非常灵活,而且还会学习开发者的编码风格和编程模式,所以效果还是比较不错的。以下是一些自动完成的候选项。有些函数名在开发者中可能会被频繁使用,所以推荐:对于一些变量,aiXcoder可以根据变量类型提出对该变量可能的操作,例如下图“m”中的变量,aiXcoder提出一个代码添加字符串:对比评测aiXcoder官方也将这款产品与其他代码补全工具进行了对比,包括Kite和TabNine。在对比过程中,aiXcoder会使用Kite或TabNine官方提供的示例代码,测试完成这段代码需要多少次击键。结果表明,aiXcoder的效率是其他插件的1.5倍以上。aiXcoder是如何打造一个能够实现高效代码补全的aiXcoder,背后有强大的技术支持。据李哥教授介绍,aiXcoder很早就尝试了语言模型,把代码当成语言直接建模,就像DeepTabNine一样。然而,研究人员很快发现,只有语言模型是行不通的,它总是提出一些毫无意义、不科学的补全建议。为此,aiXcoder整合了基于序列的程序代码语言模型、基于抽象语法树和程序逻辑关系的图神经网络等方法,共同打造了一个完整的系统。为何难以直接生成代码如果深度学习模型能够直接按照开发者的意图端到端的方式生成相应的代码,那么这样的模型就非常“优雅”了。但经过研究发现,这样的任务要求很难实现,这与任务本身所依赖的数据的性质有关。李戈教授从机器学习所依赖的数据的性质出发,对代码生成任务与传统图像处理任务、自然语言处理任务的区别给出了更加直观的解释。对于图像识别或图像分类任务,机器学习的目标是在连续数据集(图像数据)和近连续数据集(标签)之间建立一种边界接近明确的映射关系。这样一来,由于图像数据极其密集,而标签集的边界又足够清晰,那么这相当于一个有大量数据需要学习的标签。这样的映射关系比较容易建立,这也是为什么机器学习中图像相关的任务比较容易完成的原因。对于自然语言处理任务,机器学习需要在一个相对连续(离散性高于图像)边界更清晰的数据集和另一个边界更连续的数据集之间建立一种关系。映射关系。由于自然语言处理中的文本数据比图像数据稀疏,因此与自然语言处理相关的任务更难获得更好的模型性能。但就代码生成而言,从程序员的意图(intent)生成程序代码的问题可以看作是从“程序员的意图空间”到“程序代码空间”的映射,其中意图可以是自然语言描述的信息。如上图所示,这是一个从边界更连续的数据集到边界更离散的数据集的映射。换句话说,虽然代码生成的意图比较明确,但是实现意图的代码数据比较稀疏,即使是同一个意图,对应的实现代码之间还是有很大的差距,所以这样的任务很难的。教育。为此,在aiXcoder的实际实现中,针对不同应用领域的代??码采用了特定的模型,只使用该领域的数据进行训练。例如,TensorFlow或PyTorch等框架也有自己特定的代码完成模型。这样做的主要目的是为了增强节目分发的密度。在特定领域,代码分布更接近连续性。可见,要按照程序员的“意图”“直接”生成完整的代码是非常困难的,但李哥教授表示,类似的技术可以用来辅助人类程序员编写代码,我们可以借鉴程序员写了什么。获取程序员在代码中的“编程意图”,进而综合分析代码、结构信息、变量引用信息、API序列信息、继承关系信息等,自动生成后续代码。但是在这个过程中,仅仅语言模型是远远不够的,还需要分析很多其他的代码特征,才能做好生成代码的补全。一个纯粹的预训练语言模型呢?说到代码补全,有些人可能会下意识地认为这只是一个普通的语言建模任务,模型只需要根据开发者之前编写的代码来预测未来的代码即可。因此,使用最先进的预训练语言模型,然后在代码数据上进行微调,可能是一个很好的方式。但李戈教授表示,这样的想法还远远不够。预训练语言模型在代码补全任务中表现不佳,主要是因为代码补全任务有许多不同于自然语言分析任务的挑战。首先是代码文本的语义抽象问题。代码的语义(功能语义)与其文字表示之间存在更大的差距。我们无法从字面上确定代码的确切语义。例如,在代码中,仅更改一个字符就可以完全改变整行代码的功能,因此处理代码语言并准确提取其含义是一项比自然语言处理更棘手的任务。f=open('word_ids.txt','r')f=open('word_ids.txt','w')如上图所示,Python代码中,打开时使用“r”和“w”一个文件”将执行完全不同的功能。另外,代码的功能语义难以表达和详细描述,代码的功能语义有多种表达方式。例如,为了实现某个功能,有多个文本形式的代码,不能说一个代码是对的,另一个是错的。list_a=[]foriinitems:result=test(i)list_a.append(result)list_a=[test(i)foriinitems]如图所示,实现list_a的代码可以多种多样,但是语言模型会学习它们完全不同的表示。同时,代码文本本身的结构也非常复杂。例如,代码的语义与代码的结构(如行与行之间的缩进)有很大的相关性,代码的语义依赖于代码的结构来表达。这是预训练语言模型难以表示的特征。最后,代码具有进化特征。代码比自然语言迭代得更快,因此预训练的语言模型无法及时捕获进化特征。考虑到代码语言的诸多特点,单纯的预训练语言模型无法取得很好的效果。既然核心技术不够单独的语言模型,那么aiXcoder结合了哪些技术,又是靠什么来完成代码的呢?总的来说,aiXcoder主要依靠其独特的深度神经网络模型学习程序代码,可以分析出以下几类程序的特征:1.程序的结构语义特征:编程语言是一种结构性强的语言,结构信息程序的语义也反映了程序的语义。例如,抽象语法树是一种更通用的解析代码的结构,它反映了代码的语义特征。aiXcoder充分利用抽象语法树来解释程序员编写的代码的语义。2、程序元素之间的逻辑关系:程序代码的不同元素之间存在不同的关系,如程序变量之间的引用关系、类之间的继承关系、方法和参数之间的调用关系等。程序本身可以表示为多种图,如控制流图、数据流图、调用图等。借助图神经网络,aiXcoder可以对程序元素之间的多种关系进行建模,从而可以对程序元素之间的复杂关系进行分析和推理。3、程序语言序列模型:当然,程序语言也有与自然语言相似的方面,因此可以利用程序标识符之间的序列关系来建立程序语言模型。aiXcoder还使用最新的深度学习语言模型对程序中的序列信息进行建模。在得到程序代码的各种特征之后,就要将这些特征输入到深度神经网络中进行分析,但这并不容易,因为这些特征在输入到神经网络之前需要进行向量化处理。在研究过程中,北京大学提出了一系列解决程序语言组件量化的方法,并在国际上首次发表相关论文,为aiXcoder的构建奠定了基础。