首页/AI/RAG 与向量库速查/FAISS IndexFlat 精确检索

FAISS IndexFlat 精确检索

IndexFlatL2 / IndexFlatIP 是暴力精确检索索引:逐一比较全部向量,结果为准确保基线;数据量在十万级内、或用于验证近似索引的召回时常用。

RAG 与向量库速查AI更新于 2026-10-13

FAISS IndexFlat 是什么

IndexFlatL2 与 IndexFlatIP 是 FAISS 的暴力精确索引:查询时逐一计算与库中每个向量的距离,结果就是真实最近邻,没有任何近似误差。它不需要训练、可以随时追加向量,实现也最简单。代价是查询耗时随数据量线性增长:十万级还能接受,百万级单次查询就要扫描全量向量。它的两个不可替代用处是——数据量不大时的直接方案,以及作为近似索引的召回基线。

基本信息

类型暴力精确检索(brute force)
变体IndexFlatL2(欧氏)、IndexFlatIP(内积)
训练不需要,可直接 add
复杂度查询耗时与向量条数线性相关
常用搭配faiss.normalize_L2 后配 IndexFlatIP 等价余弦

典型使用场景

  • 召回基线:为 HNSW、IVF 等近似索引提供精确对照
  • 小规模直接使用:数据量在十万级内,精确结果更有价值
  • 离线去重:对全量向量做精确近邻查找,识别重复与近似重复
  • 结果校验:抽查线上近似检索的结果,确认没有系统性遗漏
  • 原型验证:先把链路跑通,再按数据增长替换索引类型

IndexFlatIP 找相似(内积)

IndexFlatIP 找相似(内积)
import faiss, numpy as np

xb = np.random.rand(100000, 384).astype('float32')
faiss.normalize_L2(xb)                      # 归一化后内积等价余弦
index = faiss.IndexFlatIP(384)
index.add(xb)
q = np.random.rand(1, 384).astype('float32')
faiss.normalize_L2(q)
D, I = index.search(q, 5)                   # D 为相似度,I 为向量下标
print(I[0], D[0])

两种 Flat 索引对比

索引度量使用要点
IndexFlatL2欧氏距离结果越小越相似,无需归一化
IndexFlatIP内积需自行归一化,否则模长主导排序
IndexFlat(通用)由构造参数决定选择度量后不要再混用
配 IndexIDMap同上需要业务主键时包一层

使用与迁移要点

  • 先确认度量:余弦用 IP 并归一化,欧氏才用 L2,别混着配
  • 规模判断:十万级可直接用,百万级以上评估 IVF 或 HNSW
  • 落盘习惯:write_index 保存并在启动时校验 ntotal
  • 主键映射:需要业务主键时用 IndexIDMap 包装,避免自建下标映射
替换为近似索引之前,务必先记录 Flat 的 Recall@10 作为基线:没有这条基线,就无法判断新索引到底损失了多少召回。

易错点

  • 用 L2 索引配归一化向量却不换 IP,度量语义与文档描述不一致
  • 百万级数据继续用 Flat,单次查询扫描全量导致延迟不可接受
  • 查询向量未归一化而库内已归一化,IndexFlatIP 的排序被模长带偏
  • 把精确结果当成唯一真相,忽略标注本身可能存在遗漏
  • 直接在进程内保存索引却不落盘,重启后需要全量重建

数据来源与参考

  • FAISS wiki(IndexFlat / MetricType)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