当前位置:   article > 正文

#VDB|RAG|AIGC#(含代码)向量检索工具FAISS的搭建和使用教程、经验分享_c# faiss以图搜图

c# faiss以图搜图

请添加图片描述

向量数据库Faiss是Facebook AI研究院开发的一种高效的相似性搜索和聚类的库。它能够快速处理大规模数据,并且支持在高维空间中进行相似性搜索。

本文将依faiss使用全流程来教学gpu版的faiss如何使用

整个使用流程是:

  1. faiss环境配置
  2. 获取词向量
  3. 词向量索引获取
  4. 索引-词向量文档存储
  5. 读取索引-词向量文档
  6. 向量匹配

环境配置

pip install faiss-cpu==1.7.3
# pip install faiss-gpu==1.7.2  # gpu安装
  • 1
  • 2

词向量获取

词向量模型可以从大规模文本嵌入基准 (MTEB) 排行榜中选取
可选

SentenceTransformer(‘lier007/xiaobu-embedding’)

FastTextEncoder( “infgrad/stella-base-zh-v2”)

FlagModel(‘BAAI/bge-large-zh-v1.5’,query_instruction_for_retrieval=“为这个句子生成表示以用于检索相关文章:”,
use_fp16=True)

等等……

通用加载方法:

model = SentenceTransformer('你的词向量模型')
sentence_embeddings  = model.encode(texts, normalize_embeddings)
  • 1
  • 2

存储

sentence_embeddings = 获取到的词向量[]
dimension = sentence_embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(sentence_embeddings)
faiss.write_index(index, output_path)
  • 1
  • 2
  • 3
  • 4
  • 5

构建索引

上面代码中构建索引的方式是IndexFlatL2,实际上,FAISS还提供了其他构建索引的方式。不同的索引方法在不同场景下有不同的优势,你可以根据数据集大小、内存限制和搜索速度的需求来选择适当的索引类型。
在这里插入图片描述

1. IndexFlatL2 - 暴力检索L2

使用欧氏距离(L2)进行精确检索。
如果采用此索引结构,查询向量需要和索引中每个向量计算L2距离,然后进行排序,最后将距离较小的前k个结果返回。注意:IndexFlatL2索引不需要训练过程。

import faiss
d = # 向量维度
index = faiss.IndexFlatL2(d)  # 构建索引
data = ...  # 添加数据
index.add(data)  # 添加数据到索引
  • 1
  • 2
  • 3
  • 4
  • 5

2. IndexIVFFlat - 倒排索引,加速,查询优化

使用倒排索引结构,将数据集划分为多个聚类空间,以加速搜索。
在查询阶段,首先定位到可能包含相似向量的聚类中心,然后在该聚类中心附近进行精确搜索。
请添加图片描述

import faiss
d = # 向量维度
nlist = # 聚类空间
k = # 返回结果个数
quantizer = faiss.IndexFlatL2(d)  # 量化器
index = faiss.IndexIVFFlat(quantizer, d, nlist)  # 构建索引
index.nprobe = 20  # 查找聚类中心的个数
index.train(data)  # 训练
index.add(data)  # 添加数据到索引

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3.IndexIVFPQ - 省空间超快

使用 Product Quantization(PQ)技术进行有损压缩,以节省内存。
在查询阶段,返回近似结果。请添加图片描述

请添加图片描述

请添加图片描述

import faiss
d = # 向量维度
m =   # 空间拆分
nlist = # 聚类空间
k = # 返回结果个数
quantizer = faiss.IndexFlatL2(d)
index = faiss.IndexIVFPQ(quantizer, d, nlist, m, 8)  # 每个向量用8 bits 编码
index.nprobe = 20  # 查找聚类中心的个数
index.train(data)  # 训练
index.add(data)  # 添加数据到索引
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4.IndexHNSWFlat-图索引

请添加图片描述
Regular Graph:图中每个顶点具有相同数目的邻居。
Random Graph:图中每个顶点的邻居数是随机的。
Small World Graph:介于Regular与Random之间;局部同类顶点的连接呈现出regular,全局不同类顶点的连接呈现出random。
构建好small world graph后,随机选择一个起始点,逐个遍历其邻接点,选择与目标最近的顶点继续遍历,直到找到最近的顶点。这个过程称之为NSW(Navigable small world)。

HNSW是Hierarchical Navigable Small World的缩写,即分层的NSW。整体可分为图构造过程和图检索过程。

请添加图片描述
上图描述了图构造过程。layer=0包含数据集中所有节点,layer=l以50%概率从layer=l-1层中选择的点构成。在每层的NSW图中查找m个近邻,然后连接它他。

请添加图片描述

对HNSW进行查询时,从最高层检索,逐层往下进行。

构建索引的方式对比与选择

1 简单场景
如果只需较少次查询时,建议使用“Flat”索引直接计算。因为建索引时间不能被查询时间弥补。如果全部数据不能放入RAM内存,则可分多次构建小索引,最后再将小索引查询结果合并。

如果需要确切结果的话,则需要使用IndexFlatL2 或者 IndexFlatIP。

2 基于内存的考量
如果不关注(如内存较大或数据集较小),则HNSW是最好的选择,它不仅快而且准。比HNSW更快的选择是IVF1024,PQNx4fs,RFlat。

如果稍微考虑的话,则采用先聚类再Flat索引的方式。

如果比较重要的话,则采用OPQM_D,…,PQMx4fsr。 其中OPQ用来降维,PQ对向量进行量化。

如果非常重要,则采用OPQM_D,…,PQM。其中D和M有特定要求。

3 考虑数据集大小
如果数据集大小在1M以下,则采用…,IVFK,…。

如果数据集大小在1M~10M,则采用 …,IVF65536_HNSW32,…。训练向量数建议在 30 * 65536 and 256 * 65536之间。

如果数据集大小在10M~100M,则采用…,IVF262144_HNSW32,…。训练向量数建议在 30 * 262144 and 256 * 262144之间。

如果数据集大小在100M~1B,则采用…,IVF1048576_HNSW32,…。训练向量数建议在30 * 1048576 and 256 * 1048576之间。

覆盖

读取

index = faiss.read_index(index_path)
  • 1

搜索

search = model.encode(["有问题这个功能"])
 D, I = index.search(search, topK=5)
 for k in I[0]:
     print(texts2[k])
 pass
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/242491
推荐阅读
相关标签
  

闽ICP备14008679号