知识库检索匹配的服务化实践

文章详细描述了使用Milvus进行向量召回和文本向量计算的模型,涉及双塔召回模型、InfoNCE算法、精排序以及工程实现中的性能优化策略,包括QPS和响应时间的管理。文章还介绍了Milvus在知识库检索中的关键技术和生态优势。
摘要由CSDN通过智能技术生成

参考:有赞技术|知识库检索匹配的服务化实践 - AIQ (6aiq.com)

 向量召回

向量召回的思想就是计算检索词的向量和文档标题/相似问的向量的余弦相似度,返回相似度分数最高的TopK个文档,计算向量相似度的步骤放在Milvus进行,Milvus作为向量检索库,对计算过程有优化,性能更好。

向量计算模型结构:

文本转向量的算法模型由embedding、两层transformer和MLP组成,模型最后会对编码向量做L2归一化,采用典型的双塔模式,可以将左塔的检索词和右塔的文档标题形成独立的子网络,左右塔的结构分离但编码器参数共享,双塔结构天然的可以用于召回,将这个模型部署到小盒子就可以在线计算检索词的向量,将海量的知识库文档作为右塔离线训练成文本向量后刷入向量检索工具Milvus。

双塔召回模型的核心思想是将query/item嵌入到共享低维空间,然后通过向量距离来度量相关性。

工程实现部分的DP离线任务中实现了计算文档标题和相似问向量并将其导入Milvus的功能。由于Milvus对string类型属性信息存储检索不够友好,会在DB阶段会请求mysql库表对召回结果进行扩展,匹配补全相关信息。

3.4 精排序

经过召回和粗排后,可以理解为将重要相关的文档排在了前面,但是距离用户真正的检索意图还有差距,可以使用用户的检索记录对结果再进行排序。

基于所有场景的用户检索点击数据,有点击行为就认为检索词和文档标题匹配(正样本),其他就认为没有那么匹配(负样本)。

训练数据样例:

采用 in_batch 负采样就不需要提前构造负样本,模型的设计如下:

检索词与正负样本的相似度会进入InfoNCE(info Noise Contrastive Estimation,噪声对比估计)的函数计算损失,使用这个损失来更新模型参数。这个由很多负样本组成的双塔结构也称为对比学习,核心思想是去拉近相似的样本,推开不相似的样本,目标是要从样本中学习到一个好的语义表示空间。

精排模型与文本转向量的算法原理相同。

InfoNCE计算公式:(可以理解为带温度超参的CrossEntropy)

分子是正例对的相似度,分母是正例对+所有负例对的相似度,最小化infoNCE loss,就是最大化正例对的相似度,最小化负例对的相似度。

在计算损失时,label可以在batch内生成,检索词和文档的编码向量经过矩阵乘法可以得到一个相似度方阵,对角位置就是互相匹配的检索词和文档的分数,如果batch_size=4,那每行对应的label就是 [0,1,2,3]。in_batch负采样损失计算示意图:

模型训练好以后,就得到文本的编码器,输入两个文本,就可以得到一个匹配的分数,将这个模型部署到小盒子,在需要排序时,输入候选的文档标题和检索词,按计算出来的分数从高到低排序,就完成了一次对检索结果的排序。

您提到的“RT”和“QPS”分别可能代表以下含义:

  • RT(Response Time):响应时间,通常是指系统从接收到请求到返回响应所需的时间。为了降低响应时间以优化用户体验,可以采取的方法包括但不限于:提高服务器性能、采用缓存技术、优化数据库查询、负载均衡、异步处理等。

  • QPS(Queries Per Second):每秒查询数,是衡量系统处理能力的一个重要指标。要解决高并发场景下的QPS问题,可以考虑以下策略:

    • 水平扩展:增加服务器数量以分摊请求压力。
    • 垂直扩展:提升单个服务器的硬件配置,如CPU、内存和磁盘I/O能力。
    • 数据库优化:使用读写分离、分库分表、索引优化等手段提高数据库性能。
    • 缓存技术:利用Redis、Memcached等缓存系统减少对数据库的直接访问。
    • 异步处理和消息队列:对于非实时任务,可以引入消息队列进行解耦和异步处理,减轻服务器瞬时压力。
    • 使用高性能框架和服务:选择支持高并发的开发框架,并合理设计服务架构,比如微服务架构。

通过以上方法的综合运用,可以有效改善系统的响应时间和处理请求的能力,从而解决RT和QPS问题。

四、工程实现

