首页/AI/RAG 与向量库速查/FAISS 索引读写与合并

FAISS 索引读写与合并

FAISS 提供 write_index / read_index 做持久化,也可用 IndexIDMap 保存业务 id;多份索引可 merge_from 合并,适合分片构建再汇总的离线流水线。

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

FAISS 索引读写与合并

FAISS 的索引可以落盘复用:write_index 写出文件、read_index 读回,省去每次服务的重建开销;配合 IndexIDMap 与 add_with_ids 能把业务主键直接存进索引,检索返回的就是业务 id。分片构建的索引还能用 merge_from 合并,适合「先分片离线构建,再汇总成一份」的流水线。前提条件是同类型、同维度、同度量的索引才能合并,业务 id 需要 int64。

基本信息

持久化write_index 写出、read_index 读回
业务主键IndexIDMap 配合 add_with_ids
合并merge_from,要求同类型同维度同度量
id 类型必须为 int64
常用结构IndexFlatIP 精确检索,另可选用 IVF 与 HNSW
典型用途离线批量构建、分片汇总、服务启动加载

典型使用场景

  • 离线流水线分片构建索引,最后合并成一份完整索引
  • 服务启动时加载预构建索引,避免每次重建
  • 用业务主键检索,省掉序号到 id 的映射表
  • 把线上索引定期落盘,用于快速回滚
  • 多个数据源各自构建后合并,避免一次性占用大内存

IndexIDMap 与合并

IndexIDMap 与合并
import faiss, numpy as np

idx = faiss.IndexFlatIP(384)                    # 内积精确索引
idmap = faiss.IndexIDMap(idx)                   # 包装成可带业务 id
ids = np.arange(1000, 1010, dtype="int64")      # 业务 id 必须 int64
idmap.add_with_ids(np.random.rand(10, 384).astype("float32"), ids)
faiss.write_index(idmap, "part.faiss")          # 落盘

p2 = faiss.read_index("part.faiss")             # 读回
p1 = faiss.read_index("part_a.faiss")
p1.merge_from(p2)                               # 同类型索引可合并
faiss.write_index(p1, "merged.faiss")

接口读法

接口作用注意
write_index 与 read_index索引持久化文件格式与 FAISS 版本相关,跨版本加载需先验证
add_with_ids写入并指定业务 idid 必须为 int64
merge_from合并两份索引要求同类型、同维度、同度量
IndexFlatIP精确内积检索向量需先归一化,内积才等价于余弦
用 add_with_ids 后检索直接返回业务 id,可以省掉额外维护的序号映射表,也避免了映射错位导致的取错文档。
read_index 加载的索引文件与构建它的 FAISS 版本绑定:跨版本升级时先用小样本验证能否加载,避免线上启动即失败。
IndexFlatIP 属于精确检索:数据量到百万级时内存与延迟都会明显上升,此时应换成 IVF 或 HNSW 近似索引,并用同一评测集确认召回损失可接受。
合并前先校验分片之间有没有重复的业务 id:不同分片写入相同 id 会得到重复命中,排序时同一个文档占满多个返回位。

易错点

  • 合并不同度量或不同维度的索引:构造上不成立,直接报错或产生错乱结果
  • 业务 id 用 int64 以外类型:转换期间溢出或丢精度,检索命中的 id 无法对应原文
  • 索引只在内存里构建不落盘:服务重启就必须重建,重建时长在故障时无从压缩
  • 把精确索引用于大规模数据:内存占用随数据量线性增长,单机撑不住

数据来源与参考

  • FAISS wiki(IndexIDMap / merge_from)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