TurboVec 高性能向量库

RyanCodrai/turbovec 访问 GitHub ↗
🔤 Rust ★ 15939 ⑂ 0 daily #17 (+230) 抓取 2026-08-21

一句话简介

基于 Rust 编写的高性能向量检索库,提供快速相似度搜索与近似最近邻功能,适用于大规模嵌入数据场景。

标签

  • Rust
  • 向量检索
  • 近似最近邻
  • 机器学习
  • 高性能计算

适用应用场景

  • 推荐系统中的相似内容检索
  • RAG 应用中的文档嵌入检索
  • 图像与文本嵌入的语义搜索
  • 大规模向量数据的快速聚类与去重

README 中文摘要

项目概览

turbovec 是一个基于 Google Research 的 TurboQuant 算法构建的高性能向量索引库,提供 Rust 核心与 Python 绑定。它采用与数据无关的量化方式,无需训练阶段即可实现接近最优的失真率。典型场景下,1000 万文档的 float32 语料库约需 31 GB 内存,turbovec 可压缩至 4 GB,且搜索速度优于 FAISS。

核心特性

  • 在线写入:向量加入即索引,无需训练、无需调参,语料增长时无需重建。
  • SIMD 加速搜索:ARM 平台使用 NEON SDOT/SMMLA,x86 平台使用 AVX-512 VNNIvpermb,并具备 AVX2 与标量回退路径。
  • 增量持久化sync(path) 仅写入自上次同步以来变更的内容,单次 fsync 即保证崩溃安全,删除与小批量追加开销均为毫秒级。
  • 搜索时过滤:通过 allowlist 或槽位位掩码直接在 SIMD 内核中过滤,以 32 向量块粒度短路无关块,避免过取与召回损失。
  • 纯本地运行:无托管服务,数据不离开本机或 VPC,可与开源嵌入模型组成完全离线的 RAG 栈。

Python 用法

pip install turbovec
from turbovec import TurboQuantIndex

index = TurboQuantIndex(dim=1536, bit_width=4)
index.add(vectors)                       # vectors 必须是 (n, dim) 的 float32
scores, indices = index.search(query, k=10)

index.write("my_index.tv")               # 整文件快照
loaded = TurboQuantIndex.load("my_index.tv")
index.sync("my_index.tv")                # 增量持久化

需要稳定的外部 ID 时使用 IdMapIndex,支持 add_with_idsremove(id) 与 O(1) 删除:

from turbovec import IdMapIndex
import numpy as np

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)
index.remove(1002)

混合检索

先由 SQL/BM25 等系统产出候选集,再调用带 allowlistsearch() 进行稠密重排:

allowed = np.array([...], dtype=np.uint64)   # 外部系统的候选 id
scores, ids = idx.search(query, k=10, allowlist=allowed)

输出长度等于 min(k, n_allowed),不会用回填项凑数。

框架集成

turbovec 提供各主流框架内置向量库的即插即用替换:

  • LangChain:pip install turbovec[langchain]
  • LlamaIndex:pip install turbovec[llama-index]
  • Haystack:pip install turbovec[haystack]
  • Agno:pip install turbovec[agno]

Rust 用法

# Cargo.toml
turbovec = "..."
use turbovec::TurboQuantIndex;

let mut index = TurboQuantIndex::new(1536, 4).unwrap();
index.add(&vectors);
let results = index.search(&queries, 10);
index.write("index.tv").unwrap();
let loaded = TurboQuantIndex::load("index.tv").unwrap();

需要稳定 ID 与删除语义时使用 IdMapIndex,API 与 Python 端对齐。

性能与召回

在 100K 向量、k=64 的测试集上:

  • 搜索速度:ARM 与 x86 平台均全面领先 FAISS IndexPQFastScan。4-bit 平均 3.4× 加速,2-bit 平均提升 20–26%。
  • 插入延迟:单向量 add() 耗时 6.3–19.7 µs,比 FAISS 快 7.6–13.9 倍;100 向量批量摊销到 4.6–16.3 µs/向量。
  • 删除延迟IdMapIndex.remove(id) 介于 0.44–1.37 µs/op,而 FAISS 的 remove_ids 在 100K 规模下单次删除需要 0.19–1.02 s。
  • 召回率:在 OpenAI d=1536 / d=3072 上,校准版(TQ+)在 R@1 上 4 档中有 3 档胜 FAISS(领先 0.9–2.9 点);GloVe d=200 低维场景下,4-bit R@1 领先 +1.9 点,2-bit R@1 领先 +0.8 点。

压缩与持久化

1536 维向量从 6,144 字节(FP32)压缩到 384 字节(2-bit),达 16× 压缩率。save → load → 首查 流程基于单文件 .tv 格式,配合 fsync + 原子重命名保证崩溃一致性。

算法原理

  1. 归一化:剥离向量模长,仅保留方向。
  2. 随机旋转:与同一正交矩阵相乘,使各坐标独立服从 Beta 分布(高维下趋近 N(0, 1/d))。
  3. 逐坐标校准(可选 TQ+):用 ~1024 个样本拟合每维的 shift/scale,把经验分位数映射到码本边界。校准后无需重训,可用 index.calibration_state 查看状态。
  4. Lloyd-Max 标量量化:根据已知分布预先计算最优码本,2-bit 4 个桶,4-bit 16 个桶。
  5. 位打包:按字节紧密存储。
  6. 长度重归一化打分:编码时为每个向量存一个标量 ||v|| / ⟨u, x̂⟩,搜索内核在堆插入前乘回,消除 SQ 对内积的下偏。

构建与基准测试

Python 端通过 maturin 构建:

pip install maturin
cd turbovec-python
maturin build --release
pip install target/wheels/*.whl

x86_64 默认编译基线为 x86-64-v2(SSE4.2,Nehalem 2008+),AVX-512/AVX2 内核通过 is_x86_feature_detected! 在运行时启用。

数据集下载与基准运行:

python3 benchmarks/download_data.py all
python3 benchmarks/suite/speed_d1536_2bit_arm_mt.py
python3 benchmarks/suite/recall_d1536_2bit.py
python3 benchmarks/create_diagrams.py     # 重新生成图表

针对优化迭代,提供 Rust 版 insert_bench 工具(合成向量、确定性、无需数据集与 FAISS),便于在数秒内验证假设:

cargo run --release --example insert_bench -- --dim 1536 --bits 2

适用场景

在 RAG 应用中,turbovec 适合对隐私、内存占用、查询延迟敏感的场景。其本地化运行特性便于搭配任意开源嵌入模型,构建完全离线的检索增强生成栈。

参考资料

摘要更新于 2026-08-21 00:33:12 · 原文 24658 字符 · md5 2f316dcea3b5…