向量检索-faiss检索

article/2025/9/12 20:35:25

一、语义相似检索背景

1、为什么引入语义相似检索(向量检索)

问题引出 搜索引擎和搜索广告最难解决的问题是语义相似度

                   具体体现:召回和排序

 

Case1: "从北京到上海的机票""携程网"相似性

Case2"快递软件""菜鸟裹裹"相似性

 

2、语义相似度==向量检索?

   语义相似度包含:

  • 深度学习模型
  •  向量检索工程化实现

 

3、补充关键字召回率(倒排拉链截断)

  • 关键字召回可能存在拉链后面的长期得不到召回
  • 相关性强依赖Rwt模块分词的关键词匹配 

4、 语义相似度的关键点

(1).深度学习模型

      DSSM Deep Structured Semantic Models

      CNN-DSSM(CLSM  convolutional latent semantic model /CNN-DSSM)

      LSTM-DSSM(Long-Short-Term Memory)

(2)  向量工程化实现

  • Faiss:索引库
  • Annoy: 树模型
  • HNSW: 紧密图
  • Milvus 服务引擎
  • Vearch京东服务引擎
  • NSG
总体流程如下:

5、 Faiss索引库

向量索引需要解决的问题:

  • 高维向量距离计算
  • 高维向量的内存存储

名词解释:

  • 查询向量:用户的查询向量
  • 聚类中心向量(中心向量):在向量集合中训练出来的聚类向量,其实也是向量集合中的点
  • 样本向量: 聚类中心倒排拉链的向量集合
  • SDC(symmetric distance computation) 对称求距离
  • ADC(asymmetric distance computation) 非对称求距离
