压缩 (向量量化)
向量量化通过压缩向量嵌入来减少向量索引的内存占用,从而降低部署成本并提高向量相似性搜索的速度。
Weaviate 目前提供四种向量量化技术
从 v1.33 开始,您可以使用 DEFAULT_QUANTIZATION 环境变量为新集合设置默认量化。默认情况下,未设置此变量,这意味着除非您显式配置,否则不会应用任何量化。当设置为(例如,8 位 RQ 量化)时,所有新创建的集合都将使用该量化设置。请注意,一旦在集合上设置,就无法禁用量化。如果索引类型不受支持(例如,PQ 和 SQ 不受 flat 索引的支持),则默认量化将不会应用于集合。
什么是量化?
通常,量化技术通过用精度较低的数字表示数字来减少内存占用,例如将数字四舍五入到最接近的整数。在神经网络中,量化通过将存储为 32 位浮点数 (4 字节) 的模型的权重或激活值减少到精度较低的数字(例如 8 位整数 (1 字节))来减少内存占用。
什么是向量量化?
向量量化是一种减少向量嵌入内存占用的技术。向量嵌入通常表示为 32 位浮点数。向量量化技术通过将它们表示为较小的数字(例如 8 位整数或二进制数)来减小向量嵌入的大小。一些量化技术还会减少向量嵌入的维度数。
积量化
积量化是一种多步量化技术,可用于 Weaviate 中的 hnsw 索引。
PQ 分两个步骤减少每个向量嵌入的大小。首先,它将向量维数减少到较小的“段”数,然后将每个段量化为比原始位数更少的位数(通常是 32 位浮点数)。
PQ 在召回率、性能和内存使用之间进行权衡。这意味着减少内存的 PQ 配置也可能减少召回率。在使用没有 PQ 的 HNSW 时,存在类似的权衡。如果您使用 PQ 压缩,还应调整 HNSW,使其相互补充。
在 PQ 中,原始向量嵌入表示为较小向量的乘积,这些较小向量称为“段”或“子空间”。然后,每个段独立量化以创建压缩的向量嵌入。

