赞
踩
向量数据库Faiss是Facebook AI研究院开发的一种高效的相似性搜索和聚类的库。它能够快速处理大规模数据,并且支持在高维空间中进行相似性搜索。
本文将依faiss使用全流程来教学gpu版的faiss如何使用
整个使用流程是:
- faiss环境配置
- 获取词向量
- 词向量索引获取
- 索引-词向量文档存储
- 读取索引-词向量文档
- 向量匹配
pip install faiss-cpu==1.7.3
# pip install faiss-gpu==1.7.2 # gpu安装
词向量模型可以从大规模文本嵌入基准 (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)
sentence_embeddings = 获取到的词向量[]
dimension = sentence_embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(sentence_embeddings)
faiss.write_index(index, output_path)
上面代码中构建索引的方式是IndexFlatL2,实际上,FAISS还提供了其他构建索引的方式。不同的索引方法在不同场景下有不同的优势,你可以根据数据集大小、内存限制和搜索速度的需求来选择适当的索引类型。
使用欧氏距离(L2)进行精确检索。
如果采用此索引结构,查询向量需要和索引中每个向量计算L2距离,然后进行排序,最后将距离较小的前k个结果返回。注意:IndexFlatL2索引不需要训练过程。
import faiss
d = # 向量维度
index = faiss.IndexFlatL2(d) # 构建索引
data = ... # 添加数据
index.add(data) # 添加数据到索引
使用倒排索引结构,将数据集划分为多个聚类空间,以加速搜索。
在查询阶段,首先定位到可能包含相似向量的聚类中心,然后在该聚类中心附近进行精确搜索。
import faiss
d = # 向量维度
nlist = # 聚类空间
k = # 返回结果个数
quantizer = faiss.IndexFlatL2(d) # 量化器
index = faiss.IndexIVFFlat(quantizer, d, nlist) # 构建索引
index.nprobe = 20 # 查找聚类中心的个数
index.train(data) # 训练
index.add(data) # 添加数据到索引
使用 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) # 添加数据到索引
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)
search = model.encode(["有问题这个功能"])
D, I = index.search(search, topK=5)
for k in I[0]:
print(texts2[k])
pass
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。