Zilliz 13小时前
Milvus 2.6 引入 RaBitQ:极致向量压缩,内存节省与性能提升
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

Milvus 2.6 的核心亮点 RaBitQ 1-bit Quantization 技术,将向量量化压缩推向极致,实现了 FP32 向量到 1-bit 的压缩比率,同时保持高召回率。该技术利用高维空间几何特性和角度信息编码,通过 IVF_RABITQ 索引,能够在显著降低资源消耗的同时,提升搜索性能。文章深入剖析了 RaBitQ 的技术原理,阐述了其在 AI 基础设施中的重要意义,并提供了实际应用场景及 Python 示例,帮助开发者快速体验其在内存瓶颈优化方面的优势。

💡 **RaBitQ 1-bit Quantization 的核心技术**:RaBitQ 源于论文《RaBitQ: Quantizing High-Dimensional Vectors with a Theoretical Error Bound for Approximate Nearest Neighbor Search》,它通过将 FP32 向量压缩为二进制表示(1 bit/维度),实现极致存储优化。其核心原理在于利用高维空间的“浓度度量”现象和向量归一化后的角度信息编码,克服了传统量化方法在压缩时信息丢失过多的问题。

🚀 **Milvus 2.6 中的 RaBitQ 集成与优势**:在 Milvus 2.6 中,RaBitQ 通过新的索引类型 IVF_RABITQ 实现,支持高度可配置的压缩比(默认 1:32),能在内存占用减少 72% 的同时,将 QPS 提升 4 倍,且召回率保持在 95% 以上。它通过结合 IVF 聚类和可选精炼策略,实现了“零精度损失”的实用化 1-bit 量化,成为生产环境的首选量化工具。

📈 **RaBitQ 的重要意义与应用场景**:RaBitQ 是对 AI 基础设施内存瓶颈的战略回应,解决了数据规模爆炸式增长带来的内存挑战。它适用于推荐系统、语义搜索(如 RAG)、多模态 AI(图像/视频检索)以及边缘计算等资源敏感、高负载的场景,推动 AI 民主化,使中小团队也能处理海量向量数据。

🛠️ **RaBitQ 的实践应用与内存优化实测**:文章提供了使用 Python 和 MilvusClient 快速上手 RaBitQ 的教程,演示了创建 IVF_RABITQ 索引并进行搜索的过程。通过与 IVF_FLAT 索引的内存占用对比实测,证明了 RaBitQ 在显著节约内存方面的实际效果,在集合加载后,采用 RaBitQ 的集合内存占用量明显低于 IVF_FLAT 索引。

原创 臧伟 2025-11-06 18:04 上海

适合AI infra场景

Milvus2.6 版本更新的诸多功能中, RaBitQ 1-bit Quantization(以下简称 RaBitQ)无疑是最耀眼的亮点。

它将向量量化压缩推向极致,实现 FP32 向量压缩至 1:32 的极致比率,同时保持高召回率,帮助开发者在模型训练为代表的海量数据场景下显著降低资源消耗。

本文将深入剖析 RaBitQ 的技术细节与实际应用,并通过一个上手案例,让你快速感受到其魅力。

如果你正为向量数据库的内存瓶颈烦恼,这篇文章将为你带来实用启发。

01

RaBitQ 1-bit Quantization 的具体介绍

RaBitQ 源于论文《RaBitQ: Quantizing High-Dimensional Vectors with a Theoretical Error Bound for Approximate Nearest Neighbor Search》https://arxiv.org/abs/2405.12497。它专为高维向量设计,通过将 FP32(32 位浮点数)向量压缩为二进制表示(每个维度仅 1 bit),实现极端存储优化,同时借助理论误差界限保证搜索准确性。

核心原理

与 Milvus 的集成

在 Milvus 2.6 中,RaBitQ 通过新索引类型 IVF_RABITQ 实现,支持高度可配置的压缩比(默认 1:32)。

搜索时可调 rbq_query_bits(查询量化,0=无)和 refine_k(精炼倍数)。

