返回

文章详情

Turbovec – Google 的 TurboQuant 用于 Rust 中的向量搜索

Hacker News2026年8月18日 18:07

一个包含 1000 万份文档的语料库使用 31GB 的 RAM 作为 float32。turbovec 将其压缩到 4GB 并且比 FAISS 快。turbovec 是一个 Rust 向量索引,带有 Python 绑定,基于 Google Research 的 TurboQuant 算法构建——一种数据无关的量化器,具有近乎最佳的失真,无需单独的训练阶段。在线摄取。添加向量,它们会被索引——没有训练步骤,没有参数调整,随着语料库的增长无需重建。快速的 SIMD 搜索。手写内核——ARM 上的 NEON SDOT/SMMLA,x86 上的 AVX-512 VNNI 和 vpermb,以及 AVX2 和标量回退——在每个测量配置中都优于 FAISS IndexPQFastScan,平均在 4 位时快 3.4 倍,在 2 位时快 23%,两种架构均如此。增量保存。sync(path) 仅保留自上次同步以来更改的内容——每次调用一次 fsync,无论是任何字节都能保证故障安全,删除或小型追加的成本为毫秒,无论索引多大。write/load 保留整文件快照。搜索时过滤。传递一个 id 允许列表(或一个槽位位掩码)到 search(),内核会直接遵从。您始终会从允许的集合中获得最多 k 个结果——没有过度提取,选择性过滤没有召回损失。完全本地。没有托管服务,没有数据离开您的机器或 VPC。与任何开源嵌入模型配对,构建完全隔离的 RAG 堆栈。在隐私、内存或延迟至关重要的情况下构建 RAG?您来对地方了。pip install turbovec from turbovec import TurboQuantIndex index = TurboQuantIndex ( dim = 1536 , bit_width = 4 ) index . add ( vectors ) index . add ( more_vectors ) scores , indices = index . search ( query , k = 10 ) index . write ( "my_index.tv" ) loaded = TurboQuantIndex . load ( "my_index.tv" ) index . sync ( "my_index.tv" ) # 更改后:持久增量保存向量和查询是形状为 (n, dim) 的 2-D float32 数组——如果需要,其他数据类型会被拒绝而不是安静地转换,因此请先使用 np.asarray(x, dtype=np.float32) 进行转换。需要在删除后仍能生存的稳定 ids?使用 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 是您的 uint64 外部 ids index . remove ( 1002 ) # O(1) 通过 id index . write ( "my_index.tvim" ) loaded = IdMapIndex . load ( "my_index.tvim" ) index . sync ( "my_index.tvim" ) # 持久增量保存,包含 ids 混合检索(过滤搜索)限制结果为来自另一个系统(SQL、BM25、ACL、时间窗口等)的候选集合: import numpy as np from turbovec import IdMapIndex idx = IdMapIndex ( dim = 1536 , bit_width = 4 ) idx . add_with_ids ( vectors , ids ) # 第 1 步:外部系统缩小到候选 ids。 allowed = np . array ( db . execute ( "SELECT id FROM docs WHERE tenant=?" , ( t ,)). fetchall (), dtype = np . uint64 ) # 第 2 步:在候选集内进行密集重排名。 scores , ids = idx . search ( query , k = 10 , allowlist = allowed ) 过滤发生在 SIMD 内核内,粒度为 32 向量块:没有允许槽的块在任何 LUT 查找或评分工作之前被短路,并且在评分块内部个别非允许槽在堆插入时会被丢弃。选择性允许列表(允许的索引的小部分)因此避免了大部分的 SIMD 成本,而不是事后支付并丢弃结果。输出长度为 min(k, n_allowed),其中 n_allowed 计算独特的允许向量——当允许的向量少于 k 时,您只会得到实际的结果,而不是填充的回退。请参阅 docs/api.md 查看完整参考。框架集成 各个框架中树内引用的向量/文档存储的即插即用替代品。相同的公共表面,相同的持久语义,相同的检索器和管道接线——交换导入并保留您的管道。LangChain — pip install turbovec[langchain] · 替代 langchain_core.vectorstores.InMemoryVectorStore LlamaIndex — pip install turbovec[llama-index] · 替代 llama_index.core.vector_stores.SimpleVectorStore Haystack — pip install turbovec[haystack] · 替代 haystack.document_stores.in_memory.InMemoryDocumentStore Agno — pip install turbovec[agno] · 替代 agno.vectordb.lancedb.LanceDb Rust cargo add 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 ( ) ; 对于能在删除后生存的稳定外部 ids:使用 turbovec :: IdMapIndex ; let mut index = IdMapIndex :: new ( 1536 , 4 ) . unwrap ( ) ; index . add_with_ids ( & vectors , & [ 1001 , 1002 , 1003 ] ) . unwrap ( ) ; let ( scores , ids ) = index . search ( & queries , 10 ) ; index . remove ( 1002 ) ; index . write ( "index.tvim" ) . unwrap ( ) ; let loaded = IdMapIndex

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