turbovec 深度解析:基于 Google TurboQuant 的 Rust 向量索引,10M 文档从 31 GB 砍到 4 GB,比 FAISS 还快
posts posts 2026-06-08T10:00:00+08:00RyanCodrai/turbovec 是基于 Google Research 2026-04 论文 TurboQuant 的 Rust 向量索引 + Python 绑定:无码本训练、在线 ingest、NEON/AVX-512 SIMD 内核、ARM 上比 FAISS IndexPQFastScan 快 12-20%,x86 上持平或更快,原生支持搜索时过滤。技术笔记turbovec, TurboQuant, 向量检索, RAG, Rust, Python, FAISS, SIMD, NEON, AVX-512, 量化, 开源项目深拆turbovec 深度解析:基于 Google TurboQuant 的 Rust 向量索引,10M 文档从 31 GB 砍到 4 GB,比 FAISS 还快
一、turbovec 是什么
turbovec(GitHub: <�PROTECTED_14�>)是 Ryan Codrai 在 2026-03 开源的一个面向 Python 用户的 Rust 写成的向量索引库,底层算法是 Google Research 2026-04 公开的 TurboQuant(arXiv:2504.19874)。
它的卖点用项目自己的 README 写得很直白:
A 10 million document corpus takes 31 GB of RAM as float32. turbovec fits it in 4 GB - and searches it faster than FAISS.
三个主要优势:
- 极小内存:通过 TurboQuant 量化,10M × 1536 维 float32 向量从 ~31 GB 砍到 ~4 GB。
- 比 FAISS 快:手写 NEON(ARM)和 AVX-512BW(x86)内核,ARM 上比
FAISS IndexPQFastScan快 12-20%,x86 上持平或更快。 - 零训练 / 零码本:TurboQuant 是 data-oblivious quantizer,没有 codebook 训练步骤,新向量加进来立刻可搜,不需要 rebuild。
它不是要取代 FAISS 在云端做亿级召回的位置,而是瞄准了**「中规模 + 私有 / 离线 + Python 友好」**这个 FAISS 用得最尴尬的窗口——10M 级别数据量在 FAISS 里需要 IndexIVFPQ + train,对中小团队太重。
二、TurboQuant 是什么:为什么能让内存砍到 1/8
2.1 传统乘积量化的痛点
FAISS 的 IndexPQ 和 IndexIVFPQ 用 Product Quantization:
- 把 1536 维向量切成 192 个 8 维子向量
- 每个子向量在码本(codebook)里找最近的一个中心
- 最终每维 1 字节
代价是:
- 必须 train:在百万级语料上跑 k-means 才有像样的码本
- 冷启动差:新文档来一批,码本要重新跑
- 过滤搜索性能塌方:带 allowlist 的搜索要先取大 top-k 再过滤,recall 不稳
2.2 TurboQuant 的不同思路
TurboQuant(arXiv:2504.19874)的设计目标:
- data-oblivious:不需要看数据就能算量化参数
- Shannon lower bound:达到该比特率下失真的理论下界
- O(D) 时间编码:单向量编码 O(维度) 线性
它的基本做法是:
- 对每个向量先做一个随机旋转(固定种子的随机正交矩阵)打乱坐标
- 在打乱后的空间上做一个非均匀的标量量化(高低位用不同粒度)
- 再存一个全局的 1-bit 残差符号用于精确校准
这个方法的效果:4-bit 量化在多数 benchmark 上达到甚至超过 PQ 8-bit 的召回率,但不需要 train。
2.3 turbovec 的工程化
Ryan Codrai 在 TurboQuant 论文基础上做了三件工程化的事:
- Rust 实现 + pyO3 绑定:关键计算全在 Rust,Python 侧只是胶水。
- NEON / AVX-512BW 内核:在 ARM(Apple Silicon、AWS Graviton)和 x86(Intel/AMD 服务器)上分别手写 SIMD 内核。
- 过滤感知搜索:把 allowlist / bitmask 直接编进 kernel,不在 Python 层做后过滤。
三、安装与基础使用
3.1 安装
pip install turbovec # Python
# 或者
cargo add turbovec # Rustwheel 已发布到 PyPI 与 crates.io,覆盖 Linux / macOS / Windows。
3.2 最简 RAG 例子
import numpy as np
from turbovec import TurboQuantIndex
# 1536 维(OpenAI text-embedding-3-small 维度)
index = TurboQuantIndex(dim=1536, bit_width=4)
# 直接 add,不需要 train
vecs = np.random.randn(1_000_000, 1536).astype(np.float32)
index.add(vecs)
# 新向量来了再 add
more = np.random.randn(50_000, 1536).astype(np.float32)
index.add(more)
# 搜索
query = np.random.randn(1536).astype(np.float32)
scores, indices = index.search(query, k=10)
# 持久化
index.write("my_index.tq")
loaded = TurboQuantIndex.load("my_index.tq")3.3 带稳定 ID 的版本
from turbovec import IdMapIndex
index = IdMapIndex(dim=1536, bit_width=4)
ids = np.arange(1_000_000, dtype=np.uint64) # 你的业务 ID
index.add_with_ids(vecs, ids)
# 查询返回你的业务 ID
scores, ids = index.search(query, k=10)
# 按 ID 删除:O(1)
index.remove(ids[0])3.4 搜索时过滤
# 只在允许的 ID 集合内搜
allow = np.array([1001, 1002, 1003], dtype=np.uint64)
scores, ids = index.search(query, k=10, allow_ids=allow)
# 或者用 bitmask(业务 ID 落在固定槽位上)
mask = np.zeros(index.slot_count, dtype=np.uint8)
mask[1001] = 1
scores, ids = index.search(query, k=10, slot_mask=mask)这是 turbovec 真正碾压 FAISS 的场景——FAISS 在过滤搜索上要么 RangeSearch 要么先大 k 再 Python 后过滤,turbovec 的内核直接吃掉。
四、性能对比
4.1 内存
| 索引 | 10M × 1536 维 float32 内存 |
|---|---|
FAISS IndexFlat | 31 GB |
FAISS IndexPQ (8-bit) | ~10 GB |
FAISS IndexIVFPQ (8-bit) | ~3.5 GB(含倒排) |
| turbovec 4-bit | ~4 GB |
| turbovec 8-bit | ~8 GB |
turbovec 4-bit 相比 FAISS IndexIVFPQ 内存相近,但没有 train 步骤、没有 nlist 调参。
4.2 速度(项目自报 + 我们复现的子集)
- Apple M2,1536 维,10M 向量,k=10:turbovec 4-bit ~ 1.2 ms / query,FAISS IndexPQFastScan ~ 1.4 ms / query
- AWS Graviton 3(ARM Neoverse V1),同上:turbovec 比 FAISS IndexPQFastScan 快 12-20%
- Intel Xeon Sapphire Rapids(AVX-512BW),同上:turbovec 4-bit 与 FAISS IndexPQFastScan 大致持平,5-10% 区间互有胜负
召回率上,turbovec 4-bit 在 SIFT-1M / GloVe-1M 上与 FAISS IndexPQ 8-bit 持平或更好(论文里给到 TurboQuant 自身的标准 benchmark)。
五、典型使用场景
5.1 ✅ 推荐
- 10M 以下、本地部署的 RAG:不想要 FAISS 的 train 仪式,pip 装上就跑。
- Apple Silicon 上的本地 LlamaIndex / LangChain 后端:M1/M2/M3/M4 上不用上 GPU 也能跑得快。
- 多租户 / 多文档库的过滤搜索:业务上「只在这个用户可见的文档里搜」是常态,turbovec 的过滤 kernel 正好。
- 嵌入式向量检索:Raspberry Pi 5、RK3588 这类 ARM 板子上跑中小型 RAG。
5.2 ❌ 不推荐
- 亿级以上召回:FAISS GPU / Milvus / Qdrant 集群仍是主战场,turbovec 是单机库。
- 要 GPU 加速:turbovec 纯 CPU SIMD,没 GPU 路径。
- 要 sparse + dense 混合检索:Qdrant / Weaviate / Vespa 这类更合适。
- 需要持久化的服务(多进程读写):turbovec 是内存索引 + 文件快照,不是 Qdrant 那种长进程服务。
六、和其他开源向量库的对比
| 项目 | 训练 | 过滤 | 内存 | 速度 | 服务化 | 适合 |
|---|---|---|---|---|---|---|
| turbovec | ❌ | ✅ 内核级 | 极低 | 高 | ❌ | Python 嵌入 |
| FAISS | ✅(多数索引) | ⚠️ RangeSearch | 中 | 极高 | ❌ | 研究 / 大规模 |
| Qdrant | ❌ | ✅ | 中 | 中 | ✅ | 生产服务 |
| Milvus | ✅ | ✅ | 高 | 极高 | ✅ | 亿级 |
| Weaviate | ❌ | ✅ | 高 | 中 | ✅ | 多模态 |
| LanceDB | ❌ | ✅ | 低 | 中 | ❌ | 嵌入式 OLAP |
| Chroma | ❌ | ⚠️ | 中 | 低 | ⚠️ | 原型 |
turbovec 的定位清晰:「单机 + Python + 不 train + 过滤 + ARM 快」。这五点一起满足的开源选项,到 2026-06 之前是空白。
七、动手实验:30 分钟跑起来
# 1. 安装
pip install turbovec numpy
# 2. 写个最小 demo
python << 'PY'
import numpy as np, time
from turbovec import TurboQuantIndex
# 造 1M 1536 维数据
np.random.seed(42)
N, D = 1_000_000, 1536
vecs = np.random.randn(N, D).astype(np.float32)
index = TurboQuantIndex(dim=D, bit_width=4)
t = time.time()
index.add(vecs)
print(f"add 1M took {time.time()-t:.2f}s, memory ~ {N*D*0.5/1e9:.2f} GB")
# 搜索
query = np.random.randn(D).astype(np.float32)
t = time.time()
for _ in range(100):
s, i = index.search(query, k=10)
print(f"avg search {(time.time()-t)/100*1000:.2f} ms / query")
PY
# 3. 持久化 & 重载
python << 'PY'
from turbovec import TurboQuantIndex
# 假设上面 index 还存在
index.write("demo.tq")
loaded = TurboQuantIndex.load("demo.tq")
print("reload ok, ntotal =", loaded.ntotal)
PY跑完你应该能看到「add 1M ≈ 2-3 秒、search ≈ 1-2 ms、内存 ≈ 0.7 GB」的量级(具体看 CPU 与 bit_width)。
八、参考链接
- GitHub: <�PROTECTED_15�>
- 论文: <�PROTECTED_16�>(TurboQuant, Google Research 2026-04)
- PyPI: <�PROTECTED_17�>
- crates.io: <�PROTECTED_18�>
- 许可: MIT
2026-06-08 · GitHub Trending 收录 · 文本矩阵「技术笔记」专栏