从代码检索到生成,Code Embedding Model如何改变开发者的工作方式?

向量数据库大模型数据库

SFR-Embedding-Code:用于代码检索的嵌入模型系列

SFR-Embedding-Code:

https://huggingface.co/Salesforce/SFR-Embedding-Code-400M\_R

https://huggingface.co/Salesforce/SFR-Embedding-Code-2B\_R

代码检索是人工智能领域中一个关键但尚未得到充分探索的领域。虽然文本检索系统在自然语言处理 (NLP) 任务中取得了显著成功,但这些方法在应用于代码时往往不尽如人意。开发人员在检索代码片段时面临着独特的挑战,例如理解语法、控制流和变量依赖关系。SFR -Embedding-Code是一系列开创性的代码嵌入模型,旨在解决这些挑战并彻底改变我们检索和生成代码的方式。

为什么需要检索代码生成?

开发人员通常需要遵循特定项目惯例、处理依赖项或正确与框架集成的代码。代码生成模型可能会产生通用或不完整的结果,无法解决这些细微差别。同时,检索增强生成方法直接从源代码存储库中获取经过测试的真实示例,确保相关性和最佳实践,以实现更强大、更高效的迁移过程。

picture.image

从transformers==3.x迁移到transformers==4.x时,您经常会遇到破坏代码的更改。该图强调,仅生成修复程序是不够的 - 您必须从多个来源检索信息:库的 GitHub PR 和发行说明(了解更改的内容)、您自己的代码库(查找过时的用法)和社区示例(查看推荐的新模式)。

为什么需要使用代码检索而不是文本检索来检索代码?

经过自然语言嵌入训练的基于文本的检索器通常无法捕捉代码的结构和语义细微差别。代码检索需要专门针对代码嵌入训练模型,以理解特定于编程的语法、结构和上下文。

picture.image

基于文本的检索失败,因为它仅适用于二维列表(例如[[1, 2], [3, 4]]),而不适用于任意嵌套(例如[[1, [2, 3]], 4])。基于代码的检索可通过递归适用于任意嵌套列表。

基于文本的检索器关注关键字相似性(例如“flatten”和“list”)和表面级别的匹配,而忽略了代码中更深层的语义关系。

基于代码的检索器理解代码中的语法、逻辑和模式,使其能够检索上下文正确且通用的实现。

SFR-Embedding-Code:Salesforce AI Research 的代码嵌入模型

SFR-Embedding-Code 引入了一系列大规模开源嵌入模型,参数大小从 4 亿到 70 亿不等。这些模型重新定义了代码检索领域的最新技术,在 CoIR 基准测试中比第二好的模型高出 20% 以上。

picture.image

SFR-Embedding-Code 专为代码和文本检索而设计,使其成为跨领域的多功能工具,让我们将其分解为主要亮点:

统一框架:SFR-Embedding-Code 将各种编程任务转换为通用的检索格式。它支持 12 种编程语言和五种检索类别,包括代码到文本、文本到代码和混合任务。

性能提升:利用具有

双向注意力

的 LLM,7B 模型在代码检索方面取得了前所未有的成果,在 CoIR 上树立了新的标杆,同时在文本检索的 BEIR 上保持了有竞争力的性能。

开源:与封闭模型不同,SFR-Embedding-Code 向社区开放,促进透明度和协作。

检索增强生成 (RAG):增强检索可改进代码摘要、完成和问题修复等下游任务,对开发人员来说非常有价值。

可扩展的模型选择: SFR-Embedding-Code 提供多种模型大小,每种都针对不同的用例进行了优化。7B模型旨在实现最高质量,性能卓越,但需要更多的计算资源。400M模型优先考虑效率,提供更快的推理、更低的成本以及在 CPU 上运行的能力。2B模型在质量和效率之间取得平衡 ,为各种应用提供了实用基础。

为了建立有效的代码检索系统,我们利用现有数据集,将其构建成有意义的(查询、文档)对,以进行对比学习。

为了实现

文本到代码检索

,我们利用Text2SQL和代码竞赛任务,将文本描述视为查询,将相应的代码解决方案视为文档。

代码到文本检索

依赖于代码摘要,使用完整代码作为查询,将其简明摘要作为文档。

对于

代码到代码的检索

,我们使用:

代码翻译将一种编程语言(PL A)编写的代码作为查询,将其在另一种语言(PL B)中的等效翻译作为正文档,确保双向学习。

代码克隆检测可识别功能相同但语法不同的代码片段,并将它们重新用于(查询、文档)对,捕获实现中的变化。

