alitrack

我给DuckDB写了个向量搜索插件,31GB→4GB

DuckDB 的分析能力很强,但向量搜索一直是个缺口。社区里有人用 Python 在 DuckDB 外面跑 FAISS,有人用 pgvector 扩展 PostgreSQL 来做——但都得引入外部依赖。

我也想在 DuckDB 里直接做向量搜索。不用 Python,不用 pgvector,不用任何外部工具。

所以写了 duckdb_turbovec。

● ● ●

它做了什么

duckdb_turbovec 是一个 DuckDB 扩展,把 Google 的 TurboQuant 量化算法(ICLR 2026)搬进了 DuckDB。

粗暴地说:用 2-4 bit 压缩向量,搜索精度损失不到 1%,体积缩小 8-16 倍。

它是 DuckDB 生态里第一个 TurboQuant 扩展——也是目前唯一一个。

架构

架构

● ● ●

三种构建模式

安装后只需要 LOAD 'turbovec.duckdb_extension':

扁平索引(适合小规模):

SET VARIABLE vec_str = (SELECT string_agg(emb::VARCHAR, ',') FROM documents); SELECT * FROM turboquant_build(getvariable('vec_str'), 1536, 4, '/tmp/myidx.tv');

直接传 LIST(dim 自动检测):

SELECT * FROM turboquant_build_list(   [0.1,0.2,0.3,0.4, 0.2,0.1,0.4,0.3], 4, '/tmp/myidx.tv' );

IVF 索引(大规模,K-means 分区):

SELECT * FROM turboquant_build_ivf(   getvariable('vec_str'), 1536, 4, 256, '/tmp/myivf/' );

搜索也简单:

SELECT * FROM turboquant_search('/tmp/myidx.tv', '[0.1, 0.2, ...]', 10); SELECT * FROM turboquant_search_ivf('/tmp/myivf/', '[0.1, 0.2, ...]', 10, 8);

● ● ●

实测数据

拿 1,154 条 1024 维向量在本地跑了一下:

指标
数值
原始大小
4.6 MB
压缩后
301 KB(4-bit, 15×)
构建速度
0.46s(2,533 vec/s)
查询延迟
71 ms / 查询
Recall@1/3/5
100% / 100% / 99.2%

71ms 比 brute-force 的 47ms 慢——因为 TurboQuant 的开销在小数据集上不划算,break-even 大约 10K 向量以上。但一到万级,优势就出来:TurboQuant 论文里 1M×1536d 从 31GB 压到 4GB(8×),PG 的 pg_turbovec 用 2-bit 能做到 412MB(20×)。

ARM 上比 FAISS FastScan 快 12-20%。x86 上有 AVX-512 加速。

● ● ●

为什么不是 pgvector?

PostgreSQL 生态已经有 pgvector、pg_turbovec(412MB 存 100 万向量)、pg_turboquant(比 HNSW 快 12%)。

但如果你的数据已经在 DuckDB 里——每天用 DuckDB 跑分析,顺带想搜一下最相似的向量——装个 PostgreSQL 再导数据完全是多余操作。一个 LOAD 就够了。

● ● ●

v0.3.0 更新

v0.2.0 时有三个明显短板。v0.3.0 全修了:

① 增量 CRUD — 不用重建索引了:

SELECT * FROM turboquant_add('/tmp/myidx.tv', '[[0.3,0.1,...]]', 1536); SELECT * FROM turboquant_remove('/tmp/myidx.tv', 0);

底层是 turbovec 的 swap_remove(O(1))。

② 简化输入 — turboquant_build_concat 接受扁平逗号分隔的浮点数:

SET VARIABLE v = (SELECT string_agg(emb::VARCHAR, ',') FROM documents); SELECT * FROM turboquant_build_concat('/tmp/idx.tv', 1024, 4, getvariable('v'));

③ IVF 自动全扫 — probes=0 扫描所有 cluster:

SELECT * FROM turboquant_search_ivf('/tmp/myivf/', '[0.1, ...]', 10, 0);

22 个集成测试,三平台 CI 全绿。

● ● ●

试试看

git clone [email protected]:alitrack/duckdb_turbovec.git && cd duckdb_turbovec cargo build --release python3 scripts/metadata.py target/release/libturbovec.so -o turbovec.duckdb_extension duckdb -c "LOAD 'turbovec.duckdb_extension'; SELECT * FROM turboquant_build_list(..., 4, '/tmp/test.tv');"

MIT 协议。macOS、Linux、Windows 都能跑。如果你也在用 DuckDB 做分析,顺带想搜一下最相似的向量——可以试试这个。