相比传统方法,RaBitQ 的优势在于“零精度损失”:基准测试显示,它在 SIFT1M 数据集上实现 72% 内存减少,同时 QPS(每秒查询数)提升 4 倍,且召回率保持在 95% 以上。这让它成为生产环境的首选量化工具。

02

引入 RaBitQ 的意义和应用场景

引入意义

Milvus 2.6 的 RaBitQ 并非简单的技术迭代,而是针对 AI 基础设施痛点的战略回应。随着数据规模从亿级跃升至万亿级,内存消耗已成为向量数据库的“阿喀琉斯之踵”。传统量化虽能节省空间,但往往以牺牲搜索质量为代价,导致应用效果打折。

传统 FP32 存储内存爆炸(1B 向量 ≈ 3TB),PQ/SQ 虽压缩但召回低。RaBitQ 首次让 1-bit 量化实用化

作为开源项目,RaBitQ 与 Zilliz Cloud 集成,提供自动化配置 profile,根据负载动态调整参数。这不仅降低了运维门槛,还推动 AI 民主化,让中小团队也能处理亿级向量。

应用场景

RaBitQ 适用于资源敏感的高负载场景:

03

手把手教程:快速上手 RaBitQ

为了让你快速上手,我们用一个 Python 示例演示 RaBitQ 在 Milvus 中的应用。场景:插入 1000 个随机 128D 向量,创建 IVF_RABITQ 索引,进行 ANN 搜索。

    from pymilvus import MilvusClient, DataType

    import numpy as np

    import random

    # 1. 连接 & 创建集合

    client = MilvusClient("http://localhost:19530")

    client.drop_collection("rabitq_col")  # 清理

    schema = client.create_schema(auto_id=False, enable_dynamic_field=False)

    schema.add_field("id", DataType.INT64, is_primary=True)

    schema.add_field("embedding", DataType.FLOAT_VECTOR, dim=768)

    client.create_collection(collection_name="rabitq_col", schema=schema)

    # 2. 插入 100k 随机向量

    rows = []

    for i in range(100000):

        rows.append({"id": i, "embedding": np.random.random(768).tolist()})

    insert(client, "rabitq_col", rows, 3)

    # 3. 创建 IVF_RABITQ 索引

    index_params = client.prepare_index_params()

    index_params.add_index(

        field_name="embedding",

        index_type="IVF_RABITQ",

        metric_type="L2",  # 或 IP/COSINE

        params={

            "nlist"1024,

            "refine"True,

            "refine_type""SQ8"  # 高召回

        }

    )

    client.create_index("rabitq_col", index_params)

    # 4. 加载集合

    client.load_collection("rabitq_col")

    print("Collection loaded")

    # 5. 搜索(Top-10)

    query_vectors = [np.random.random(768).tolist()]

    search_params = {

        # "metric_type": "L2",

        "params": {

            "nprobe"128,      # 搜索簇数

            "rbq_query_bits"0# 无查询量化=最高召回

            "refine_k"2       # 精炼 2 倍

        }

    }

    res = client.search(

        collection_name="rabitq_col",

        data=query_vectors,

        anns_field="embedding",

        search_params=search_params,

        limit=10,

        output_fields=["id"]

    )

    print(res)


    为了提高批量插入数据的成功率,我们实现了一个带有重试机制的插入方法

      def insert(client, collection_name, data, max_retries):

        """批量插入数据,带重试机制"""

        total = len(data)

        batch_size = 20000

        total_inserted = 0

        failed_batches = []

        for i in range(0, total, batch_size):

            batch = data[i:i + batch_size]

            batch_num = i // batch_size + 1

            success = False

            for attempt in range(max_retries):

                try:

                    result = client.insert(collection_name, data=batch)

                    count = result.get('insert_count'len(batch))

                    total_inserted += count

                    print(f" Batch {batch_num}/{(total-1)//batch_size + 1}: "

                          f"{count} rows (Total: {total_inserted}/{total})")

                    success = True

                    break

                except Exception as e:

                    if "larger than max" in str(e):

                        # 如果还是太大,减小批次

                        new_batch_size = batch_size // 2

                        if new_batch_size < 10:

                            print(f" Batch {batch_num} failed: batch too small to split")

                            failed_batches.append((i, batch))

                            break

                        print(f" Batch too large, reducing size to {new_batch_size}")

                        batch_size = new_batch_size

                        break  # 重新分批

                    else:

                        print(f" Attempt {attempt + 1}/{max_retries} failed: {e}")

                        if attempt < max_retries - 1:

                            time.sleep(2 ** attempt)  # 指数退避

            if not success and batch not in [b[1for b in failed_batches]:

                failed_batches.append((i, batch))

        return total_inserted, failed_batches

      输出结果:


        data: [[{'id'3723'distance'111.82170104980469'entity': {'id'3723}}, {'id'8974'distance'112.3028793334961'entity': {'id'8974}}, {'id'6612'distance'113.15422058105469'entity': {'id'6612}}, {'id'9513'distance'113.48468780517578'entity': {'id'9513}}, {'id'1756'distance'114.02412414550781'entity': {'id'1756}}, {'id'4104'distance'114.40816497802734'entity': {'id'4104}}, {'id'681'distance'114.434814453125'entity': {'id'681}}, {'id'6757'distance'114.61549377441406'entity': {'id'6757}}, {'id'3454'distance'115.34103393554688'entity': {'id'3454}}, {'id'5080'distance'115.34539031982422'entity': {'id'5080}}]]


        运行说明:索引构建时间 < 1 秒,搜索延迟毫秒级。启用

        调优Tips

        接下来,让我们实测下启用RaBitQ之后,内存占用量减少情况。由于Milvus没有直接查看collection占用内存数据的方法,我们通过milvus docker container内存数据来粗略对比下collection内存占用量。

        通过docker stats milvus-standalone --no-stream 我们可以看到,milvus启动后,内存占用 146M

        在集合 rabitq_col load之后,内存是 380M

        对比测试集合采用 IVF_FLAT 索引,插入与集合 rabitq_col 相同的数据,对比下内存占用。

        在此之前,我们先 release 下之前加载的集合 rabitq_col

          client.release_collection(

              collection_name="rabitq_col"

          )

          res = client.get_load_state(

              collection_name="rabitq_col"

          )

          print(res)


          测试集合 采用 IVF_FLAT 索引,集合名字是 ivf_flat_col

            schema = client.create_schema(auto_id=False, enable_dynamic_field=False)

            schema.add_field("id", DataType.INT64, is_primary=True)

            schema.add_field("embedding", DataType.FLOAT_VECTOR, dim=768)

            client.create_collection(collection_name="ivf_flat_col", schema=schema)

            # 插入相同 100k 数据

            insert(client, "ivf_flat_col", rows, 3)

            index_params_flat = client.prepare_index_params()

            index_params_flat.add_index(

                field_name="embedding",

                index_type="IVF_FLAT",

                metric_type="L2",

                params={"nlist"1024}

            )

            client.create_index("ivf_flat_col", index_params_flat)

            # 加载集合

            client.load_collection("ivf_flat_col")

            print("Collection ivf_flat_col loaded")


            集合加载完成之后,查看内存占用 655M

            总体来看,集合 ivf_flat_col的内容使用量 明显高于集合 rabitq_col,可见RaBitQ 有效节约了内存。

            作者介绍

            Zilliz 黄金写手:臧伟

            阅读推荐

            不再搞Chain 设计的LangChain 1.0,与LangGraph有哪些区别?

            多智能体系统中,如何用向量数据库共享上下文?OpenAgents x Milvus

            放弃ES+Mongo,如何用Milvus一套系统搞定千万用户视频检索*关键词

            Embedding相似度不是万金油,电商、 新闻场景如何按时效性做rerank

            多少做RAG的人,连分词都搞不定? Milvus Analyzer指南

            阅读原文

            跳转微信打开

            Fish AI Reader

            Fish AI Reader

            AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

            FishAI

            FishAI

            鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

            联系邮箱 441953276@qq.com

            相关标签

            Milvus RaBitQ 向量数据库 向量量化 AI 基础设施 数据压缩 性能优化 Milvus 2.6 Vector Database Vector Quantization AI Infrastructure Data Compression Performance Optimization
            相关文章