首页 / 文章

turbovec:使用 Rust 语言中的 TurboQuant 将 RAG 嵌入向量压缩16倍

TurboVec将Google的TurboQuant引入Rust语言,且无需训练即可将RAG嵌入索引的大小缩小16倍。它在哪些方面优于FAISS,以及还有哪些工具更适用。

发布者:REACTAPP.TOP阅读约 10 分钟2219 词

来源: turbovec for RAG: A Practical Guide to Faster, Smaller Vector Search

以实际投入使用的检索流程为例:有千万份文档,每份文档都使用 OpenAI 的 text-embedding-3-small 模型生成,维度为 1536,以 float32 格式存储。在添加任何元数据之前,仅这些向量就占了 31 GB 的空间。到了这种规模,“要在哪里运行?”已不再是一个随意的问题——这意味着需要一台内存庞大的云服务器,很可能由第三方托管,同时还伴随着各种隐私和运营方面的问题。

如果用 turbovec 以每维度 2 位的形式处理相同的数据,其体积会缩小到约 4 GB,这样的大小完全可以容纳在笔记本电脑的 RAM 中且还有剩余空间。本文的其余部分将解释这一现象的原理、何时该选择 turbovec,以及何时其他工具更为合适。

什么是 turbovec

turbovec 是一个带有 Python 绑定的 Rust 向量索引库,采用 MIT 许可证,在本文撰写时已在 GitHub 上获得约 950 个星标。它实现了 TurboQuant 算法,该算法由谷歌研究院和纽约大学的研究人员开发,并已被 ICLR 2026 接受。

有一个值得了解的细节:谷歌从未公开其自身算法的参考代码,因此社区挺身而出。RyanCodrai/turbovec 项目专注于向量搜索这一检索应用场景,而另一个名为 hackimov/turboquant-kv 的项目则将相同理念应用于压缩语言模型的 KV 缓存。这两者都是独立的开源项目。

换句话说,使用 turbovec 就意味着使用的是由社区实现的谷歌研究算法,而在 FAISS 团队自己使用的测试基准中,它的表现优于长期以来一直作为内存向量搜索生产标准的 Meta FAISS。

算法的工作原理

一旦了解其原理,就会发现这种方法出奇地简洁,总共分为四个步骤。

1. 分离长度与方向

每个嵌入向量都有一个模长(即其 L2 范数)和一个方向。将模长提取出来,以每个向量一个浮点数的形式保存,剩下的就是高维球面上的单位长度方向。这看似微不足道,但后续的所有操作都依赖于它,因为位于球面上的向量可以通过几何方法来处理。

2. 随机旋转

接下来,每个向量都会乘以同一个随机正交矩阵,该矩阵是通过高斯矩阵的QR分解生成一次的。初读时,这一步会让人感觉像魔术一般。

其原理在于:在高维空间中,随机旋转能使每个坐标的分布变得可预测。旋转之后,每个向量的每个坐标都会遵循一种已知且高度集中的贝塔分布,而随着维数增加,这种分布会逐渐趋近于高斯分布。无论输入是什么,其分布都保持不变。法律文件、产品评价和医学文献在统计上最终都会呈现相似的特征,因此该算法并不依赖具体数据。数学家将这种现象称为在球面上的测度集中,这也解释了为何无需训练过程:旋转就已经完成了通常需要训练过的代码本才能完成的工作。

3. 选择最优的桶

了解每个坐标所遵循的分布情况,就能提前确定对数值进行分桶的最佳方式。2位量化为每个坐标提供4个分桶,4位量化则提供16个分桶。这种计算方法被称为Lloyd-Max标量量化,它旨在回答一个简单的问题:在已知分布的情况下,应如何设定分界线才能使平均舍入误差降至最低?一旦知道了分布情况,其答案就可以用封闭形式得出。而且由于所有向量的旋转后分布都是相同的,因此分桶规则是由数学公式决定的,而非来自数据本身。

4. 打包比特

此时每个坐标都变成了一个较小的整数:2位量化时为0到3,4位量化时为0到15。经过紧密打包后,一个原本作为float32类型需要6,144字节的1536维向量,使用2位量化仅需384字节,而4位量化则需要768字节。这相当于实现了16倍和8倍的压缩率。

无需解压即可搜索

查询过程从不解压存储的数据。查询会被一次性转换到同一空间,然后直接通过与预先构建的查找表中的量化码进行比对。内部循环依赖SIMD指令,ARM平台使用NEON,最新款x86处理器使用AVX-512BW,而AVX2则作为备用方案。

正是在这里,该库与算法本身形成了区别并展现出优势。其自行编写的SIMD内核在ARM平台上的运行速度比FAISS的FastScan快12%到20%,在x86平台上则能与其持平或更快。

