针对现有代码搜索解决方案依然存在的一些不足,语言智能处理研究组( LIPLAB )博士生范也同学创新性提出通过双向 Hard Negative Mining 以获得更好的对比学习效果的代码搜索解决方案 CoCoHaNeRe。该工作近期被软件工程领域顶级期刊 CM TOSEM( CCF A类 )录用。该研究工作的背景、动机、具体方案和评估等内容详细介绍如下。
1. 代码搜索研究背景:旨在根据给定的自然语言查询在庞大的代码库中找到最相关的代码片段。准确的代码搜索引擎可以提高代码重用度并提高编程效率。代码搜索的重点是如何度量代码和查询的语义相似度。随着代码预训练、大语言模型的发展,使用数值特征向量表示代码和查询的语义、使用向量距离表示语义相似度的模式已经取代了传统的字符串匹配方法。语义表示的质量对代码搜索等下游任务的有效性至关重要。目前,最先进的学习方法采用对比学习范式。对比学习的目标是最大化匹配的代码和查询( 正样本 )之间的相似度,并最小化不匹配的代码和查询( 负样本 )之间的相似度。为了增加负样本的重用,现有的对比学习方法使用大队列( 存储库 )来存储。
2. 本文研究动机:利用反例进行代码搜索还存在很大的改进空间。首先,由于负样本的随机选择,现有模型学习到的语义表示不能很好地区分相似的代码。其次,由于记忆库中的语义向量复用了之前的推理结果,然后直接用于损失函数计算,没有经过梯度下降,导致模型不能有效学习到负样本语义信息。
3. 具体方案:首先,为了让模型能够区分相似的代码,如图 1 所示,CoCoHaNeRe 在对比训练中引入了双向困难负例挖掘,也就是代码库中与正例最相似的负例,因为困难负例最容易让模型出错,解决好困难负例更能让模型取得好的学习效果。其次,为了提高训练过程中负样本的学习效率,CoCoHaNeRe 将所有困难负例都加入到模型的梯度下降过程中,具体如图 2 所示。
图1. 双向困难负例挖掘与对比学习
图2. 用 Memory Bank( Queue )存储 Hard Negative Examples 并实时更新
4. 效果评估:为验证 CoCoHaNeRe 的有效性,本文在六种编程语言的大型代码搜索数据集、相似代码检索任务、代码克隆检测和代码问答任务上进行了实验。实验结果表明,CoCoHaNeRe 模型达到这些任务上的 SOTA 性能。在代码搜索任务中,CoCoHaNeRe 的平均 MRR 得分分别超过 CodeBERT、GraphCodeBERT 和 UniXcoder 11.25%、8.13% 和 7.38%,在代码克隆检测和代码问答方面也取得了很大进展。此外,该方法在不同编程语言和代码预训练模型中表现均良好。此外,定性分析表明我们的模型有效区分了相似代码之间的高阶语义差异。
范也同学由 LIPLAB 葛季栋老师和李传艺老师共同指导,主要研究代码检索及其应用。欢迎对本工作感兴趣的同学与我们联系:lcy@nju.edu.cn , yefan@smail.nju.edu.cn 。