优化文本嵌入,大幅提升RAG检索速度

大家好,文本嵌入技术能够将文字信息转换成高维向量表示的数字,提供了一种理解和处理文本数据的新方式,帮助我们更好地理解和处理文本数据。这些向量能够捕捉文本的深层特征,进而支持多种应用,比如理解语义、进行文本分类、聚类、信息检索,甚至优化搜索结果排序等。本文将介绍优化文本嵌入方法,据不同的应用需求,灵活调整嵌入向量的维度,大幅提升检索效率。

1.文本嵌入

图片

从输入字符串到句子嵌入

定义一个词汇表,这个表把所有可能输入的字符,包括字母、特殊符号、短词和子词,都映射到整数值。比如:

{"a": 1,"b": 2,"c": 3,..."z": 26,"the": 27," ": 28
}

经过标记化处理后,可以将令牌(token)列表输入到编码器模型中。这个模型经过大量数据的训练,能够将每个令牌转换为高维数值向量嵌入。

例如,OpenAI的text-embedding-3-large模型的嵌入向量输出维度为3072。如果想要获得单个句子嵌入,需要从多个令牌嵌入中提取信息,常见的做法是对所有令牌嵌入求平均值。

2.套娃嵌入

套娃嵌入(Matryoshka Representation Learning)是一种先进的文本表示技术,由华盛顿大学、谷歌研究院和哈佛大学的学者们在2022年发表的论文《Matryoshka Representation Learning》中首次提出。

套娃嵌入技术能够在单一的嵌入向量中嵌入多个层次的信息,它不是只训练一个单一维度为1024的嵌入向量,而是同时优化一组不同大小的维度,如1024、512、256、128、64等。

图片

这样的设计让嵌入向量像套娃一样,外层包含着较为概括的信息,而内层则逐渐包含更细致的信息。这种结构能够在几乎不影响性能的情况下,根据实际需求来调整嵌入向量的长度,从而更好地适应各种不同的应用环境。

3.套娃嵌入的重要性

假设要在向量数据库中存储一大批文本嵌入向量。每个嵌入有 d 个维度,每个维度都是一个32位的浮点数。这样算下来,存储空间就需要n * d * 4 个字节。

如果想要计算这些向量的相似性,如点积或余弦相似性(只是归一化的点积),维度 d 越高,需要做的数学计算量就越多。

图片

点积公式

有了MRL技术,如果我们更看重节省内存和提高处理速度,从而减少成本,可能只取前64个维度来用。如果追求最佳的性能,那就用上所有的维度,当然也可以选择一个折中的维度数。

总的来说,MRL技术让LLM用户能够在嵌入向量的存储成本和性能之间找到一个平衡点。

4.Nomic AI的MRL应用

Nomic的套娃文本嵌入模型nomic-embed-text-v1.5是使用 matryoshka_dims = [768,512,256,128,64] 训练的。该模型在Hugging Face上公开可用。

这个编码器模型还支持多种前缀,比如[search_query, search_document, classification, clustering],这意味着它能针对搜索查询、搜索文档、文本分类和聚类等特定任务,提供更为精准的嵌入结果。

以下是nomic-embed-text-v1.5在大规模文本嵌入基准(MTEB)上的表现:

图片

使用PyTorch和Sentence Transformers库在Python中实现该模型:

!pip install torch sentence_transformers einopsimport torch
from sentence_transformers import SentenceTransformermodel = SentenceTransformer("nomic-ai/nomic-embed-text-v1.5",device=device,trust_remote_code=True,prompts={"search_query": "search_query: ","search_document": "search_document: ","classification": "classification: ","clustering": "clustering: ",},
)def embed_sentences(model: SentenceTransformer,sentences: list[str],prompt_name: str,matryoshka_dim: int,device: str,
):assert matryoshka_dim <= 768, "maximum dimension for nomic-embed-text-v1.5 is 768"embeddings = model.encode(sentences, prompt_name=prompt_name, device=device, convert_to_tensor=True)embeddings = torch.nn.functional.layer_norm(embeddings, normalized_shape=(embeddings.shape[1],))embeddings = embeddings[:, :matryoshka_dim]embeddings = torch.nn.functional.normalize(embeddings, p=2, dim=1)return embeddings.cpu()

