Faiss

ryluo 2020-09-05 14:54:30

faiss是一个高效的向量相似度搜索库,由facebook开发,支持python和c++,主要应用在大规模的向量相似性搜索场景中。


向量相似性搜索

给定一个向量集合,faiss通过构建一个数据结构来实现给定一个向量$x$快速的在向量集合中查找到与$x$距离最近的向量,在faiss库中这个数据结构被称为索引(index), 对于不同规模的向量搜索faiss库提供了不同的索引以实现高效的查找。

faiss主要实现的功能如下:

  1. 不仅仅返回距离最近的向量,也能够返回第二近,第三近的向量,…,第K近的向量
  2. 可以同时批量查找多个向量(batch processing),在大多数索引类型中,这种方式都比一个个查找要快
  3. 在精确性和执行速度上实现了一定的平衡,比如,给出了10%的错误结果,但是运行速度快了10倍或者仅仅占用了1/10的内存
  4. 在搜索时,使用的是最大内积(inner product)搜索,而不是最小欧式距离搜索
  5. 将索引存储在磁盘上而不是RAM中

注意:faiss使用的数据类型只能是32位的浮点型


python使用教程

定义数据

import numpy as np
d = 64                           # 向量的维度
nb = 100000                      # 需要搜索的向量集合的大小
nq = 10000                       # 查询向量的集合大小
np.random.seed(1234)             # 设置随机数种子
xb = np.random.random((nb, d)).astype('float32') # 定义搜索向量集合
xb[:, 0] += np.arange(nb) / 1000.
xq = np.random.random((nq, d)).astype('float32') # 定义查询向量集合
xq[:, 0] += np.arange(nq) / 1000.

建立索引

import faiss                   # 导入faiss包
index = faiss.IndexFlatL2(d)   # 建立索引对象,这里只需要指定搜索向量的维度即可
print(index.is_trained)         
index.add(xb)                  # 将搜索向量集合添加至索引对象中
print(index.ntotal)

向量搜索

k = 4                          # 定义返回的紧邻个数
D, I = index.search(xq, k)    
print(I[:5])                   # 返回前5个查询查询的结果
print(I[-5:])                  # 返回后5个查询查询的结果


注意:

上述向量搜索返回的I是相对索引值,也就是在构建向量索引时的矩阵,第几行就表示对应的向量索引是多少。所以当真实情况下的索引与相对索引不一致的时候需要对两者进行相互转换。