代码完成使用给定的代码片段作为查询,并使用下一个逻辑段作为正文档,与开发人员迭代构建代码的方式保持一致。

扩展到

混合代码检索

,我们引入了更多动态的查询文档结构:

代码问题修复将错误报告(查询)与其相应的修复(文档)配对。

代码代理对话使用过去的对话轮次作为查询,并使用下一个预期响应作为文档。

为了进一步增强代码检索功能,我们在同一编程语言中加入了

反面示例

,以确保模型具有更好的泛化能力,并区分相关和不相关的匹配项。通过将这些数据集重新用于结构化的查询-文档对,我们创建了一个强大的检索系统,专门用于高效且有效的代码搜索。

picture.image

在CoIR 基准测试中,SFR-Embedding-Code7B在所有 10 个数据集上的平均得分是目前排名第一的模型,这体现了其通用代码和文本训练的有效性。SFR -Embedding-Code 400M 和 2B等较小的模型也优于同等规模的模型,提供了具有延迟和成本优势的高效替代方案。它们的成功凸显了我们训练方法的稳健性和通用性。

桥接文本和代码

检索

SFR-Embedding-Code的功能远不止处理代码。它的文本检索功能使其成为一款多功能、双重用途的工具,可用于查找特定代码片段的文档、搜索解释或教程,以及将文本和代码见解集成到有凝聚力的解决方案中。

picture.image

与最强大的文本嵌入模型NV-Embed-V2和SFR-V2相比,SFR-Embedding-Code在文本和代码检索数据集上始终以更高的平均分数胜过它们。

解决 GitHub 问题

picture.image

SFR-Embedding-Code 在SWE-Bench Lite上进行了评估,该评估遵循Code-RAG benchmark,它具有 300 个问题数据集,用于修改多个文件以通过测试用例。SFR-Embedding-Code 模型系列的检索质量提高,提高了解决问题的准确性和效率,在标准化 Docker 环境中接近黄金标准性能。


Qodo-Embed-1:State-of-the-Art Code Retrieval With Efficient Code Embedding Models

Qodo-Embed-1:

https://huggingface.co/Qodo/Qodo-Embed-1-1.5B

https://huggingface.co/Qodo/Qodo-Embed-1-7B

Qodo-Embed-1,这是一个新的代码嵌入模型系列,它实现了最先进的性能,同时保持了比现有模型小得多的占用空间。在CoIR 基准测试中(该基准测试衡量模型检索上下文的能力),我们的 1.5B 模型得分为 68.53,超过了更大的 7B 模型。Qodo 的较大模型 Qodo-Embed-1-7B 也优于同等规模的模型,得分为 71.5。

该论文介绍了使用合成数据生成训练代码嵌入模型的方法。

代码嵌入模型的挑战

现有代码嵌入模型的主要挑战在于难以根据自然语言查询准确检索相关代码片段。许多通用嵌入模型(如 OpenAI 的 text-embedding-3-large)专注于语言模式,而不是语法、变量依赖关系、控制流和 API 使用等代码特定元素。这一差距导致搜索结果和代码检索不相关或不精确,而这对于实现AI 编码代理至关重要。

以下是通用嵌入模型不足的典型案例:

查询:当操作偶尔可能失败时,使操作更加可靠

理想情况下,我们希望代码片段能够实现重试或故障安全机制。但是,通用嵌入模型(如 OpenAI 的 text-embedding-3-large)会返回以下代码:

picture.image

查询到代码分数:text-embedding-3-large:[23.33, 37.14](错误地倾向于不相关的代码)

最初,我们通过使用 LLM 为代码片段生成自然语言描述,并使用这些描述和原始代码对代码片段进行索引,解决了语义不匹配的问题。这种双重索引方法使我们的检索系统能够更好地将自然语言查询与相关代码片段对齐,从而显著提高搜索准确性。然而,生成这些描述会带来大量计算开销、增加索引复杂性和增加延迟。

通过使用代码嵌入专用模型,我们可以跳过描述生成步骤而不会牺牲性能。这简化了系统并降低了成本。

合成数据生成

分别基于 Qwen2-1.5b 和 Qwen2-7b 对两个嵌入模型进行了微调,但在获取使模型能够理解编程语言和自然语言所需的训练数据方面遇到了重大挑战。合成数据在这里有所帮助,它通过为现有代码生成自然语言描述来填补空白。

对于 Qodo-Embed-1,我们构建了一个管道,可以自动从 GitHub 抓取开源代码,应用多个过滤步骤来确保质量,然后将合成函数描述和文档字符串注入数据。

picture.image

文档字符串生成

对于缺少文档的功能,我们生成多个风格各异的合成文档字符串,从格式化的文档到简洁的自然语言摘要。