使用 matryoshka_dim 参数,可以将原本768维的嵌入向量进行截断,然后归一化新的嵌入向量。

现在,可以设置期望的维度,对维基百科上的一些文本内容以及相关问题进行编码,以供检索增强生成(RAG)的应用场景使用:

matryoshka_dim = 64wikipedia_texts = ["The dog (Canis familiaris or Canis lupus familiaris) is a domesticated descendant of the wolf.","Albert Einstein was born in Ulm in the Kingdom of Württemberg in the German Empire, on 14 March 1879.","Einstein excelled at physics and mathematics from an early age, and soon acquired the mathematical expertise normally only found in a child several years his senior.","Werner Karl Heisenberg was a German theoretical physicist, one of the main pioneers of the theory of quantum mechanics, and a principal scientist in the Nazi nuclear weapons program during World War II.","Steven Paul Jobs (February 24, 1955 - October 5, 2011) was an American businessman, inventor, and investor best known for co-founding the technology giant Apple Inc.","The cat (Felis catus), commonly referred to as the domestic cat or house cat, is the only domesticated species in the family Felidae.",
]question = ["Where was Albert Einstein born?"]question_embedding = embed_sentences(model,sentences=question,prompt_name="search_query",matryoshka_dim=matryoshka_dim,device=device,
)document_embeddings = embed_sentences(model,sentences=wikipedia_texts,prompt_name="search_document",matryoshka_dim=matryoshka_dim,device=device,
)
print(f"document_embeddings.shape: {document_embeddings.shape}")
print(f"question_embedding.shape:  {question_embedding.shape}")
>> document_embeddings.shape: torch.Size([6, 64])
>> question_embedding.shape:  torch.Size([1, 64])

可以用散点图可视化套娃文本嵌入的前两个维度,不过需要注意的是,这个嵌入模型并没有专门针对二维展示进行优化。

图片

将文档嵌入存储在向量数据库中,这里使用的是Faiss。Faiss是Meta Research的开源库,用于高效相似性搜索和密集向量的聚类。

!pip install faiss-cpu
import faiss
index = faiss.IndexFlatIP(matryoshka_dim)
index.add(document_embeddings)

通过“精确搜索内积”的方法,构建一个名为IndexFlatIP的向量数据库,它使用的是点积相似性度量。因为使用的嵌入向量已经过归一化处理,所以点积和余弦相似性在这种情况下是等价的。

index 现在是一个包含六个文本嵌入的向量数据库:

print(index.ntotal)
>> 6

搜索与我们的问题最相似的嵌入,并检索前k个结果:

distances, indices = index.search(question_embedding, k=6)
print(indices)
print(distances)
>> [[1 2 3 4 0 5]]
>> [[0.9633528  0.729192   0.63353264 0.62068397 0.512541   0.43155164]]

最相似的文本在数据库中的索引是1,相似性得分为0.96(最高是1.0)。

# results with d=64
print(question)
print(wikipedia_texts[1])
>> ['Where was Albert Einstein born?']
>> 'Albert Einstein was born in Ulm in the Kingdom of Württemberg in the German Empire, on 14 March 1879.'

这里也用matryoshka_dim=768重新运行了代码,得到了类似的结果,然而更高的维度需要更多的内存和更多的计算。

# results with d=768
print(indices)
print(distances)
>> [[1 2 4 3 0 5]]
>> [[0.92466116 0.645744   0.54405797 0.54004824 0.39331824 0.37972206]]

5.MRL&量化

如果想要进一步压缩我们的嵌入,可以使用MRL和二进制向量量化。二进制量化将嵌入向量中所有大于零的数字转换为一,其余的转换为零。

图片

使用二进制量化,一个维度为 d 的嵌入向量只需要 d / 8 字节的内存,这比32位浮点数的 d * 4 字节减少了32倍,然而这种减少是以性能为代价的。

