辽宁省建设工程造价管理协会网站,做网站数据库坏了,都网站建设,齐鲁人才网泰安招聘文章目录 一.简介1.1 什么是Faiss1.2 Faiss的安装 二.Faiss检索流程2.1 构建向量库2.2 构建索引2.3 top-k检索 三.Faiss构建索引的多种方式3.1 Flat #xff1a;暴力检索3.2 IVFx Flat #xff1a;倒排暴力检索3.3 IVFxPQy 倒排乘积量化3.4 LSH 局部敏感哈希3.5 HNSWx 一.简介… 文章目录 一.简介1.1 什么是Faiss1.2 Faiss的安装 二.Faiss检索流程2.1 构建向量库2.2 构建索引2.3 top-k检索 三.Faiss构建索引的多种方式3.1 Flat 暴力检索3.2 IVFx Flat 倒排暴力检索3.3 IVFxPQy 倒排乘积量化3.4 LSH 局部敏感哈希3.5 HNSWx 一.简介
1.1 什么是Faiss
Faiss的全称是Facebook AI Similarity Search是Facebook的AI团队针对大规模相似度检索问题开发的一个工具使用C编写有python接口对10亿量级的索引可以做到毫秒级检索的性能。 简单来说Faiss的工作就是把我们自己的候选向量集封装成一个index数据库它可以加速我们检索相似向量top-K的过程其中有些索引还支持GPU构建。
1.2 Faiss的安装
## cpu版
$ conda install -c pytorch faiss-cpu
## gpu版
$ conda install -c pytorch faiss-gpu二.Faiss检索流程
2.1 构建向量库
这一部分就是将我们已有的数据转成向量库。
import numpy as np
d 64 # 向量维度
nb 100000 # index向量库的数据量
nq 10000 # 待检索query的数目
np.random.seed(1234)
xb np.random.random((nb, d)).astype(float32)
xb[:, 0] np.arange(nb) / 1000. # index向量库的向量
xq np.random.random((nq, d)).astype(float32)
xq[:, 0] np.arange(nq) / 1000. # 待检索的query向量2.2 构建索引
用faiss 构建index并将向量添加到index中。这里我们选用暴力检索的方法FlatL2L2代表构建的index采用的相似度度量方法为L2范数即欧氏距离。
import faiss
index faiss.IndexFlatL2(d)
print(index.is_trained) # 输出为True代表该类index不需要训练只需要add向量进去即可
index.add(xb) # 将向量库中的向量加入到index中
print(index.ntotal) # 输出index中包含的向量总数为100000 2.3 top-k检索
检索与query最相似的top-k。
k 4 # topK的K值
D, I index.search(xq, k)# xq为待检索向量返回的I为每个待检索query最相似TopK的索引listD为其对应的距离
print(I[:5])
print(D[-5:])三.Faiss构建索引的多种方式
构建index方法和传参方法可以为
dim, measure 64, faiss.METRIC_L2
param Flat
index faiss.index_factory(dim, param, measure)dim为向量维数最重要的是param参数它是传入index的参数代表需要构建什么类型的索引measure为度量方法目前支持两种欧氏距离和inner product即内积。因此要计算余弦相似度只需要将vecs归一化后使用内积度量即可。
此外Faiss官方支持八种度量方式分别是 1METRIC_INNER_PRODUCT内积 2METRIC_L1曼哈顿距离 3METRIC_L2欧氏距离 4METRIC_Linf无穷范数 5METRIC_Lpp范数 6METRIC_BrayCurtisBC相异度 7METRIC_Canberra兰氏距离/堪培拉距离 8METRIC_JensenShannonJS散度
3.1 Flat 暴力检索
优点该方法是Faiss所有index中最准确的召回率最高的方法没有之一缺点速度慢占内存大。使用情况向量候选集很少在50万以内并且内存不紧张。Ps虽然都是暴力检索faiss的暴力检索速度比一般程序猿自己写的暴力检索要快上不少所以并不代表其无用武之地建议有暴力检索需求的同学还是用下faiss。构建方法
dim, measure 64, faiss.METRIC_L2
param Flat
index faiss.index_factory(dim, param, measure)
index.is_trained # 输出为True
index.add(xb) # 向index中添加向量3.2 IVFx Flat 倒排暴力检索
优点IVF主要利用倒排的思想在文档检索场景下的倒排技术是指一个kw后面挂上很多个包含该词的doc由于kw数量远远小于doc因此会大大减少了检索的时间。在向量中如何使用倒排呢可以拿出每个聚类中心下的向量ID每个中心ID后面挂上一堆非中心向量每次查询向量的时候找到最近的几个中心ID分别搜索这几个中心下的非中心向量。通过减小搜索范围提升搜索效率。缺点速度也还不是很快。使用情况相比Flat会大大增加检索的速度建议百万级别向量可以使用。参数IVFx中的x是k-means聚类中心的个数构建方法
dim, measure 64, faiss.METRIC_L2
param IVF100,Flat # 代表k-means聚类中心为100,
index faiss.index_factory(dim, param, measure)
print(index.is_trained) # 此时输出为False因为倒排索引需要训练k-means
index.train(xb) # 因此需要先训练index再add向量
index.add(xb)3.3 IVFxPQy 倒排乘积量化
优点工业界大量使用此方法各项指标都均可以接受利用乘积量化的方法改进了IVF的k-means将一个向量的维度切成x段每段分别进行k-means再检索。缺点集百家之长自然也集百家之短使用情况一般来说各方面没啥特殊的极端要求的话最推荐使用该方法参数IVFxPQy其中的x和y同上构建方法
dim, measure 64, faiss.METRIC_L2
param IVF100,PQ16
index faiss.index_factory(dim, param, measure)
print(index.is_trained) # 此时输出为False因为倒排索引需要训练k-means
index.train(xb) # 因此需要先训练index再add向量 index.add(xb)
index.add(xb)3.4 LSH 局部敏感哈希
原理哈希对大家再熟悉不过向量也可以采用哈希来加速查找我们这里说的哈希指的是局部敏感哈希Locality Sensitive HashingLSH不同于传统哈希尽量不产生碰撞局部敏感哈希依赖碰撞来查找近邻。高维空间的两点若距离很近那么设计一种哈希函数对这两点进行哈希计算后分桶使得他们哈希分桶值有很大的概率是一样的若两点之间的距离较远则他们哈希分桶值相同的概率会很小。优点训练非常快支持分批导入index占内存很小检索也比较快缺点召回率非常拉垮。使用情况候选向量库非常大离线检索内存资源比较稀缺的情况构建方法
dim, measure 64, faiss.METRIC_L2
param LSH
index faiss.index_factory(dim, param, measure)
print(index.is_trained) # 此时输出为True
index.train(xb)
index.add(xb)3.5 HNSWx
优点该方法为基于图检索的改进方法检索速度极快10亿级别秒出检索结果而且召回率几乎可以媲美Flat最高能达到惊人的97%。检索的时间复杂度为loglogn几乎可以无视候选向量的量级了。并且支持分批导入极其适合线上任务毫秒级别体验。缺点构建索引极慢占用内存极大是Faiss中最大的大于原向量占用的内存大小参数HNSWx中的x为构建图时每个点最多连接多少个节点x越大构图越复杂查询越精确当然构建index时间也就越慢x取4~64中的任何一个整数。使用情况不在乎内存并且有充裕的时间来构建index构建方法
dim, measure 64, faiss.METRIC_L2
param HNSW64
index faiss.index_factory(dim, param, measure)
print(index.is_trained) # 此时输出为True
index.add(xb)