当线上接受一条检索请求文本后,先调用在线推理-小盒子计算Query向量,然后去Milvus向量库中和知识库向量进行相似度计算,并返回距离最近的Top N个Item作为向量召回的结果。

4.1 离线训练(DP平台)

海量的知识语料库向量化计算在自研DP平台离线运行,使得全库文本匹配速度较快

  • 语料库预处理:包括语料库的文本清洗、文本筛选等预处理逻辑
  • 语料库向量化:利用上述的向量计算模型进行向量化
  • 导入Milvus库:将集合部署在Milvus集群,依次批量导入更新机器的集合保证线上可用

4.2 在线推理(Sunfish平台)

自研算法平台(Sunfish)对模型训练提供一站式闭环服务,支持分布式训练、GPU/CPU切换、模型版本管理、一键式运行和部署等功能,其中:

  • 算法工程模块:一键运行训练、任务作业管理、模型输出
  • 模型管理模块:实现训练任务、地址导入、本地上传等多途径模型来源选择
  • 模型部署模块:简单配置、模型格式选择、线上资源配置等便捷署方式

4.3 Milvus向量检索

Milvus 是一款开源的、针对海量特征向量的向量相似性检索(ANNS,Approximately nearest neighbor search)引擎,集成了 Faiss、Annoy 等广泛应用的向量索引,成本更低、性能更好、高度灵活、稳定可靠以及高速查询等特点,十亿向量检索仅毫秒响应。

1、Milvus向量索引列表如下:

简言之,每种索引都有自己的适用场景,如何选择合适的索引可以简单遵循如下原则:

  • 当查询数据规模小,且需要 100%查询召回率时,用 FLAT;
  • 当需要高性能查询,且要求召回率尽可能高时,用 IVF_FLAT;
  • 当需要高性能查询,且磁盘、内存、显存资源有限时,用 IVFSQ8H;
  • 当需要高性能查询,且磁盘、内存资源有限,且只有 CPU 资源时,用 IVFSQ8。

2、Milvus 目前支持的距离计算方式与数据格式、索引类型之间的兼容关系

选择合适的距离计算方式比较向量间的距离,能很大程度地提高数据分类和聚类性能,主要采用内积 (IP)的计算方式,内积更适合计算向量的方向。

内积计算两条向量之间的夹角余弦,并返回相应的点积。内积距离的计算公式为:

假设有 A 和 B 两条向量,则 ||A|| 与 ||B|| 分别代表 A 和 B 归一化后的值。cosθ 代表 A 与 B 之间的余弦夹角。

在向量归一化之后,内积与余弦相似度等价。因此 Milvus 并没有单独提供余弦相似度作为向量距离计算方式。

4.4 算法接口服务

算法模型接口服务由ai-service和ai-app两个服务组成,ai-service负责调用算法模型在线推理、Milvus实时向量召回等接入库,ai-app负责业务逻辑的开发。

2、ai-app接口设计

实现业务逻辑开发测试后,发布上线即可提供前后端调用。

单从查询来说,用户会有 topk 向量的查询,有向量距离在某个范围内的查询,还会有根据属性过滤数据的需求,且对于向量距离的计算方式有 IP、Cosine 等多种计算需求,以及通过迭代器的方式批量获取数据等。此外,用户对于 QPS、稳定性、索引多样、写入等方面还有各种需求,举个例子,对于写入来说,存在实时写入、更新、批量导入、批量快速删除等诉求。

Milvus 在 2.3.x 中为上述场景增强了 API,满足了用户不同场景下的快速开发需求。例如 upsert 功能,我们能为用户提供 insert 或 update 的功能,在用户有数据覆盖的需求时,仅需一行代码即可满足需求,不需要进行查询、检查、再写入这些繁琐步骤。又例如 ScaNN 索引,我们为用户在 HNSW 之外提供了性能更强劲的索引。

基础概念

标量:无向量,只有数值大小没有方向
向量:区别于具体的单维度数值标量,可以认为是一条线,有多个数值表示。嵌入向量Embedding Vector是非结构化数据的特征抽象,例如电子邮件、物联网传感器数据、Instagram照片、蛋白质结构等等。从数学上讲,嵌入向量是一个浮点数数组或二进制数组。
向量范数:向量范数是指向量的大小或长度,计算向量范式可以用来衡量向量的大小、相似度等。计算方式分为
L1:曼哈顿范数,将向量元素绝对值相加之和
L2:欧几里得范数,将向量元素的平房和开更号
向量归一化:对向量进行归一化操作,以确保不同维度上的特征权重相等,避免某些维度对结果产生较大影响。可以采用L1、L2归一化,一种常用的归一化方法是使用 L2 范数进行单位化处理,即将向量除以其 L2 范数得到单位向量。
向量内积:点积、数量积,两个向量的点积就是吧对应位置元素点积之和,对于某个位置元素的点积a · b = |a|·|b|·cos v。其中||表示向量范数。点乘的几何意义是可以用来表征或计算两个向量之间的夹角,以及在b向量在a向量方向上的投影。
向量外积:外积(英语:Outer product),在线性代数中一般指两个向量的张量积,其结果为一矩阵;与外积相对,向量的外积是矩阵的克罗内克积的特殊情况。
余弦相似度:向量之间的夹角的余弦值,范围为[-1,1],越接近1表示两个向量越来约相似。

