📌 项目地址:RyanCodrai/turbovec | ⭐ 6,292 颗星 | 🔧 Python | 📜 未标注
核心价值:内存与速度的极致压缩
向量检索的痛点很直接:当数据量达到千万级,32 位浮点数存储占据 31GB 内存,而实际有用的语义信息远没有这么多。turbovec 基于 Google Research 的 TurboQuant 算法,将每个向量压缩到 4 比特,同一份 1000 万文档的 corpus 只需约 4GB——并且搜索速度还比 FAISS 更快。
关键设计是 data-oblivious:不需要训练码本、不需要单独的 train 阶段、不需要随着索引增长而重建。与 FAISS 的 IndexPQFastScan 相比,turbovec 的 Rust 手写 NEON(ARM)和 AVX-512BW(x86)内核在 ARM 上快 12–20%,在 x86 上持平或更快。
实际用法:两分钟上手
pip install turbovec
基础用法极其简洁:
from turbovec import TurboQuantIndex
index = TurboQuantIndex(dim=1536, bit_width=4)
index.add(vectors) # 在线添加,无需 train
index.add(more_vectors) # 可增量添加
scores, indices = index.search(query, k=10)
# 持久化
index.write("my_index.tq")
loaded = TurboQuantIndex.load("my_index.tq")
如果文档需要稳定的外部 ID(即使在删除后 ID 保持不变),使用 IdMapIndex:
import numpy as np
from turbovec import IdMapIndex
index = IdMapIndex(dim=1536, bit_width=4)
index.add_with_ids(vectors, np.array([1001, 1002, 1003], dtype=np.uint64))
scores, ids = index.search(query, k=10) # ids 是外部 ID
index.remove(1002) # O(1) 删除
index.write("my_index.tvim")
loaded = IdMapIndex.load("my_index.tvim")
add_with_ids 的 ID 必须是无符号 64 位整数,删除操作是常数时间。
过滤搜索:混合检索的正确姿势
实际 RAG 系统中,往往先用关键词(BM25)、时间窗口、租户隔离等外部系统筛选出一个候选 ID 集合,再对这些候选文本进行向量重排序。传统做法是先全量搜索再过滤,这会浪费 SIMD 资源。turbovec 的 search() 方法支持 allowlist 参数:
# Stage 1: 外部系统(SQL/BM25/ACL)筛选出候选 ID
allowed = np.array(db.execute("SELECT id FROM docs WHERE tenant=?", (t,)).fetchall(),
dtype=np.uint64)
# Stage 2: 仅在候选集合内做向量重排序
scores, ids = idx.search(query, k=10, allowlist=allowed)
关键优化:SIMD 内核在 32 向量块级别检查 allowlist,如果某个块完全不在候选集内,直接跳过整个块的 LUT 查找和打分;对于块内部分允许的槽位,只在插入堆时丢弃非允许结果。当候选集很小(比如只占索引的百分之几)时,大部分 SIMD 开销被避免,而不是先算完再过滤。
返回结果数量是 min(k, len(allowed)),不会因为候选集不足 k 而产生错误。
与同类工具的区别
| 特性 | turbovec | FAISS (IVF+PQ) |
|---|---|---|
| 量化训练 | 无需训练,data-oblivious | 需要训练码本(train 步骤) |
| 增量添加 | 直接 add,无需重建 | 需重建索引或使用 IndexIDMap 等特殊结构 |
| 过滤搜索 | 集成在 SIMD 内核中,零额外开销 | 需后过滤或使用 RangeSearch |
| 量化精度 | 4 比特,达到 Shannon 下界 | 常用 8 比特或 4 比特(需训练) |
| 平台加速 | 手写 NEON / AVX-512BW | 通用向量化,依赖编译器 |
turbovec 更适合 纯本地、内存敏感、需要频繁添加/删除向量 的场景。如果已经有现成的 FAISS 索引且不需要增量更新,迁移成本需要考虑。另外 turbovec 当前只支持 L2 距离或内积(需确认 README 没有明确说明距离度量,但实践中通常用内积或 L2),建议参考官方文档确认。
注意事项
- 许可证:项目 GitHub 仓库没有在 README 中明确许可证,使用前应检查仓库 License 文件。
- 依赖:Python 包已发布在 PyPI,底层是 Rust 二进制,安装时可能需要本机支持 AVX-512BW 或 NEON 指令集以获得最佳性能。
- 精度:4 比特量化虽然压缩率惊人,但召回率取决于数据类型和分布。对于 high recall 要求(如 >95%),建议在自己的数据集上对比原始浮点搜索的 recall。
- 唯一索引:
IdMapIndex支持删除,但TurboQuantIndex的 add 是按顺序分配内部 slot,无外部 ID;如果需要稳定 ID 和删除,必须用IdMapIndex。 - 内存:虽然压缩到 4GB,但写入和加载时可能有临时缓冲区,生产环境需预留 2–3 倍内存余量。
turbovec 是一个将学术前沿量化算法(TurboQuant)工程化的高效实现,特别适合构建隐私敏感、资源受限的 RAG 系统。如果目前正在用 FAISS 但受困于内存和索引重建成本,值得一试。