在训练过程中,嵌入模型采用了套娃损失函数,以优化多个嵌入维度。通过套娃表示学习,LLM用户可以在减少文本嵌入大小和接受轻微性能损失之间进行权衡。

较小的嵌入向量占用的内存更少,计算量也更小,长期来看有助于节省成本。同时,它们的计算速度也更快,因此具有更高的检索速度,这对于像RAG这样的应用程序来说尤其重要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/3291.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【通信领域术语】MNO 和 MVNO 的简介

定义与关系 MNO 和 MVNO 是两种不同类型的移动运营商。 MNO(Mobile Network Operator,移动网络运营商)指利用物理网络基础设施提供移动服务的一种移动服务提供商。 MVNO(Mobile Virtual Network Operator,虚拟移动网络运营商)不拥有网络基础设施。 两者最大的区别在于,…

868历年真题算法设计题+程序设计题

11.52013年真题*4 一天四道太顶了&#xff0c;11.6-11.15先且两天四道题&#xff0c;先把数学二轮三轮结束&#xff01; 如果程序设计题写不了 核心算法 &#xff0c;但是把思路写上去&#xff0c;只将核心函数空出来也能拿些分&#xff01;&#xff01;DFS大概率不会和stack同…

仿制药一致性评价数据库之药品一致性评价查询

在《我不是药神》电影中&#xff0c;白血病特效药“格列宁”原研药与印度仿制药价格相差近10倍&#xff0c;在仿制药生物等效达到99%以上情况下&#xff0c;你会如何抉择&#xff1f;即便在如今的美国&#xff0c;仿制药也占据了90%以上的用药市场。 正如《仿制药的真相》书中…

【JS学习】08. web API-事件进阶

Web APIs - 第3天 进一步学习 事件进阶&#xff0c;实现更多交互的网页特效&#xff0c;结合事件流的特征优化事件执行的效率 掌握阻止事件冒泡的方法理解事件委托的实现原理 事件流 事件流是对事件执行过程的描述&#xff0c;了解事件的执行过程有助于加深对事件的理解&…

Spring Validation数据校检

文章目录 Spring Validation1 关于Spring Validation2 使用流程3 快速入门4 运行异常处理4.1 说明4.2 处理异常4.3 明确提示消息 5 常用注解5.1 NotNull注解5.2 NotEmpty 注解5.3 NotBlank 注解5.4 Size 注解5.5 Range 注解 6 非POJO参数校验6.1 使用流程6.2 使用示例 Spring V…

Node.js 全栈开发进阶篇

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;node.js篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来node.js篇专栏内容:node.js- 全栈开发进阶篇 前言 大家好&#xff0c;我是青山。在上一篇文章中&#xff0c;…

实战| 使用深度学习分割和计算水体和农田面积【Pytorch附源码】

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发…

虚拟机 Ubuntu 扩容

文章目录 一、Vmware 重新分配 Ubuntu 空间二、Ubuntu 扩容分区 一、Vmware 重新分配 Ubuntu 空间 先打开 Vmware &#xff0c;选择要重新分配空间的虚拟机 点击 编辑虚拟机设置 &#xff0c;再点击 硬盘 &#xff0c;再点击 扩展 选择预计扩展的空间&#xff0c;然后点击 扩展…

Mybatis的高级用法

MybatisPlus 实体类注释字段 TableName&#xff08;“数据库表名”&#xff09; TableId&#xff08;“主键名”&#xff09; TableField&#xff08;“字段名”&#xff09; BaseMapper接口对象方法 普通查询 1、主键 T selectById(Serializable id) 使用场景为通过主…

excel表格加锁忘密码怎么解决?

百度好多方法都无效&#xff0c;下面方法可行&#xff1a; 点击sheet单元格名称&#xff0c;鼠标右边出现弹框选择“查看代码”&#xff1a; 出现的框中输入以下代码: Sub demo()// 锁定当前工作表&#xff0c;允许筛选操作ActiveSheet.Protect DrawingObjects:True, CONTENT…

