☰
Faiss 1.11.0 向量检索提速:RaBitQ 把每条向量压缩到约 1/32 的存储
2026/10/4 18:37:27 网站建设 项目流程

Faiss 1.11.0 向量检索提速:RaBitQ 把每条向量压缩到约 1/32 的存储

【免费下载链接】faissA library for efficient similarity search and clustering of dense vectors.项目地址: https://gitcode.com/GitHub_Trending/fa/faiss

Faiss 1.11.0(2025-04-24 发布,见 CHANGELOG.md)是稠密向量检索库 Faiss 的新版本,解决数据量上涨后 fp32 向量存储与暴力搜索延迟扛不住的瓶颈,核心新增是 RaBitQ 量化索引。读完本文,你能三步建出一个 RaBitQ 索引并发起查询,按数据规模、精度、内存三个条件选到合适索引,并用三个量化指标确认优化生效。

这个版本改了什么

  • 新增 RaBitQ 实现:IndexRaBitQ、IndexIVFRaBitQ及其 FastScan 变体共 4 种索引形态,index factory 直接支持"RaBitQ"、"RaBitQfs"字符串(faiss/IndexRaBitQ.h、faiss/index_factory.cpp)
  • 新增内存映射与零拷贝反序列化器,加载大索引不必再整体复制一份内存(faiss/impl/mapped_io.h)
  • 训练 API 增加normalize_l2/is_spherical开关,让球面数据的预处理行为显式化(CHANGELOG 1.11.0 Added 一节)
  • 修复IndexHNSW的metric_arg传参 bug、为nb_neighbors增加越界检查、修复 ARM 平台上IVFPQFastScan的 range search 行为(CHANGELOG 1.11.0 Fixed 一节)
  • C API 开始通过 Conda 发布,C 语言接入的安装方式更简单(CHANGELOG 1.11.0 Changed 一节)

RaBitQ 是怎么省事的

把一条 256 维向量想成行李箱里 256 件物品。乘积量化(PQ,把向量切成 M 段、每段查码本表)相当于把物品分装进小袋子再逐个描述;RaBitQ 则是完全不拆行李,每个维度只记 1 个比特:正还是负。于是每维从 4 个字节降到 1/8 个字节,再外加几个字节的校准常数,总存储约是 fp32 的 1/25 到 1/32(码长公式见 faiss/impl/RaBitQuantizer.h 的compute_code_size)。搜索时 CPU 用 and、popcount 这类位运算估计距离,而不是逐维浮点乘法,SIMD 指令集恰好对位运算加速明显。

三步跑通最小示例

第一步:安装。pip 装现成包最简单,想自己编译也可以从源码来:

pip install faiss-cpu # 或:git clone https://gitcode.com/GitHub_Trending/fa/faiss # cmake -B build && cmake --build build -j && cmake --install build

第二步:建索引。IndexRaBitQ只需要维度d和每维位数nb_bits,没有 PQ 那种 M 参数,训练也远比聚类轻量。第三步:查询,接口和普通 Faiss 索引完全一致:

import numpy as np import faiss d, n = 256, 200_000 xb = np.random.randn(n, d).astype("float32") xq = np.random.randn(10, d).astype("float32") index = faiss.IndexRaBitQ(d, nb_bits=1) # 1-bit 量化 index.add(xb) D, I = index.search(xq, 10)

按场景选索引

数据规模精度要求内存条件推荐索引
百万以内接近精确搜索不限IndexFlatL2暴力搜索
千万级可接受少量召回损失紧张IndexRaBitQ(nb_bits=1)
亿级精度与速度平衡紧张IndexIVFRaBitQ(nlist 取 √N 量级)
千万级以上极高精度充足IndexHNSWFlat图索引

💡 一般从 IVF + RaBitQ 起步,再调nprobe换召回;CPU 支持 AVX-512 时可换 FastScan 变体(factory 字符串"RaBitQfs"),批处理吞吐更高。

怎么确认优化生效

不用搭监控体系,看三个数字就够:

  • 查询延迟:用 timeit 跑 10 次 search 取平均毫秒数,benchs/bench_rabitq.py 里的计时函数可以直接照搬
  • 召回率:拿精确 top-k 做对照,用faiss.eval_intersection算交集占比,与升级前的基线对比
  • 内存:RaBitQ 1-bit 码每条向量占 (d+7)/8 + 8 字节,乘上向量总数,对比 fp32 的 d×4 字节,省了多少一目了然

📌 该基准脚本会依次跑 256 / 512 / 768 / 1024 维,按维度输出召回与延迟表格,跑一遍就能得到你这台机器上的前后对比。

容易踩的四个坑

  • 按 IVFPQ 的签名调用IndexIVFRaBitQ。原因:它的构造参数是 (quantizer, d, nlist, ...),不存在 IVFPQ 的 M、nbits 参数,RaBitQ 的位宽参数是nb_bits(1-9)。规避:先看 faiss/IndexIVFRaBitQ.h 里的真实签名再写代码
  • 在 FastScan 变体里把qb设为 0。原因:SIMD 查找表需要量化后的查询,头文件明确注明 FastScan 不支持qb=0。规避:保留默认qb=4,需要更精查询量化再调大
  • 用sa_decode的输出去核对 L2 精度。原因:解码偏向保持内积,重建向量的 L2 误差可能偏大。规避:L2 场景以 search 路径的距离为准,不把重建结果当真值
  • 小数据硬上量化索引。原因:数据不到百万且内存充裕时,暴力搜索更准也更简单,量化收益只在大规模或内存受限时才体现。规避:先跑IndexFlatL2建立精度与延迟基线,再决定是否压缩

Faiss 1.11.0 让向量检索的内存和延迟收益集中在nb_bits一个参数上,配合内存映射反序列化,大索引的加载和部署都更省力。想继续深入,可以从以下三个入口看起:

  • benchs/bench_rabitq.py:RaBitQ 官方基准脚本,含计时与召回计算
  • faiss/impl/RaBitQuantizer.h:量化器核心接口与码长、解码语义的注释
  • INSTALL.md:源码编译与安装的完整说明

【免费下载链接】faissA library for efficient similarity search and clustering of dense vectors.项目地址: https://gitcode.com/GitHub_Trending/fa/faiss

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询