我们用于生成合成文档字符串的提示:

输入:没有文档字符串的 Python 函数或方法。

输出:简洁且信息丰富的文档字符串,描述函数的目的、输入和输出。


                            
Prompt: Generate a detailed docstring for the following function. Include:
                            
A clear description of what the function does
                            
All parameters with their types and descriptions
                            
The return value(s) with type and description
                            
Any exceptions that may be raised
                            
Here is the function: [INPUT FUNCTION HERE] Format the docstring using Google-style docstring format. Be specific about types and ensure the documentation is clear and comprehensive. Provide only the docstring and nothing more
                        

代码查询生成

为了实现代码搜索和检索任务,我们需要改进代码和查询之间的语义对齐,并使用附加上下文扩充文档字符串。我们使用提示来生成与给定代码相对应的自然语言查询:

输入:实现特定功能的代码片段。

输出:开发人员可能用来搜索此功能的自然语言查询。


                            
Prompt:
                            
You are a query generator. Your task is to produce ONLY a brief and concise natural-language search query that developers could use to find similar code solutions. The code snippet to analyze will be provided below.
                            
OUTPUT RULES:
                            
– Generate ONLY the search query.
                            
– No explanations or additional text.
                            
– Length: 10-30 words.
                            
– Use common programming terminology.
                            
– Clearly capture the core functionality of the code.
                            
GOOD EXAMPLES:
                            
[Insert clear and concise examples of good code search queries here.]
                            
BAD EXAMPLES:
                            
[Insert examples of poor-quality queries here.]
                            
INPUT FUNCTION:
                            
[Insert function signature or definition here]
                            
FUNCTION DOCSTRING:
                            
[Insert existing or generated docstring here]
                            
CODE SNIPPET:
                            
[Insert the full code snippet here]
                        

对 Qodo-Embed-1 进行基准测试

CoIR 基准(面向代码的信息检索)是一个标准化评估框架,旨在评估 AI 模型在检索和理解代码方面的表现。它衡量模型在不同编程语言中执行各种代码检索任务的能力。

Qodo-Embed-1-1.5B 在效率和性能之间实现了出色的平衡,尽管规模较小,但其表现却远超其他大型模型。在 CoIR 基准测试中,其得分为 68.53,超过了 OpenAI 的 text-embedding-3-large(65.17)等规模更大的竞争对手,以及 Salesforce 的 SFR-Embedding-2_R(67.41)等类似规模的模型。与此同时,Qodo-Embed-1-7B 得分为 71.5,进一步提高了标准,表现优于类似规模的模型。这种效率使团队能够有效地搜索庞大的代码库,而无需承担高昂的计算或基础设施成本,从而实现更广泛、更实用的部署。


OASIS: Order-Augmented Strategy for Improved Code Search

OASIS:

https://huggingface.co/Kwaipilot/OASIS-code-embedding-1.5B

提出了一种新的代码搜索方法 OASIS(Order-Augmented Strategy for Improved Code Search),旨在改进代码嵌入模型,使其能够更好地理解代码的语义,提高代码检索的准确性。

研究背景

代码搜索任务旨在根据自然语言查询(NL Query)检索最匹配的代码片段,以提高开发者的效率。当前主流的方法是使用代码嵌入(Code Embedding),即将代码和自然语言查询映射到相同的嵌入空间,通过计算向量相似性来实现检索。

目前的代码嵌入模型主要依赖对比学习(Contrastive Learning),其中采用InfoNCE 损失,通过拉近正样本(正确的 NL-代码对)并推远负样本(随机的 NL-代码对)来优化嵌入。然而,由于代码的上下文较为稀疏,仅靠主要的正负样本差异进行训练可能导致模型捕捉不到代码的微妙语义差异。例如,在代码搜索任务中,两个代码片段可能在词汇上高度相似,但在功能上却截然不同。

为了解决这一问题,OASIS 提出了基于顺序增强(Order-Augmented)的策略,通过为负样本赋予细粒度的相似性标签(order labels),引导模型捕捉更细微的代码语义差异,从而提升代码搜索的效果。

OASIS 方法概述

picture.image

OASIS 的核心思想是通过**顺序增强策略(Order-Augmented Strategy)**为负样本赋予更精确的相似性标签,使模型能够识别负样本之间的微妙差异,从而提升代码嵌入的质量。具体而言,OASIS 采用以下三步流程:

  1. 相似性注释(Similarity Annotation)

使用大型语言模型(LLM)为代码生成高质量的 Docstring,将其视为自然语言查询(NL Query)。

