首页/AI/RAG 与向量库速查/FAISS HNSW 使用与保存

FAISS HNSW 使用与保存

FAISS 的 IndexHNSWFlat 在进程内提供图索引检索:构建后可在查询时调 efSearch;索引通过 write_index / read_index 保存与加载,注意保存的是索引结构而非原始数据源。

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

FAISS HNSW 是什么

IndexHNSWFlat 用多层邻近图组织向量,查询时从入口点沿图逐层逼近目标,靠 efSearch 控制搜索广度。索引跑在进程内,省掉网络往返与服务部署成本,适合离线批处理、单机检索服务和召回实验。索引用 write_index 保存、read_index 加载;保存的是索引结构本身,原始向量数据源要另行备份。

基本信息

构建参数M 控制每个节点的连边数,efConstruction 控制建图时的搜索广度
查询参数efSearch 越大召回越高、延迟越高
持久化faiss.write_index 写入文件,faiss.read_index 加载
版本敏感索引文件与 faiss 版本强相关,升级前要验证可加载

典型使用场景

  • 离线批量检索:把索引加载进脚本一口气跑完,不受服务并发限制
  • 召回实验:对比 HNSW 与 IVF 在不同参数下的召回与耗时
  • 单机小服务:向量规模在内存可容纳范围内,省去集群运维
  • 索引快照归档:把某次构建的索引存下来,方便复现历史结果
  • 迁移前的临时方案:正式向量库部署完成前先用进程内索引顶着

构建保存与加载

构建保存与加载
import faiss, numpy as np

d = 384
index = faiss.IndexHNSWFlat(d, 32)          # 32 为 M,邻居数
index.hnsw.efConstruction = 200             # 建图搜索广度,越大越慢越准
xb = np.random.rand(200000, d).astype("float32")
index.add(xb)                               # 添加数据,注意先加全再保存
index.hnsw.efSearch = 64                    # 查询期可随时调整
faiss.write_index(index, "kb_hnsw.faiss")

loaded = faiss.read_index("kb_hnsw.faiss")
print(loaded.ntotal)                        # 核对数量与预期一致

参数与影响

参数作用调大后的影响
M每个节点的邻居连边数召回更好,内存与建图时间上升
efConstruction建图时的搜索广度图质量更高,建索引更慢
efSearch查询时的搜索广度召回上升,延迟上升
ntotal索引内向量总量与预期不符说明写入不完整
索引文件与库版本强相关:升级 faiss 前先在测试环境验证可加载性,避免生产环境启动时才报错。
HNSW 不支持高效删除,删除后通常留空洞或需重建;需要频繁更新语料时,进程内索引的维护成本会比服务化向量库高,选型时要把更新频率一起考虑。

易错点

  • 保存索引前未 add 全部数据,恢复后数量对不上
  • 跨版本直接加载索引文件,兼容性问题可能在运行时报错
  • 认为索引文件等于数据备份:原始向量与元数据仍需单独保存
  • 把 efSearch 调到很低追求速度,召回下降却未做评测对照

数据来源与参考

  • FAISS wiki(HNSW / write_index)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