创建段后,有一个训练步骤来计算每个段的 质心。默认情况下,Weaviate 将每个段聚类成 256 个质心。这些质心构成一个码本,Weaviate 在后续步骤中用于压缩向量嵌入。
准备好码本后,Weaviate 使用最接近质心的 ID 来压缩每个向量段。新的向量嵌入显著减少了内存消耗。想象一个集合,其中每个向量嵌入有 768 个四字节元素。在 PQ 压缩之前,每个向量嵌入需要 768 x 4 = 3072 字节的存储空间。PQ 压缩后,每个向量需要 128 x 1 = 128 字节的存储空间。原始表示法比 PQ 压缩版本大近 24 倍。(它不是完全 24 倍,因为码本存在少量开销。)
要启用 PQ 压缩,请参阅 启用 PQ 压缩
段
PQ 段 控制内存和召回率之间的权衡。较大的 段 参数意味着更高的内存使用量和召回率。需要注意的是,段必须均匀地划分原始向量维度。
以下是常见向量化模块的段值列表
| 模块 | 模型 | 维度 | 段 |
|---|---|---|---|
| openai | text-embedding-ada-002 | 1536 | 512, 384, 256, 192, 96 |
| cohere | multilingual-22-12 | 768 | 384, 256, 192, 96 |
| huggingface | sentence-transformers/all-MiniLM-L12-v2 | 384 | 192, 128, 96 |
PQ 压缩过程
PQ 有一个训练阶段,用于创建码本。我们建议使用每片 10,000 到 100,000 条记录来创建码本。训练步骤可以手动或自动触发。有关更多详细信息,请参阅 配置:积量化。
当触发训练步骤时,后台作业会将索引转换为压缩索引。在转换进行时,索引为只读状态。分片状态在转换完成后返回到 READY。
Weaviate 使用最多 trainingLimit 个对象(每个分片)进行训练,即使有更多可用对象也是如此。
PQ 转换完成后,可以像往常一样查询和写入索引。由于量化的影响,距离可能会略有不同。
- (
v1.27及更高版本) 如果集合中的对象多于训练限制,Weaviate 会从集合中随机选择对象来训练码本。 - (
v1.26及更早版本) Weaviate 使用集合中的前trainingLimit个对象来训练码本。 - 如果集合中的对象少于训练限制,Weaviate 将使用集合中的所有对象来训练码本。
编码器
在上述配置中,您可以看到您可以设置 encoder 对象来指定如何生成码本质心。Weaviate 的 PQ 支持使用两种不同的编码器。默认值为 kmeans,它映射到用于创建质心的传统方法。
或者,还有 tile 编码器。此编码器目前是实验性的,但具有更快的导入时间和在 SIFT 和 GIST 等数据集上的更好召回率。tile 编码器还有一个 distribution 参数,用于控制在生成质心时使用哪种分布。可以通过将 type 设置为 tile 或 kmeans 来配置编码器,从而创建用于积量化的码本。有关配置详细信息,请参阅 配置:向量索引。
距离计算
使用积量化,距离是使用查询向量进行非对称计算的,目标是在计算距离时保留查询向量中的所有原始信息。
了解更多关于 如何在 Weaviate 中配置积量化。
您可能还对我们的博客文章 如何使用积量化减少高达 90% 以上的内存需求 感兴趣。
二值量化
二值量化 (BQ) 是一种将每个向量嵌入转换为二进制表示形式的量化技术。二进制表示形式远小于原始向量嵌入。通常,每个向量维度需要 32 位,但二进制表示形式只需要 1 位,从而减少了 32 倍的存储需求。这通过减少需要从磁盘读取的数据量以及简化距离计算来加速向量搜索。
权衡是 BQ 具有损失性。二进制表示法本质上省略了大量信息,因此距离计算不如原始向量嵌入准确。
一些向量化器比其他向量化器更适合 BQ。从经验上看,我们看到 Cohere 的 V3 模型(例如 embed-multilingual-v3.0 或 embed-english-v3.0)以及 OpenAI 的 ada-002 模型在启用 BQ 时具有令人鼓舞的召回率。我们建议您使用自己的数据和首选向量化器测试 BQ,以确定它是否适合您的用例。
请注意,当启用 BQ 时,可以使用向量缓存来提高查询性能。向量缓存用于通过减少对量化向量嵌入的磁盘读取次数来加速查询。请注意,它必须与内存使用考虑因素平衡,每个向量占用 n_dimensions 位。
标量量化
标量量化 (SQ) 向量嵌入中的维度通常表示为 32 位浮点数。SQ 将浮点表示形式转换为 8 位整数。这减少了 4 倍的尺寸。
与 BQ 一样,SQ 压缩是一种有损压缩技术。但是,SQ 具有更大的范围。SQ 算法分析您的数据,并将维度值分布到 256 个桶中(8 位)。
SQ 压缩向量比 BQ 压缩向量更准确。它们也比未压缩向量小得多。
桶边界是通过确定训练集中最小值和最大值来派生的,并将值均匀地分布到最小值和最大值之间的 256 个桶中。然后,8 位整数用于表示桶号。
训练集的大小是可配置的。默认值为每片 100,000 个对象。
启用 SQ 后,Weaviate 通过过度获取压缩结果来提高召回率。在 Weaviate 检索压缩结果后,它会将与压缩结果对应的原始未压缩向量与查询进行比较。第二次搜索速度很快,因为它只搜索少量向量而不是整个数据库。
旋转量化
旋转量化 (RQ) 提供显著的压缩,同时保持高召回率。与 SQ 不同,RQ 不需要训练阶段,并且可以在索引创建时立即启用。RQ 有 8 位 和 1 位 变体。
8 位 RQ
v1.32 和 v1.35 中添加8 位旋转量化 (RQ) 用于 HNSW 向量索引 于 v1.32 中添加。
8 位旋转量化 (RQ) 用于 flat 向量索引 于 v1.35 中添加。
8 位 RQ 提供 4 倍压缩,同时在内部测试中保持 98-99% 的召回率。该方法如下工作
-
快速伪随机旋转:输入向量使用基于沃尔什-哈达玛变换的快速旋转进行变换。对于 1536 维向量,此旋转大约需要 7-10 微秒。输出维度向上舍入到 64 的最接近倍数。
-
标量量化:旋转向量的每个条目被量化为 8 位整数。每个旋转向量的最小值和最大值定义了量化区间。
1-bit RQ
v1.33 和 v1.35 中添加针对 HNSW 向量索引的 1 位旋转量化 (RQ) 于 v1.33 中添加。
针对扁平向量索引的 1 位旋转量化 (RQ) 于 v1.35 中添加。
1 位 RQ 是一种非对称量化方法,随着维度的增加,可提供接近 32 倍的压缩。 1 位 RQ 是 BQ 的更强大和更准确的替代方案,仅略有性能损失(在内部测试中,与 BQ 相比,吞吐量减少约 10%)。虽然在编码时间和距离计算方面比 PQ 性能更好,但 1 位 RQ 通常提供的召回率略低于经过良好调整的 PQ。
该方法的工作流程如下
-
快速伪随机旋转:与 8 位 RQ 相同的旋转过程应用于输入向量。对于 1 位 RQ,输出维度始终填充到至少 256 位,以提高低维数据的性能。
-
非对称量化:
- 数据向量:通过存储每个条目的符号,使用每维 1 位进行量化
- 查询向量:在搜索期间使用每维 5 位进行标量量化
这种非对称方法通过在距离计算期间为查询向量使用更高的精度,提高了与对称 1 位方案(如 BQ)相比的召回率。在适合 BQ 的数据集(如 OpenAI 嵌入)上,1 位 RQ 基本上匹配 BQ 的召回率。它也适用于 BQ 表现不佳的数据集(如 SIFT)。
RQ 特性
旋转步骤提供了多重好处。它倾向于减小量化区间并减少量化误差,通过更均匀地分布值来实现。它还将距离信息更均匀地分布在所有维度上,为距离估计提供更好的起点。
两种 RQ 变体都会将维度数向上舍入到 64 的倍数,这意味着低维数据(少于 64 或 128 维)可能会导致次优压缩。此外,有几个因素会影响实际的压缩率
- 辅助数据存储:8 位 RQ 存储 16 字节,1 位 RQ 存储 8 字节,与压缩代码一起存储
- 维度舍入:维度向上舍入到 64 的最接近倍数,并且 1 位 RQ 也填充到至少 256 位
由于这些因素,只有当维度增加时,4 倍和 32 倍的压缩率才能达到。这些效应对于低维向量来说更为明显。
虽然受到扩展的 RaBitQ 的启发,但出于性能原因,此实现差异很大。它使用快速伪随机旋转而不是真正的随机旋转。
超取/重评分
当您使用 SQ、RQ 或 BQ 时,Weaviate 会超取结果然后对其进行重评分。这是因为压缩向量上的距离计算不如对原始向量嵌入进行相同计算那样准确。
当您运行查询时,Weaviate 会将查询限制与可配置的 rescoreLimit 参数进行比较。
查询会检索压缩对象,直到对象计数达到哪个限制更大。然后,Weaviate 获取与压缩向量对应的原始、未压缩的向量嵌入。使用未压缩的向量重新计算查询距离分数。
例如,如果使用限制为 10 的查询,并且重评分限制为 200,Weaviate 会获取 200 个对象。重评分后,查询会返回前 10 个对象。此过程可以抵消压缩引起的搜索质量(召回率)损失。
由于 RQ 具有 98-99% 的高固有召回率,因此通常可以禁用重评分(将 rescoreLimit 设置为 0),以获得最大的查询性能,而对搜索质量的影响最小。
向量压缩与向量索引
使用 HNSW 索引
可以使用 PQ、SQ、RQ 或 BQ 配置 HNSW 索引。由于 HNSW 存储在内存中,因此压缩可以减少您的内存占用,或者允许您在相同数量的内存中存储更多数据。
您可能还对我们的博客文章 HNSW+PQ - 探索 ANN 算法 Part 2.1 感兴趣。
使用扁平索引
可以将 RQ 和 BQ 应用于 扁平索引。由于扁平索引搜索是一种蛮力方法,因此压缩可以减少 Weaviate 需要读取的数据量并提高速度。
重评分
量化本质上由于减少信息精度而涉及一些信息损失。为了减轻这种情况,Weaviate 使用一种称为重评分的技术,使用也与压缩向量一起存储的未压缩向量。重评分会重新计算返回候选对象的原始向量之间的距离。这确保了将最准确的结果返回给用户。
在某些情况下,重评分还包括超取,通过超取,会获取额外的候选对象以确保在初始搜索中不会遗漏前几个候选对象。
更多资源
问题和反馈
如果您有任何问题或反馈,请在 用户论坛 中告诉我们。