参考:https://blog.csdn.net/qq_24654501/article/details/134495870

数据模型相关概念

Bitset:位图集合
Channel:有两个不同的Channel在Milvus。它们是PChannel和VChannel。
每个PChannel对应一个日志存储主题。PChannel是物理Channel。每个PChannel对应一个日志存储主题。当Milvus集群启动时,默认情况下将分配一组256个PChannels来存储记录数据插入、删除和更新的日志。
每个VChannel对应于集合中的一个分片。VChannel代表逻辑信道。每个VChannel代表集合中的一个分片。每个集合将被分配一组VChannels,用于记录数据插入、删除和更新。VChannel在逻辑上是分离的,但在物理上共享资源。
Collection:数据实体集合,类比表
Schema:集合模式,模式是定义数据类型和数据属性的Meta信息。每个集合都有自己的集合模式,该模式定义集合的所有字段、自动ID(主键)分配启用和集合描述。集合架构中还包括定义字段的名称、数据类型和其他属性的字段架构。
Entity:数据实体,每个实体会有一个主键。
Field:数据字段,类型可以是数字、字符串、向量等结构化数据。
Normalization:归一化,归一化是指转换嵌入(向量)以使其范数等于1的过程。如果使用内积(IP)来计算嵌入相似度,则所有嵌入都必须归一化。归一化后,内积等于余弦相似度。
Vector index:向量索引是从原始数据中派生出来的重组数据结构,可以大大加速向量相似性搜索的过程。Milvus支持多种向量索引类型。
Vector similarity search:向量相似性搜索是将向量与数据库进行比较以找到与目标搜索向量最相似的向量的过程。近似最近邻(ANN)搜索算法用于计算向量之间的相似性。

系统设计概念,作为云原生矢量数据库,Milvus通过设计将存储和计算分离。为了增强弹性和灵活性,Milvus中的所有组件都是无状态的。

接入层:提供访问的API
协调服务:大脑,将任务分配给工作节点
工作节点:四肢,执行大脑下发的DML命令
存储服务:骨骼,负责数据持久化。它包括Meta存储、日志代理和对象存储。

相关概念

Message storage:消息存储是Milvus的日志存储引擎。
Dependency:其他依赖,Milvus的依赖项包括etcd(存储Meta数据),MinIO或S3(对象存储)和Pulsar(管理快照日志)。
Milvus cluster:在Milvus的集群部署中,服务由一组节点提供,以实现高可用性和易扩展性。
Partition:分区是集合的物理划分。Milvus支持将收集数据划分为物理存储上的多个部分。这个过程称为分区,每个分区可以包含多个段。
Segment:段是由Milvus自动创建的用于保存插入数据的数据文件。一个集合可以有多个段,一个段可以有多个实体。在向量相似性搜索期间,Milvus扫描每个片段并返回搜索结果。段可以是增长的,也可以是密封的。一个不断增长的段不断接收新插入的数据,直到它被密封。密封的段不再接收任何新数据,并将被刷新到对象存储中,留下新数据插入到新创建的增长段中。增长段将被密封,因为它持有的实体数量达到预定义的阈值,或者因为“增长”状态的跨度超过指定的限制。
Sharding:分片是指将写操作分配到不同的节点(一个节点可以存储多个分区),以充分利用Milvus集群的并行计算潜力来写数据。默认情况下,单个集合包含两个分片。Milvus采用基于主键哈希的分片方法。Milvus的开发路线图包括支持更灵活的分片方法,如随机和自定义分片。

日志相关概念

Log Broker:日志代理,支持回放的系统,负责流数据持久化、可靠的异步查询、事件通知和返回查询结果以及当工作节点故障恢复后增量数据的完整性。
Log sequence:日志序列,记录更改集合状态的所有操作。
Log snapshot:日志快照,二进制日志,一个较小的段单元,记录和处理对Milvus矢量数据库中数据的更新和更改。来自一个段的数据被持久化在多个binlog中。Milvus中有三种类型的binlog:InsertBinlog、DeleteBinlog和DDLBinlog。
Log subscriber:日志订阅者订阅日志序列以更新本地数据,并以只读副本的形式提供服务。