在同一代码库内,随机选择其他函数的 Docstring 作为负样本,并为其赋予相似性分数。

  1. 相似性优化(Similarity Refinement)

采用程序分析和 LLM 重新计算负样本的相似性,确保相似性标签的准确性。

通过高斯混合模型(GMM)和抽象语法树(AST)编辑距离,筛选可能被误标的负样本,并调整其相似性分数。

  1. OASIS 训练(Training Process)

结合对比学习(InfoNCE Loss)和顺序学习(Order-Based Loss)**优化代码嵌入模型,使其能够更准确地识别代码之间的细微差异。

实验与结果

训练数据

OASIS 在 GitHub 的53M 代码-文档对(涵盖 9 种编程语言)上进行训练。

评测数据包括:

NL2Code(自然语言到代码检索):CoSQA、AdvTest、CodeSearchNet

Code2Code(代码到代码检索):扩展版 CodeSage 数据集

主要实验结果

OASIS 在 NL2Code 任务上超越所有现有开源和封闭模型:

相比 SOTA 模型(CodeSage-Large),在 CoSQA 数据集上提高 17.34%,在 AdvTest 上提高 8.73%。

相比 OpenAI 的Text-Embedding-3-Large,OASIS 的性能更优,即使 OASIS 使用该模型生成相似性标签。

OASIS 在 Code2Code 任务上的改进更显著:

在所有 9 种编程语言上超越了 CodeSage 和 OpenAI 的闭源模型,平均提升 24.31%。

结论

OASIS 通过顺序增强策略提高了代码嵌入模型的性能,在 NL2Code 和 Code2Code 任务上均刷新了 SOTA 结果。该方法能够更细粒度地区分代码之间的微妙语义差异,为未来的代码搜索和代码理解任务提供了新的方向。


CodeT5+: Open Code Large Language Models for Code Understanding and Generation

CodeT5+:

https://huggingface.co/Salesforce/codet5p-110m-embedding

CodeT5+是一个新的开放代码大语言模型系列,具有编码器-解码器架构,可以灵活地以不同的模式(即仅编码器、仅解码器和编码器-解码器)运行,以支持广泛的代码理解和生成任务。

与原始 CodeT5 系列(基础:220M,大型770M:)相比,CodeT5+ 经过了多种预训练任务的预训练,包括跨度去噪、因果语言建模、对比学习和文本代码匹配,以从单峰代码数据和双峰代码文本数据中学习丰富的表示。此外,它采用了一种简单但有效的计算效率预训练方法,使用冻结的现成 LLM(如CodeGen)初始化模型组件,以有效扩展模型(即2B,,6B) ,并采用“浅编码器和深解码器”架构。此外,它经过指令调整,以与遵循Code Alpaca 的16B自然语言指令保持一致。

主要贡献

多阶段预训练: CodeT5+在两个阶段进行预训练。第一个阶段是单模态预训练,使用大量的代码数据来进行span去噪和因果语言建模。第二阶段是双模态预训练,使用代码和对应文本(如代码注释)对进行跨模态学习,进一步提升模型的理解和生成能力。

预训练目标: 论文提出了一系列的预训练任务,包括span去噪(用于恢复代码中的部分缺失片段)、因果语言建模(用于代码生成任务)以及对比学习和文本-代码匹配任务(用于提高模型在代码理解任务中的表现)。

计算高效的训练方法: 该方法通过使用预训练的现成模型(如CodeGen模型)初始化编码器和解码器,并将解码器冻结,减少了训练过程中需要优化的参数数量,极大地提高了训练效率。

指令调优: 论文还探讨了使用指令调优来提升模型对自然语言指令的理解能力,从而提高在实际开发任务中的应用效果。

实验与结果

人类评估任务(HumanEval): CodeT5+ 16B在零-shot的代码生成任务中达到了35.0%的pass@1和54.5%的pass@10,超越了其他开源代码LLMs,包括OpenAI的code-cushman-001。

数学编程任务: 在MathQA和GSM8K基准上,CodeT5+模型显著超越了许多大规模的语言模型。

代码总结: CodeT5+在代码总结任务上也表现优异,超越了包括UniXcoder在内的多个强大基准模型。

代码完成: 在代码完成任务中,CodeT5+在多个基准上取得了新的SOTA成绩。


更多推荐

picture.image

picture.image

picture.image


picture.image

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
火山引擎大规模机器学习平台架构设计与应用实践
围绕数据加速、模型分布式训练框架建设、大规模异构集群调度、模型开发过程标准化等AI工程化实践,全面分享如何以开发者的极致体验为核心,进行机器学习平台的设计与实现。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论