faiss

faiss的主要功能是对向量进行相似搜索。具体就是给定一个向量,在所有已知的向量库中找出与其相似度最高的一些向量,本质是一个KNN(K近邻)问题,比如google的以图找图功能。随着目前embedding的流行,word2vec,doc2vec,img2vec,item2vec,video2vec,everything2vec,所以faiss也越来越受到大家的欢迎。 根据上面的描述不难看出,faiss本质是一个向量(矢量)数据库,这个数据库在进行向量查询的时候有其独到之处,因此速度比较快,同时占用的空间也比较小。

IndexFlatL2

IndexFlatL2索引的方式是计算L2距离,为一种暴力的(brute-force))精确搜索的方式,计算方式自然就是计算各向量的欧式距离(L2距离)

IndexIVFFlat

IndexFlatL2为暴力搜索,速度慢,实际中我们需要更快的方式,于是就有了IndexIVFFlat。 为了加快搜索的速度,我们可以将数据集分割为几部分,将其定义为Voronoi Cells,每个数据向量只能落在一个cell中。查询时只需要查询query向量落在cell中的数据了,降低了距离计算次数。 IndexIVFFlat需要一个训练的阶段,其与另外一个索引quantizer有关,通过quantizer来判断属于哪个cell。

IndexIVFFlat在搜索的时候,引入了nlist(cell的数量)与nprob(执行搜索的cell树)参数。通过调整这些参数可以在速度与精度之间平衡

IndexIVFPQ

IndexFlatL2 和 IndexIVFFlat都要存储所有的向量数据。对于超大规模数据集来说,可能会不大显示。因此IndexIVFPQ索引可以用来压缩向量,具体的压缩算法为PQ(乘积量化, Product Quantizer)

IndexIVFPQ能正确找到距离最小的向量(他本身),但是距离不为0,这是因为向量数据存储时候有压缩,会损失一部分精度。

另外搜索真实查询时,虽然结果大多是错误的(与刚才的IVFFlat进行比较),但是它们在正确的空间区域,而对于真实数据,情况更好,因为: 1.统一数据很难进行索引,因为没有规律性可以被利用来聚集或降低维度 2.对于自然数据,语义最近邻居往往比不相关的结果更接近