该方法背后还有理论依据。TurboQuant的相关论文证明,其失真度始终控制在信息论下限——香农失真率极限的约2.7倍以内。简单来说,信息论规定了数据在丢失前可以被压缩的最大程度,而TurboQuant无需任何训练即可将失真度控制在这一极限的2.7倍以内。在给定的比特预算下,没有其他方法能取得更好的效果,该论文也通过正式证明支持了这一结论。

三种适用场景

内存足够的情况

回到最初的数字:31 GB的float32数据,而使用2位编码的turbovec仅需要4 GB。如此小的索引大小改变了诸多可能性。

  • 它可以直接与应用程序同处一台服务器上,无需独立的向量数据库实例。
  • 开发人员可以在笔记本电脑上运行它进行本地测试。
  • 云实例中更便宜的内存层级变得可行,从而显著降低成本。
  • 整个索引都存储在RAM中,既没有数据溢出问题,也不需要在不同节点之间进行分片。
  • 对于向量数量在10万到1亿之间的集合——这涵盖了大多数知识库、文档网站、支持档案和产品目录——这就体现了是必须围绕向量索引进行设计,还是将其视为普通的Python对象之间的差异。

    隐私与物理隔离环境

    检索流程存在一个相当严重的隐私问题。以下两种攻击可以说明这一点:

    • BadRAG仅通过用精心制作的对抗性文档污染0.04%的文本集,就能达到98.2%的成功率。
    • Vec2Text能够从嵌入向量中恢复出原始短文本,准确率高达92%。

    嵌入向量并不具备任何加密保护,因此任何能够读取向量存储内容的人都可以恢复其中嵌入的数据。每次对云向量数据库的调用、每次向 OpenAI 发送的 embed() 请求,以及每次向 Pinecone 发送的 upsert() 操作,都是数据流出安全边界的机会。

    实际上已有许多系统实现了完全的物理隔离。加州大学圣地亚哥分校的 Onyx 能够为 37,000 名用户提供服务而无需依赖互联网,Ramp、Thales、L3Harris 和 Astranis 也采用了类似的架构。turbovec 自身的宣传语“无需托管服务,数据不会离开您的机器或 VPC”正好契合这类系统。若再搭配本地部署的嵌入模型,如 BGE-M3 或 BGE-large-en-v1.5,那么数据检索过程将完全不会产生任何外部网络调用。

    无需训练代码本

    这一优势具有结构性,容易被低估。传统的产品量化方法,即IndexPQ和IndexIVFPQ中所使用的PQ,需要基于代表性数据训练代码本。当数据发生变化,比如出现新的产品类别、新语言或新文档类型时,该代码本就会过时,从而导致检索效果下降。

    TurboQuant则完全不需要代码本。随机旋转机制使得无论输入数据是什么形式,数学模型都能正常运行。在实际应用中,这意味着:

    • 流式插入操作可以顺畅进行,无需批量重新训练。
    • 从OpenAI切换到BGE再到Voyage等不同的嵌入模型时,无需从头开始重建索引。
    • 多租户索引无需针对每个租户进行单独校准。
    • 由于不存在足够多的向量来训练有效的代码本,因此冷启动问题也不复存在。

    对于那些逐步扩展或涉及多种文档类型的系统而言,这种简洁性确实能带来巨大的运营优势。

    何时选择其他方案

    某些检索模式更适合用其他方法处理,应当明确指出这一点。

    • 高召回率检索。使用全精度向量的HNSW仍是最佳选择。turbovec虽然能实现16倍的压缩率,但会牺牲一些召回率,对于大多数RAG应用来说尚可接受;但如果漏检结果会造成严重后果,则这种折衷方案就不合适了。
    • 元数据过滤与混合搜索。turbovec仅是一个索引工具,没有配套的数据库。对于“查找与X相近的向量,且仅限于标记为合规性、编辑时间在2025年12月之后的文档”这类需求,就需要使用Qdrant、Weaviate、Milvus或pgvector这样的真正向量数据库。
  • 低维嵌入(256维或更低)。根据其README的说明,在d=200时,GloVe数据集上turbovec的召回率比FAISS低3到6个百分点,因为维度较小时Beta到高斯函数的近似程度更宽松,相关理论优势也会随之减弱。如果所使用的嵌入模型较旧或维度较低,FAISS是更稳妥的选择。
  • 数十亿向量规模的处理。turbovec会逐个扫描所有压缩后的向量,这种方式在向量数量约为1亿个以内时尚可,但超过这个数量后就需要借助IVF或基于图的分区技术,而turbovec并不具备这些功能。
  • 托管服务需求。对于那些需要带API密钥的托管向量数据库的团队而言,无论turbovec的工程实现有多出色,它都不是合适的选择。
  • 入门指南

    对于需要处理10万到1亿个维度为384或更高的向量,并且团队已准备好自行搭建基础设施的内存检索场景,以下是可行的实现方案:通过PyPI进行安装:

    pip install turbovec
    

    Rust 项目则通过添加 crate 来实现:

    cargo add turbovec
    

    基本用法只需几行代码即可构建索引并执行查询:

    from turbovec import TurboQuantIndex
    
    # Build the index
    index = TurboQuantIndex(dim=1536, bit_width=4)
    index.add(document_embeddings)
    # Search
    scores, indices = index.search(query_embedding, k=10)
    # Persist
    index.write("kb.tq")
    loaded = TurboQuantIndex.load("kb.tq")
    

    这就是简单情况下的全部参数设置。

    选择位宽

    这是最重要的设置,其权衡关系相当明确。

    • 2位:压缩率为float32的16倍,召回率差距较大,且对维度更敏感。
    • 4位:压缩率为8倍,在OpenAI的1536维和3072维嵌入数据上,其召回率基本与FAISS相当。当k值在4到8之间时,两者的召回率都会趋近于1.0。

    合理的默认值是4位。只有在实际测量了内存占用情况以及该设置对自身查询召回率的影响后,才考虑使用2位。

    选择索引类型

    有两种类型。TurboQuantIndex通过位置来访问向量,这种方式较为简单,且当ID仅按插入顺序排列时速度稍快。IdMapIndex允许你使用自定义的uint64 ID,并能以恒定时间删除条目,因此当键来自数据库或文档被删除时,它是更合适的选择。

    对于大多数RAG系统而言,IdMapIndex是更好的默认选项,因为应用数据库中的ID在删除和重建后依然存在,不会破坏外部引用。

    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)  # returns your IDs
    index.remove(1002)  # O(1) by ID
    

    嵌入模型

    对于需要物理隔离的检索场景,嵌入模型必须在本地运行,因为调用 OpenAI 的 API 会抵消隐私保护的优势。目前已有两种经过充分测试的组合:

    • BGE-M3 配合 turbovec。这是一种强大的多语言模型,可在本地运行,非常适合用于国际知识库。
    • BGE-large-en-v1.5 配合 turbovec。仅支持英语,体积更小、运行速度更快,是处理英语文档的理想选择。

    在隐私并非严格要求的情况下,OpenAI 的 text-embedding-3-small(1536 维度)或 text-embedding-3-large(3072 维度)搭配 turbovec 也能正常使用。只需记住,数据泄露风险来自云端的嵌入调用,而非索引本身。

    框架集成

    turbovec 为 LangChain、LlamaIndex 和 Haystack 提供了一流的集成支持:

    pip install turbovec[langchain]
    pip install turbovec[llama-index]
    pip install turbovec[haystack]
    

    已经基于这些方案之一构建的堆栈应选择该路径,因为其阻力最小。

    需牢记的限制

    • 单机内存处理。不存在分布式模式,因此水平扩展意味着在应用层进行分片。
    • 全量扫描。每次查询都会对每个压缩向量进行扫描。SIMD技术能让处理速度保持在约1亿个向量以内,超过这个数量则需使用IVF或图层技术。
    • 硬件依赖性。在苹果M系列芯片上测得的ARM架构性能提升为12%至20%。较旧的ARM或不具备AVX-512功能的x86架构提升幅度较小,但在大多数配置下仍优于FAISS。
    • 低维度下的召回率。在维度低于256左右时,FAISS的优势十分明显。该方法在当前嵌入模型生成的768维及以上数据上表现最佳。

    更宏观的趋势

    turbovec填补了特定的市场空白:内存向量搜索、中等规模的语料库、用户自有的基础设施,以及现代嵌入模型生成的向量维度。它并非要取代Qdrant或Pinecone,而是作为FAISS可能使用的更低层级的构建模块,具备更好的压缩效果且无需训练过程。

    其背后的故事或许更有趣。一篇由四位作者撰写的谷歌研究论文被2026年的ICLR接收,但作者们并未公开代码,随后有两位社区开发者独立实现了相关功能,分别用于KV缓存压缩和向量搜索。其中用于向量搜索的实现,在该技术现有产品的自有基准测试中表现更佳。

    从学术算法到社区实现,再到超越现有标准工具的商用级库,这一路径将会不断重复出现,因为研究成果的产出速度远远快于供应商将其转化为产品的速度。turbovec就是一个成功的实例。了解其运作原理及其适用场景,对当今所有设计检索系统的人而言都很有帮助。

    相关阅读

  • RAG向量数据库内部机制:分块存储、HNSW、IVF与重排序 —— 探讨RAG向量数据库如何存储数据分块,利用HNSW和IVF检索数百万个向量,如何实现混合搜索与重排序,以及各类相似度度量的比较。
  • 还需要嵌入向量吗?向量检索与PageIndex RAG的基准测试 —— FinanceBench基准测试在单文档、多文档及含噪声数据场景下对比了向量检索与无向量PageIndex技术的表现,并进行了显著性检验。