使用流程
创建数据库:与传统的数据库引擎类似,您也可以在Milvus中创建数据库,并将权限分配给某些用户来管理它们。然后,这些用户有权管理数据库中的集合。Milvus集群最多支持64个数据库。默认存在数据库default。
创建集合:集合由一个或多个分区组成。在创建新集合时,如果不指定分区数,Milvus会创建一个默认的partition分区_default。创建集合之前需要指定元数据,支持为标量设置默认值。创建集合可以指定分片数量,相比分区,分区通过指定分区名称来减少读取负载,而分片在多个服务器之间分散写入负载。
创建索引:需要指定为某向量字段、普通标量创建索引的类型(标量默认索引类型为字典树),额外参数传入聚类参数nlist。比如IVF_FLAT索引将向量数据划分为nlist聚类单元,然后比较目标输入向量与每个聚类中心之间的距离。根据系统设置为查询的聚类数(nprobe),仅基于目标输入和最相似聚类中的向量之间的比较返回相似性搜索结果-大大减少查询时间。
加载集合:将集合、集合分区加载进内存,Milvus2.1允许用户将集合按照分区加载为多个副本,以利用额外查询节点的CPU和内存资源。此功能可提高整体QPS和吞吐量,无需额外硬件。
插入数据:可以指定partition_name将数据插入指定分区,可以将文件中的实体数据插入集合,支持manualCompaction手动压缩数据
搜索数据:根据创建的向量索引以及指定的相似度度量参数(IP、L2等)来进行相似性索引、标量搜素。

数据字段类型

动态数据类型

为了使Milvus插入数据更加灵活,对于之前创建的集合可以指定动态元数据模式。
动态模式使用户能够将具有新字段的实体插入到Milvus集合中,而无需修改现有模式。这意味着用户可以在不知道集合的完整架构的情况下插入数据,并且可以包括尚未定义的字段。

索引类型
ANN紧邻搜索的索引实现的几种方式

Tree-based index
Graph-based index
Hash-based index
Quantization-based index
在Milvus中根据数据类型将向量索引种类分为

内存索引
浮点嵌入索引
二进制嵌入索引
标量前缀索引
磁盘索引:默认启用DiskANN,可选择关闭。

聚类近似搜索
其中IVF_FLAT、IVF_SQ8、IVF_PQ、BIN_FLAT等索引创建的时候支持 nlist,查询时候支持nporbe参数,将向量数据划分为nlist聚类单元,然后比较目标输入向量与每个聚类中心之间的距离。根据系统设置为查询的聚类数(nprobe),仅基于目标输入和最相似聚类中的向量之间的比较返回相似性搜索结果-大大减少查询时间。

聚类单元是指进行聚类分析时,将数据点划分为不同的簇或群组的基本单位。每个聚类单元代表一个特定的数据集合,其内部的数据点在某种程度上相似。聚类算法通过计算各个数据点之间的距离或相似性来确定如何将它们分配到不同的聚类单元中。

聚类单元可以用于对数据进行分类、识别隐藏的模式和结构,并产生有关数据集的洞察力。利用聚类单元可以将复杂的数据集简化为更易理解和解释的形式,同时可作为进一步分析、预测和决策制定的基础。

相似度量规则

代码demo

具体的API参考官网文档下面举例向量+标量的混合搜索demo

 3.5 选择Milvus的理由

  高性能:性能高超,可对海量数据集进行向量相似度检索。Milvus不但集成了业界成熟的向量搜索技术如Faiss和SPTAG,Milvus也实现了高效的NSG图索引。同时,Milvus团队针对Faiss IVF索引进行了深度优化,实现了CPU与多GPU的融合计算,大幅提高了向量搜索性能。Milvus可以在单机环境下完成SIFT1b十亿级向量搜索任务。高可用、高可靠:Milvus支持在云上扩展,其容灾能力能够保证服务高可用。混合查询:Milvus支持在向量相似度检索过程中进行标量字段过滤,实现混合查询。开发者友好:支持多语言、多工具的Milvus生态系统。Milvus提供了向量数据管理服务,以及集成的应用开发SDK(Java/Python/C++/RESTful API)。相比直接调用Faiss和SPTAG那样的程序库,Milvus开发使用更便捷,数据管理更简单。

  • 22
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值