最近在做知识库问答的时候看到了Faiss,查询了一些资料了解其原理,下面做简单记录,方便以后查阅。
Faiss(Facebook AI Similarity Search)是Facebook AI团队开源的针对聚类和相似性搜索库,为稠密向量提供高效相似度搜索和聚类,支持十亿级别向量的搜索,是目前较成熟的近似近邻搜索库。(相似向量检索库-Faiss-简介及原理_金色麦田~的博客-CSDN博客 )
Faiss整体流程图如下所示:
图片来自:相似向量检索库-Faiss-简介及原理_金色麦田~的博客-CSDN博客
图中,Faiss主要包含两个步骤:Faiss训练和Faiss查询。
1 Faiss训练
Faiss训练主要涉及两个算法:倒排索引(Inverted Index)和乘积量化(Product Quantization, PQ)。
倒排索引图片来源:相似向量检索库-Faiss-简介及原理_金色麦田~的博客-CSDN博客
倒排索引的原理比较简单,其主要通过使用聚类算法,将原始的数据聚为N类,即N个子空间。当来一个问句时,计算该问句和N个子空间的距离(问句向量与N个子空间的中心的距离),选择出距离最近的K个子空间,这K个子空间表示该问句可能答案可能存在的区域,然后再去这K个子空间查询答案。
乘积量化图片来源:[检索算法系列-1] 乘积量化 - 知乎
乘积量化分为两个步骤:聚类和量化。
(1)聚类的步骤如下:假设有N个文本或者图片,向量化为256维的向量。将该256维的向量分成4(自己设定)小段,然后就得到了4堆N*64的向量,对每一堆向量进行聚类操作,假设聚类个数为256个,可以将一堆中的N个向量聚类为256维。
(2)量化的步骤如下:将聚类后的每类计算其簇心(聚类中心,质心),使用这个簇心的ID当作向量量化的编码,由于每个向量都是由四小段向量组成的,所以每个向量可以被4个ID编码。这样,N个256维的向量可以被量化成4个ID,每个ID可以由一个字节保存,所以每个向量可以由4个字节进行编码。这样就得到了每个向量的索引index。
2 Faiss查询
Faiss查询图片来源:ANN之乘积量化PQ_田小成plus的博客-CSDN博客
Faiss查询流程(非对称距离计算步骤):
(1)当来一个查询向量后,首先需要将其切分成4段;
(2)然后计算每段向量和该段的256个簇心之间的距离,这样就得到了一个256*4的矩阵和数组,称其为距离表;
(3)遍历样本库中的候选向量,根据距离表,计算候选向量和查询向量的距离和;
(4)根据(3)算出的距离和,返回topK个距离最近的样本;
(5)二次搜索,可以根据(4)返回的 topk 近似样本,再按照 query 和 topk对应的原始向量进行暴力匹配,提高 topk里排序的准确率。
参考文献: