Faiss 向量检索怎么上手:Python 建索引与相似度查询
Faiss 是 Facebook 开源的向量相似度检索库,适合在本地或服务器上对一批向量做最近邻查询。
如果你刚接触向量检索,想先跑通“建索引—写入向量—查询”这条链路,用 Faiss 的 CPU 版配合 Python 是最短路径。
下面按实际能跑通的顺序说明安装、建索引、查询和验证,并指出最容易卡住的维度与数据类型问题。
安装与环境确认
Faiss 官方提供 CPU 版和 GPU 版。
新手先用 CPU 版即可,不依赖 CUDA。
确认 Python 版本在 3.8 以上,然后执行:
pip install faiss-cpu numpy
安装完成后做一次导入检查,能打印版本号就说明装好了:
import faiss
import numpy as np
print(faiss.__version__)
如果导入时报 ImportError 或找不到模块,
优先检查当前 pip 是否对应你正在使用的 Python 解释器,
可用 python -m pip install faiss-cpu 重新安装。
用 IndexFlatL2 跑通第一次检索
Faiss 的核心对象是索引(index)。IndexFlatL2 表示用欧氏距离做暴力搜索,不需要训练,适合数据量不大或第一次验证。
示例中构造 4 条 8 维向量,写入后查询与第一条最接近的结果:
import faiss
import numpy as np
d = 8 # 向量维度
vectors = np.random.random((4, d)).astype('float32')
index = faiss.IndexFlatL2(d)
index.add(vectors)
print(index.ntotal) # 应输出 4
query = vectors[0:1] # 查询向量,形状 (1, d)
k = 2
distances, ids = index.search(query, k)
print(ids) # 返回最接近的 2 个向量编号
print(distances) # 对应的距离
运行后 ids 的第一位应当是 0,因为查询向量就是第 0 条数据,距离也应为 0。
这就是最基本的验证方式。
数据形状和类型必须对齐
Faiss 对输入很严格,最常见的两个报错都来自这里:
- 维度不一致:建索引时的
d必须和add、search传入向量的第二维完全相同。例如索引是 8 维,就不能传入 16 维向量。 - 类型不对:Faiss 默认接收
float32。用np.random.random生成后要加.astype('float32'),否则可能报类型错误。
另外,search 的 k 不能超过索引中已有向量数量,否则返回结果里会出现 -1 编号。
查询向量要写成二维形状 (1, d),用 vectors[0:1] 而不是 vectors[0]。
保存索引与重新加载
服务重启后不想每次重建索引,可以用 write_index 和 read_index 落盘:
faiss.write_index(index, 'faiss.index')
loaded = faiss.read_index('faiss.index')
print(loaded.ntotal)
文件路径建议放在有写权限的目录,例如项目下的 data/faiss.index。
加载后索引的维度、类型与保存前一致,直接调用 search 即可继续查询。
怎么判断检索结果可信
跑通代码不等于结果正确,建议做两步验证:
- 用已知向量查询自身,距离应接近 0,对应编号应与写入顺序一致。
- 构造一条与已有向量明显不同的查询,观察返回距离是否变大。如果距离始终不变或编号异常,先检查向量是否被重复写入或维度写错。
对于小数据量,IndexFlatL2 的结果是精确的;
数据量增大后可以再考虑 IVF 等近似索引,但那需要额外训练步骤,不适合作为第一次验证的起点。
常见疑问
Faiss 需要单独启动服务吗?
不需要。它是 Python 库,随进程加载,索引对象在内存中,持久化靠 write_index 写文件。
GPU 版和 CPU 版能混用吗?
同一份索引文件通常可以在对应版本间读写,但 GPU 版依赖 CUDA 环境和显卡驱动,新手建议先用 CPU 版把流程跑通。
查询返回 -1 是什么原因?
通常是 k 大于索引中的向量数量,或者索引还没有成功 add 数据。先检查 index.ntotal 是否符合预期。
以上流程覆盖了 Faiss 使用教程里最常遇到的安装、建索引、查询和验证环节。
先确保维度、数据类型和 k 值三者一致,再考虑保存索引和替换更复杂的索引类型,排错会轻松很多。