Vue中ref、reactive、toRef、toRefs的区别

一、ref、reactive setup 函数中默认定义的变量并不是响应式的&#xff08;即数据变了以后页面不会跟着变&#xff09;&#xff0c;如果想让变量变为响应式的变量&#xff0c;需要使用 ref 和 reactive 函数修饰变量。 ref 函数可以把基本类型变量变为响应式引用reactive 函数…

PDF全能免费转换 3.18 | 免费PDF工具集,多种转换和美化功能

PDF全能免费转换是一款主打免费好用的PDF工具集&#xff0c;功能丰富且实用。主要功能包括&#xff1a;PDF转Word/PPT/Excel/TXT/图片&#xff0c;PDF压缩和合并&#xff0c;多图合并成长图或PDF&#xff0c;身份证扫描、文件扫描、证件扫描&#xff0c;证件照换底色&#xff0…

DICOM标准:DICOM标准中的公用模块、核心模块详解(一)——病人、研究、序列、参考帧和设备模块属性详解

目录 概述 1 公用病人IE模块 1.1 病人模块 2 公用的研究IE模块 2.1 常规研究模块 2.2 病人研究模块 3 公用序列IE模块 3.1 常规序列模块 3.1.1 常规序列属性描述 4 公用参考帧信息实体模块 4.1 参考帧模块 4.1.1 参考帧属性描述 5 公用设备IE模块 5.1 常规设备模…

Webpack 配置module.css报错Uncaught TypeError: Cannot read properties of undefined

我的项目结构如下: 入口文件是index.jsx&#xff0c;组件Button.jsx使用了样式button.module.css .btn {background-color: #4CAF50;border: none;color: white; padding: 15px 32px;text-align: center;text-decoration: none;display: inline-block;font-size: 16px;margin:…

PyCharm中pylint安装与使用

目录 1. 安装插件2. pycharm中使用该功能3. 命令行使用 1. 安装插件 然后重启 2. pycharm中使用该功能 3. 命令行使用 前提是先 pip install pylint pylint demo01.py下面红框内容的意思是&#xff0c;得到10分/ 满分10分&#xff0c;上次运行获得8.33分&#xff0c;经调整…

无人机避障——大疆与Airsim中的角速度信息订阅获取

本文先将Airsim仿真中的角速度信息获取弄好&#xff0c;然后再将大疆SDK中的角速度话题订阅一下&#xff0c;并验证获取角速度信息&#xff0c;后续为DWA动态窗口法替代PID作为局部路径规划做足准备。 Airsim中的角速度信息获取 Airsim无人机状态获取&#xff1a;getMultirot…

绿宝石二十载:如何打破国外在高端电容市场的垄断?

【哔哥哔特导读】作为本土电容器企业&#xff0c;绿宝石凭借二十年的技术创新与市场深耕&#xff0c;在高端电容市场取得了显著突破。从铝电解电容器到叠层式固态电容器&#xff0c;绿宝石是如何做到的&#xff1f; 在当今竞争激烈的电子元器件市场中&#xff0c;技术创新、定…

JS中DOM和BOM

DOM DOM&#xff08;文档对象模型&#xff09;是一个跨平台和语言独立的接口&#xff0c;它允许程序和脚本动态地访问和更新文档的内容、结构和样式。在网页浏览器中&#xff0c;DOM 通常表示 HTML 或 XML 文档的对象模型。DOM 将网页内容视为节点树&#xff0c;其中每个节点都…

从配置anaconda到配置pycharm

Anaconda 是全球领先的数据科学与机器学习平台&#xff0c;专为开发者、数据分析师设计。通过 Anaconda&#xff0c;可以轻松管理数据环境、安装依赖包&#xff0c;快速启动数据分析、机器学习项目。 丰富的 Python 数据科学库&#xff1a;Anaconda 集成了常用的 Python 数据科…

JAVA开源项目 影城管理系统 计算机毕业设计

本文项目编号 T 045 &#xff0c;文末自助获取源码 \color{red}{T045&#xff0c;文末自助获取源码} T045&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 用…