Calendar 第 4 天

向量量化方法

生产级向量搜索引擎面临一个不可避免的扩展挑战:内存需求随数据集大小增长,而搜索延迟要求向量保留在快速存储中。量化通过压缩向量表示同时保持检索质量来提供解决方案——但您选择的方法从根本上决定了您系统的性能特征。

内存经济学

考虑规模的数学原理。OpenAI 的 text-embedding-3-small 生成 1536 维向量,每个向量需要 6 KB(1536 × 4 字节/float32)。这会按比例增长:100 万个向量消耗 6 GB,1000 万个向量需要 60 GB,1 亿个向量需要 600 GB 内存。

对于服务实时查询的生产级 RAG 系统,这些向量必须驻留在 RAM 或高速 SSD 存储中。按云定价计算,这会带来巨大的基础设施成本——企业级部署每月数百到数千美元。

量化通过压缩向量同时保持搜索效率来打破这种成本增长。三种主要的量化系列——标量、二进制和乘积——在速度-内存-准确性权衡曲线上提供了不同的点,每种都针对特定的部署场景进行了优化。

标量量化

标量量化将每个 float32 维度(4 字节)映射到 int8 表示(1 字节),通过学习的范围映射实现 4 倍内存压缩。该算法分析您的向量分布并确定最佳边界——通常使用分位数来排除异常值——然后将 float32 范围线性映射到 int8 范围(-128 到 127)。

该技术利用了 int8 操作可用的 SIMD 优化,除了内存优势之外,还可以实现高达 2 倍的速度提升。使用 int8 值进行距离计算比 float32 操作在计算上更简单,特别是对于主导向量搜索工作负载的点积和余弦相似度计算。

标量量化作为生产默认值表现出色,因为它在各种嵌入模型中保持 99%+ 的准确性,同时提供可预测的压缩比。与需要特定模型特征的二进制量化不同,标量量化与来自商业提供商(OpenAI、Cohere、Anthropic)和开源模型的嵌入都能可靠地工作。

from qdrant_client import QdrantClient, models
import os

client = QdrantClient(url=os.getenv("QDRANT_URL"), api_key=os.getenv("QDRANT_API_KEY"))

# For Colab:
# from google.colab import userdata
# client = QdrantClient(url=userdata.get("QDRANT_URL"), api_key=userdata.get("QDRANT_API_KEY"))

# Scalar quantization setup
client.create_collection(
    collection_name="scalar_collection",
    vectors_config=models.VectorParams(
        size=1536,
        distance=models.Distance.COSINE,
        on_disk=True,  # Move originals to disk
    ),
    quantization_config=models.ScalarQuantization(
        scalar=models.ScalarQuantizationConfig(
            type=models.ScalarType.INT8,
            quantile=0.99,  # Exclude extreme 1% of values
            always_ram=True,  # Keep quantized vectors in RAM
        )
    ),
)

查看如何在 TypeScriptRustJavaC#Go 客户端中设置标量量化。

二值量化

二进制量化代表了极端压缩方法,通过基于符号的阈值将每个维度缩减为单个位:大于零的值变为 1,小于或等于零的值变为 0。这将 1536 维向量从 6 KB(1536 × 4 字节)转换为 192 字节(1536 位 ÷ 8),实现 32 倍内存压缩。

计算优势是巨大的。位运算允许使用本机 CPU 指令进行距离计算,提供比 float32 计算快 40 倍的速度提升。现代处理器擅长并行位运算,使二进制量化对于高吞吐量搜索场景特别有效。

然而,二进制量化要求特定的模型特征以实现最佳性能。该技术最适用于围绕零呈现中心值分布的高维向量(≥1024 维)。OpenAI 的 text-embedding-ada-002 和 Cohere 的 embed-english-v2.0 等模型已验证其二进制兼容性,但其他模型可能会出现显著的准确性下降。

更新: 从 Qdrant v1.15.0 开始,引入了两种额外的量化类型1.5 位2 位二进制量化
这些方法提供了一个有用的折衷方案:它们比标量量化更激进,但提供比标准二进制量化更好的精度。它们还解决了二进制量化主要弱点之一:处理接近零的值

此外: 添加了非对称量化。此方法允许为查询和文档组合不同的量化策略,有助于平衡准确性压缩效率

# Binary quantization setup  
client.create_collection(
    collection_name="binary_collection",
    vectors_config=models.VectorParams(
        size=1536,
        distance=models.Distance.COSINE,
        on_disk=True,
    ),
    quantization_config=models.BinaryQuantization(
        binary=models.BinaryQuantizationConfig(
            encoding=models.BinaryQuantizationEncoding.ONE_BIT,
            always_ram=True,
        )
    ),
)

查看如何在 TypeScriptRustJavaC#Go 客户端中设置二进制量化。

乘积量化

乘积量化采用分而治之的方法,将向量分段为子向量,并使用学习的码本对每个段进行编码。该算法将高维向量拆分为等大小的子向量,然后独立地对每个段应用 k-means 聚类,为每个段创建 256 个质心单独的码本。

压缩机制存储质心索引而不是原始值。一个被分成 128 个子向量(每个 8 维度)的 1024 维向量只需要 128 字节用于存储(128 个索引 × 1 字节),实现大约 32 倍的压缩。在极端配置中,乘积量化可以达到 64 倍的压缩比。

其权衡是计算复杂度和准确性下降。距离计算变得不适合 SIMD,通常导致查询性能比未量化向量慢。分段编码引入了在子向量中累积的近似误差,导致与标量或二进制方法相比,准确性损失更大。乘积量化适用于极端压缩胜过准确性和速度考虑的特殊用例。

# Product quantization setup
client.create_collection(
    collection_name="pq_collection",
    vectors_config=models.VectorParams(
        size=1024,
        distance=models.Distance.COSINE,
        on_disk=True,
    ),
    quantization_config=models.ProductQuantization(
        product=models.ProductQuantizationConfig(
            compression=models.CompressionRatio.X32, #or X4, X8, X16, X32 and X64
            always_ram=True,
        )
    ),
)

查看如何在 TypeScriptRustJavaC#Go 客户端中设置乘积量化。

量化比较

量化方法精度速度压缩率
标量0.99高达 2 倍4x
二进制0.95*高达 40 倍32 倍
乘积0.70.5 倍高达 64 倍
*适用于兼容模型

查看新的 1.5 位2 位二进制量化方法与经典二进制量化的比较。它们在二进制标量方法之间提供了平衡的折衷方案。

双存储架构

Qdrant 的量化实现同时维护压缩和原始向量,从而实现灵活的部署策略和安全的实验。这种双存储方法允许您切换量化方法、调整参数或完全禁用量化而无需重新摄取数据——这对于必须最大限度地减少数据管道复杂性的生产系统来说是一个关键优势。

查看我们的 量化技巧

默认配置将两种表示都存储在 RAM 中,提供使用量化向量进行快速搜索并在需要时使用原始向量进行精确评分。但是,这会抵消内存节省。最佳生产模式是将原始向量放在磁盘上(on_disk=True),同时将量化向量保留在 RAM 中(always_ram=True)。此配置提供了两全其美的优点:快速量化搜索,并能够通过仅从磁盘存储读取少量候选集来执行精确的重新评分。

这种存储策略特别有效,因为量化搜索可靠地识别相关文档的邻域,使用于重新评分的选择性磁盘读取既高效又准确。结果是 RAM 大幅减少而延迟影响最小,这正是生产 RAG 系统实现成本效益扩展所需要的。