向量的内存压缩

      举例: d = 128维向量向量维度float 4个字节

                  3000w向量  3000*10000*128*4 = 14G内存(目前似乎我们不压缩也可以)

                   d = 512维向量56G内存

 

     乘积量化(Product Quantization

      量指的就是将一个空间划分为多个区域,然后为每个区域编码标识

      乘积的是高维空间可以看作是由多个低维空间相乘得到的

乘积量化(Product Quantization

举例:

       (1)假设1024维度的向量;分4段,每段256维,比如ABCD;

       (2)每段256维,针对每段使用256个聚类中心编号

       (3)每个聚类中心向量是256维的浮点数,256 * 4 =1024个字节

       (4)一共有256 * 4 = 1024个聚类中心向量

因此,一个 1024 维的原始浮点数向量(共 1024 * 4 字节)使用乘积量化压缩后,存储空间变为了 32 个比特

二、faiss索引库&向量化落地

 

1、Faiss从典型Case说起

Case: IndexIVFPQ + IndexFlatL2

 

2、Faiss索引库训练

(1)首先构造一级量化器(粗糙量化器)

faiss::IndexFlatL2 coarse_quantizer (d);默认构造的是L2距离;

目的:为了把向量空间的向量第一次分堆,在查询的时候能够根据到中心点距离迅速过滤掉大部分向量,加速查询,一级量化器目前测试发现最快的是HNSW索引图方式搜索

(2)构造二级量化器

faiss::IndexIVFPQ index (&coarse_quantizer, d,  ncentroids, 4, 8);

目的为了查询聚类中心的向量,返回topk;二级量化器传入的一个一级量化器,一级量化器的目的是在查询的时候快速定位的聚类中心,查询的时候也是先查询一级量化器,再查询二级量化器

 

(3)数据集问题

         在训练量化器之前,需要构建一个向量集合,以1500w向量为例,比如128维,需要申请内存1500*10000*128*4 = 7324M,大概需要7G内存注意我们插入向量的顺序就是召回向量的id,这个是一一对应的;

目前训练的时候是全部放内存的需要,所以需要提前计算好向量的维度,向量的数量,需要的机器内存大小等

3、Faiss 一级量化器训练

(1) 首先构造一级量化器(粗糙量化器)

入口函数Level1Quantizer::train_q1 (…)

  •  K是聚类中心的数量,常规设置总向量的平方根
  • max_points_per_centroid 255默认值

(2) Faiss 二级量化器训练

入口函数IndexIVFPQ::train_residual (idx_t n, const float *x)

从总向量 x 集合中随机选择 65536 pq.cp.max_points_per_centroid * pq.ksub   = 65536     Xslice是 65536 个向量集合,维度是 32
计算残差是计算的 65536 个向量与一级量化器的聚类中心的距离,   quantizer -> assign ( n , x , assign ) ; 这个函数是查询 65536 个向量,   

      assign返回的是n个聚类中心向量,里面可以有重复的中心向量残差可以看做是以一级量化器的为中心点的坐标系下各个向量表示,

      如下图:

(3)Faiss 二级量化器计算残差

计算残差就是向量的各个维度和距离中心的差值

 

(4) Faiss索引磁盘

数据下盘void write_index (const Index *idx, IOWriter *writer);

先写IndexIVFPQ * ivpq这种类型的索引,在write_ivf_header函数循环调用写了一级量化器的索引

 

4、Faiss向量的add流程

Faiss Add流程其实是把向量集合添加到向量中心的倒排拉链中

 

5、Faiss向量编码

(1)向量距离计算

 

6、 Faiss向量检索流程

(1) 先查询一级量化器

查询以及量化器的目的是找到nprobe个聚类中心的

(2) 级量化器查询

     扫描器类型IVFPQScanner

(3)  Faiss  级量化器查询步骤

距离计算

我们查询距离是非对称方法,第二张图,

SDC算法:先用PQ量化器对xy表示为对应的中心点q(x)q(y),然后用公式1来近似d(x,y)

ADC算法:只对y表示为对应的中心点q(y),然后用公式2来近似d(x,y)

参考文献:http://vividfree.github.io/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/2017/08/05/understanding-product-quantization

(4) Faiss向量检索整体流程示意图

 

(5) Faiss  级量化器查询核心函数

匿名函数init_result

这个函数是为了获取结果Topk,其中处理的是一个堆数据结构

 匿名函数scan_one_list 扫描一个聚类中心的倒排拉链,并把数据使用堆排序返回TopK

 

(6)Faiss  级量化器查询步骤1

   首先创建一个扫描器InvertedListScanner *scanner在本例中是IVFPQScanner类型   

   扫描器设置查询向量query,其实这个时候已经开始计算跟所有中心向量的距离

   扫描聚类中心节点列表

   根据中心点去查询倒排拉链,暴力搜索向量中心周围所有的点,并求距离

(7) Faiss  级量化器查询步骤2

查询的距离表示

距离计算是4个低维空间的距离之和,然后排序TopK

 

7、Faiss FAQ

(1)  Faiss查询是否线程安全的?

Faiss本身是线程安全,但是Faiss内部在耗时统计代码中不是线程安全的,比如indexIVF_stats这个数据结构,就是搞了一个全局变量来统计耗时,这种方法仅仅使用在测试阶段

(2) Faiss可以同时查询Nquery,每个query都查询nprobe个中心点吗?

是的,每个query一级量化器都返回nprobe中心点

(3) Faiss查询优化问题

IndexIVF 存在几种模式 parallel_mode = 0 1;
nprobe Faiss 查询聚类中心的个数,一般值越小,查询效率越高
max_codes 代表扫描倒排链表的时候最大向量数量

 

(4) Faiss查询优化问题

注意:(1)parallel_mode=0的时候,max_codes设置一定值,比如1000才有效,否则无效,当nprobe >1 的时候,

设置max_codes才有效,因为如果nprobe=1相当于遍历一个中心点的倒排索引,遍历完才去判断是否break

无论max_codes设置多么小,都是需要遍历一个中心点的倒排拉链的

 

(5) scan_codes聚类中心点的扫描可以离线化(主要耗时点

这个扫描是该聚类中心id周围样本向量所有距离计算,找出topk, 其实可以提前计算好分段距离,根据距离再量化成不同的分区---精度会下降

(6) faiss查询内存申请和释放问题

faiss内部为了支持线程安全每次查询都申请和释放大量内存,业务方往往在调用的时候单进程或多线程模型,大部分搜索处理模块线程数固定,不是每个query来了再启动一个线程,所以针对faiss内部频繁申请和释放内存可以使用线程存储的相关方法,循环使用内存,避免频繁申请和释放

 

二  向量化落地(部署)

1、独立部署向量

2、向量作为索引类型

3、无Faiss在线召回

 

三 未来工作展望-深度优化

  1. 向量召回后参考文本召回结果在底层合并
  2. 机器学习应用在底层索引模块打分
  3. 针对向量召回的特殊doc(文本匹配较差), 正排飘红优
  4. 在模型训练优化,提取content中的关键字+ query一起训练

 

四 参考文献

DSSM

https://www.cnblogs.com/wmx24/p/10157154.html

NSG

https://zhuanlan.zhihu.com/p/100716181

Faiss

https://github.com/facebookresearch/faiss/wiki

Vearch

https://vearch.readthedocs.io/zh_CN/latest/overview.html#id3

深度语义匹配模型

https://blog.csdn.net/qq_27590277/article/details/106264477

https://blog.csdn.net/ling620/article/details/95468908

https://zhuanlan.zhihu.com/p/39920446

https://www.cnblogs.com/guoyaohua/p/9229190.html

https://cloud.tencent.com/developer/article/1562482

http://www.wangqingbaidu.cn/article/dlp1516351259.html

https://www.jianshu.com/p/c578a77e7111

 

 


http://chatgpt.dhexx.cn/article/9TGutxwd.shtml

相关文章

ModaHub魔搭社区:向量数据库Milvus性能优化问题(三)

目录 Milvus 的导入性能如何? 边插入边搜索会影响搜索速度吗? 批量搜索时,用多线程的收益大吗? 为什么同样的数据量,用 GPU 查询比 CPU 查询慢? Milvus 的导入性能如何? 客户端和服务端在同一台物理机上时,10 万条 128 维的向量导入需要约 0.8 秒(基于 SSD 磁盘)…

Shader 优化相关资料整理

什么是渲染管线 注: 应用程序阶段:主要是CPU与内存打交道,例如碰撞检测,计算好的数据(顶点坐标、法向量、纹理坐标、纹理)就会通过数据总线传给图形硬件 。 几何阶段:其实上图有个问题&#xff…

pthread多线程入门-并行计算高维向量

介绍pthread ​ pthread其实也可以当作C/C的一个库&#xff0c;所有的函数和数据类型都在<pthread.h>中&#xff0e;跟AVX一样&#xff0c;如果使用了pthread&#xff0c;在编译的时候必须加上编译参数-lpthread&#xff0e;使用gcc编译指令如下&#xff1a; gcc filen…

Unity项目优化详解(持续补充ing)

Unity开发项目总结的几项优化点&#xff0c;比较适合中小项目优化&#xff0c;拿来即用&#xff0c;大型项目需要考虑定制化渲染管线、剔除、光照等。针对优化更多的还是需要结合项目去考虑。 一、模型 Read/Write&#xff1a;同Texture&#xff0c;若开启&#xff0c;Unity会…

SQL查询优化原理与向量化执行引擎

文章目录 1.SQL查询优化的目的2.SQL 查询优化的基本原理之研究如何通过关系代数优化执行方案3.总结使用关系代数进行查询优化的要点4.SQL 查询优化的基础算法5.Volcano Optimizer6.自底向上 vs. 自顶向下7.广度优先搜索与启发式算法8. 向量化执行引擎 1.SQL查询优化的目的 本文…

SQL优化之火山模型、向量化、编译执行

文章目录 1.当代CPU特性2.查询执行模型3.向量化VS编译执行4.编译执行融合向量化5.优化方向 1.当代CPU特性 向量化执行和编译执行是目前主流的两种数据库执行引擎优化手段。 了解CPU特性可以让我们真正理解各种数据库执行引擎优化技术的动机。 影响数据库执行引擎执行效率的C…

UE4性能优化

UE4性能优化 参考文档&#xff1a;UE4性能优化GPU分析**CPU分析**一些相关工具 Time: 2021年10月19日16:46:22 Desc: UE4性能优化 参考文档&#xff1a; https://docs.unrealengine.com/4.27/zh-CN/TestingAndOptimization/PerformanceAndProfiling/https://blog.csdn.net/u01…

一文纵览向量检索

摘要&#xff1a;本文针对向量检索要解决的问题&#xff0c;梳理了主流向量检索相关的技术&#xff0c;分析了向量检索目前的一个趋势。 什么是向量检索 首先我们了解下什么是向量&#xff0c;所谓向量就是由n个数字&#xff08;二值向量由n个比特组成&#xff09;组成的数组&…

C/C++编译器并行优化技术:并行优化针对多核处理器和多线程环境进行优化,以提高程序的并行度

目录标题 引言数据并行&#xff1a;将数据集分割成多个子集&#xff0c;分配给多个线程或处理器并行处理。延迟执行与乱序执行&#xff1a;对指令的执行顺序进行调整&#xff0c;提高指令流水线的利用率和性能。延迟执行乱序执行 任务并行&#xff1a;将程序分解为多个独立的任…

离散与提炼——一些关于向量召回算法优化方法的思考

✏️ 作者介绍&#xff1a; 周语馨&#xff0c;高级云智能工程师 最近做的很多向量召回的相关工作&#xff0c;主要集中在优化 Faiss 里面常用的几个算法&#xff0c;包括 IVFFlat 和 IVFPQ&#xff0c;并且针对这两个算法都做出了专门的优化。 前一阵子灵光乍现&#xff0c;想…

java手动回收线程_性能优化:线程资源回收

本文来自: PerfMa技术社区 PerfMa(笨马网络)官网 一、问题 模型服务平台的排序请求出现较多超时情况&#xff0c;且不定时伴随空指针异常。 二、问题发生前后的改动 召回引擎扩大了召回量&#xff0c;导致排序请求的item数量增加了。 三、出问题的模型 基于XGBoost预测的全排序…

编译优化之 - 向量化优化入门

1. 介绍 2. Intel高级向量扩展 3. GCC中向量化 4. ICC中向量化 5. AOCC/LLVM中向量化 1. 介绍 什么是自动向量化&#xff1f; 自动向量化&#xff08;automatic vectorization&#xff09;是自动并行化&#xff08;automatic parallelization&#xff09;的一种特殊情况&#…

数据库向量化如何进行性能优化

数据库向量化如何进行性能优化 前面提到&#xff0c;数据库向量化是一个巨大的、系统的性能优化工程&#xff0c;两年来&#xff0c;我们实现了数百个大大小小的优化点。我将 StarRocks 向量化两年多的性能优化经验总结为 7 个方面 &#xff08;注意&#xff0c;由于向量化执行…

simulink 状态空间加反馈报错

状态空间模型&#xff08;可控&#xff09;通过状态反馈或输出反馈可以自由配置极点和特征向量&#xff0c;得到理想的运动状态&#xff0c;通过计算得到的反馈增益矩阵K便可构建simulink模型&#xff0c;但常常报错&#xff0c;原因如下&#xff1a; 上图展示的是simulink模型…

状态空间方程MATLAB语句

1.连续系统 &#xff08;1&#xff09;使用系数矩阵获得传递函数 [num,den]ss2tf(A,B,C,D); &#xff08;2&#xff09;将传递函数写成因式分解&#xff08;零极点&#xff09;形式 [z,p,k]ss2zp(A,B,C,D) 或者 [z,p,k]tf2zp(num,den) &#xff08;3&#xff09;将给定形式…

基于matlab的系统状态空间转化

前段时间学习了一些关于通过系统状态方程判断系统可控性和可观测性&#xff0c;并由此求出其传递函数&#xff0c;基于传递函数判断其稳定性的一些知识。 一、常用的数学模型转换函数&#xff1a; 常用数学模型转换函数 ss2tf 将系统状态空间…

连续状态空间模型离散化

对于某状态空间模型&#xff1a; 其中&#xff1a; 将该连续模型离散化&#xff1a;&#xff08;代码如下&#xff09; clc;clear;close all A[-11.6028 7.1632 ;6.4909 -27.837 ]; B[3.086;5.4458]; [F,G]c2d(A,B,0.02) %0.02为采样周期 运行结果如下&#xff1a;&#xff0…

基于状态空间的数字控制器的设计

目录 一&#xff0e;目的... 2 二&#xff0e;内容... 2 三&#xff0e;实验过程与结果... 2 1&#xff0e;推算出控制对象的模型参数... 2 2. 状态空间的数字控制器的设计原理... 2 3、实验代码&#xff08;借鉴PPT内容&#xff09;... 3 4、仿真图像... 3 5、仿真结果…

人工智能:状态空间图(超详细经典例题讲解,通过例题教会你如何解决状态空间图问题)

1、定义 状态空间常记为三元组&#xff1a;<S&#xff0c;F&#xff0c;G>。 其中&#xff0c;S为初始状态的集合&#xff0c;F为操作的集合&#xff0c;G为目标状态的集合。 问题的状态空间图是一个描述该问题全部可能的状态及相互关系的有向图。 如考虑操作的代价&…

状态空间模型

&#xfeff;&#xfeff; 一、状态空间模型简述 状态空间模型是动态时域模型&#xff0c;以隐含着的时间为自变量。状态空间模型包括两个模型&#xff1a; 一是状态方程模型&#xff0c;反映动态系统在输入变量作用下在某时刻所转移到的状态&#xff1b; 二是输出或量测方程模…