背景
最近在搞 RAG 相关的东西,向量数据库这块一直用的 FAISS。用着没啥大毛病,但有个痛点:内存占用太大。
1000万条 1536 维的向量,float32 存储直接干到 31GB。服务器内存吃不住,量化方案又得单独跑 train 阶段,数据量小了码本质量还拉胯。
然后在 arXiv 上刷到一篇 Google Research 的论文——TurboQuant(ICLR 2026),顺着论文找到了它的 Rust 实现:turbovec。
试了一下,真香。
turbovec 是什么
一句话:基于 TurboQuant 算法的向量索引库,Rust 写的,有 Python 绑定。
核心卖点:
- 1000万 1536 维向量,31GB → 4GB
- 没有 train 阶段,
add()直接索引 - 比 FAISS IndexPQFastScan 快 12-20%(ARM)/ 持平或略快(x86)
- 纯本地,数据不出机器
GitHub: RyanCodrai/turbovec(9K+ stars)
技术原理(简化版)
TurboQuant 的核心思路挺巧妙的:
- 归一化:把向量长度去掉,变成超球面上的单位方向
- 随机正交旋转:旋转之后,每个坐标独立服从已知的 Beta 分布。关键点——这个分布跟输入数据无关,是数学上能推导出来的
- Lloyd-Max 量化:既然分布已知,最优的桶边界可以直接算出来,不需要从数据里学
- Bit-pack:1536维向量从 6144 字节压到 384 字节,16 倍压缩
省掉了 train 阶段,意味着:
- 数据量小也能用
- 在线添加新向量不需要重建索引
- 没有超参数调优的烦恼
实际用法
pip install turbovec
基础用法真的很简单:
from turbovec import TurboQuantIndex
index = TurboQuantIndex(dim=1536, bit_width=4)
index.add(vectors) # 直接 add,不用 train
index.add(more_vectors) # 随时加,不用重建
scores, indices = index.search(query, k=10)
# 持久化
index.write("my_index.tq")
loaded = TurboQuantIndex.load("my_index.tq")
需要稳定 ID 的场景(比如要删除某些向量),用 IdMapIndex:
import numpy as np
from turbovec import IdMapIndex
idx = IdMapIndex(dim=1536, bit_width=4)
idx.add_with_ids(vectors, np.array([1001, 1002, 1003], dtype=np.uint64))
scores, ids = idx.search(query, k=10) # 返回你自己的 uint64 id
idx.remove(1002) # O(1) 删除
最让我惊喜的是内核级过滤:
# SQL 先粗筛出候选 id
allowed = np.array(db.execute(
"SELECT id FROM docs WHERE tenant=?", (t,)
).fetchall(), dtype=np.uint64)
# 向量搜索时直接过滤,没有过取、没有召回损失
scores, ids = idx.search(query, k=10, allowlist=allowed)
过滤是在 SIMD 内核里做的,32 个向量一组,没有 allowed 的直接跳过,比"先搜再过滤"高效得多。
性能对比
官方 benchmark 数据(100K 向量, k=64, 中位数 5 次):
ARM (Apple M3 Max):
- 2-bit 单线程:比 FAISS FastScan 快 ~15%
- 4-bit 单线程:快 ~12-20%
x86 (Intel Xeon Sapphire Rapids):
- 4-bit:快 1-6%
- 2-bit:基本持平
召回率方面,OpenAI 1536/3072 维上比 FAISS IndexPQ 高 0.4-3.4 个百分点(@1)。
适配情况
- Python 3.9-3.14
- macOS + Linux(没有 Windows)
- x86 要求 AVX2(Haswell 2013+),AVX-512 运行时自动检测
- ARM 用 NEON
框架集成:LangChain / LlamaIndex / Haystack / Agno 都有 drop-in 替换。
坑和注意
- Alpha 阶段 — PyPI 标记的 Development Status 是 Alpha,生产环境慎用
- 低维数据 — GloVe d=200 这种,2-bit 下召回率比 FAISS 略低(Beta 假设在低维更松)
- x86 2-bit 多线程 — 唯一略微跑输 FAISS 的配置(2-4%)
- 没 Windows — 目前只支持 macOS 和 Linux
总结
如果你的场景是:
- 内存紧张
- 需要在线增删向量
- 不想折腾 train 阶段
- 纯本地部署
turbovec 值得试试。4GB 存原来 31GB 的数据,还不用 train,这个吸引力够大了。
我已经在自己的 RAG 项目里从 FAISS 切过去了,目前没踩坑。后续有坑再更新。
参考:
- TurboQuant 论文(ICLR 2026)
- turbovec GitHub
- FAISS FastScan