作者:来自 Elastic Tommaso Teofili 及 Thomas Veasey

自动校准会在合并(merge)阶段,通过对少量样本进行分析来预测召回率(recall),并为每个 segment 自动选择合适的向量量化参数。下面介绍我们是如何将这一能力构建到 Elasticsearch 的合并流程中的。
立即通过 Search AI 的**自助实践课程亲自体验向量搜索。你现在就可以开始 Elastic Cloud 的 免费试用,或者在你的 本地机器**上体验 Elastic。
Elasticsearch 的 DiskBBQ 格式(结合了 IVF 聚类 和二进制量化,专为大规模磁盘 ANN 搜索而设计)提供了多个参数,用于调整索引在召回率(recall)与成本之间的权衡。自动校准(automatic calibration)的目标就是自动优化这些参数,从而获得最佳性能。
在我们之前的博客中,我们介绍了自动校准背后的统计模型:描述最近邻距离如何随索引规模变化的流形(manifold)模型、描述量化噪声的高斯误差模型,以及将二者结合起来计算给定重排序(rerank)深度下预期 recall@k 的闭式解。如果你还没有阅读那篇文章,只需要了解一个核心结论:对于给定的候选量化编码和重排序深度,我们无需构建索引并进行基准测试,只需对语料库(corpus)中的一小部分样本拟合两个简单模型,就能够预测 recall@k。
本文将介绍如何以低成本评估候选配置,以及如何利用这一能力,在索引合并(merge)阶段做出同样低成本、准确且能够适应真实持续合并索引的决策。
最终,我们获得了相当显著的提升:在覆盖多种数据集的测试中,平均查询吞吐量(QPS)提升了近 17% ,同时召回率也有所提高(其中一个数据集的召回率提升了 3 倍)。更重要的是,你只需在索引配置中添加一行:
json
`"auto_calibrate": true` AI写代码
即可立即获得这一能力。我们的计划是在经过更多实践验证后,将其设为默认配置。
为什么手动调优向量量化并不可靠
bbq_disk 提供了多个可调参数:文档的量化位数(1、2、4 或 7 位)、查询向量的独立量化位数、用于重排序(reranking)的过采样(oversampling)因子,以及是否在量化前对向量进行 预处理(precondition) 。这些参数彼此并非独立,它们对召回率的影响也取决于数据本身:对于某一种 embedding model,4 位/1 位的编码可能已经足够;而对于另一种模型,则可能远远不够。
此外,一个索引通常由多个 segment 组成,并会随着时间不断进行合并(merge)。每个 segment 最终都会拥有不同的 vector 分布。因此,为整个索引手动调优一套固定配置,充其量只是一个折中的方案。这也正是自动校准 (automatic calibration)的设计初衷:让每个 segment 都拥有自己的配置,并在每次参与 merge 操作时重新评估。
Elasticsearch 如何在 merge 阶段执行自动校准
当多个 segment 进行合并,并启用了自动校准时,Elasticsearch 会从参与合并的向量中抽样文档和查询,然后执行以下步骤:
-
在合并后语料库(corpus)的一系列嵌套样本上拟合流形(manifold)模型。
-
拟合误差模型,为每一种候选
(查询位数、文档位数、是否预处理)组合预测量化误差的标准差。 -
按照成本从低到高依次评估候选配置。候选编码组合包括
(1,1)、(4,1)、(4,2)、(4,4)和(7,7)(分别表示查询 位数和文档 位数),并分别结合1.25、1.5、1.75、2.0、2.5和3.0六种过采样因子进行尝试。 -
使用上一篇文章介绍的模型估算每个候选配置的 recall@10 ,并在预测能够达到 90% recall@10 目标时立即停止,选择第一个(也就是成本最低的)配置。
最终选定的配置(编码方式、过采样因子以及是否启用预处理)会直接存储在该 segment 的元数据中。因此,它会随着 segment 一起保留下来,并在查询时自动生效,除非查询请求显式指定了其他配置。
对于较小的 segment,则不会执行这一流程:当合并后的向量数量少于 10,000 个时,数据不足以拟合出可靠的模型,因此 Elasticsearch 会直接采用当前 DiskBBQ 的默认配置,即:
-
查询向量:4 位编码
-
文档向量:1 位编码
-
不启用预处理(preconditioning)
-
使用 3 倍过采样(3× oversampling)
向量量化成本模型是如何工作的
按照上一篇文章介绍的原理,我们最初采用了三层嵌套循环来选择候选配置,这种方式本质上类似于手工维护一张查找表。
最外层循环遍历量化方案,按照文档位数(document bits)从低成本到高成本排序:(1,1) → (4,1) → (4,2) → (4,4) → (7,7)。
中间一层循环遍历重排序(rerank)深度,从浅到深排序:1.25× → 3.0×。
最内层循环遍历是否启用预处理(preconditioning):关闭 → 开启。
这种遍历顺序实际上隐含着一个成本模型,只不过它没有被明确写出来:在尝试更高位数之前,会先穷举当前量化位数下的所有重排序深度。换句话说,文档位数被认为是唯一真正昂贵的资源,而过采样(oversampling)则几乎被视为 "免费"。因此,在低位数编码下,总是会先将重排序深度增加到最大,然后才会考虑使用更高位数的编码。
现在的实现将这一隐含策略替换成了一个明确且连续的成本函数:
ini
`cost = document_bits + 1.3 × rerank_depth` AI写代码
查询位数(query bits)仍然不参与成本计算。成本模型只考虑两个因素:
-
文档位数(决定索引大小)
-
重排序深度(决定每次查询需要重新评分多少候选结果)
预处理(preconditioning)同样不包含在公式中。Elasticsearch 会先在关闭预处理 的情况下,按照成本从低到高遍历所有候选配置;只有当没有任何配置能够达到目标召回率时,才会重新执行一轮开启预处理的遍历。因此,预处理被视为一种兜底手段,而不是与文档位数和重排序深度按统一成本进行权衡的参数。
在这一成本模型下,每增加一个单位的重排序深度,其成本明显高于增加一个文档位。因此,自动校准通常会更倾向于提高量化位数,而不是不断增加过采样深度。
这样设计的主要原因在于,在 serverless 部署中,计算资源和存储资源是分别计费、分别扩缩容的,而且它们的扩缩容节奏完全不同。
增加一个文档位带来的成本主要发生在索引(indexing)阶段。它只会使 segment 在对象存储中的体积略微增大,而对象存储成本较低,也无需为了应对查询流量突增而提前预留容量。
当然,它也会带来一定的持续成本:随着量化位数增加,驻留在页缓存(page cache)中或加载用于评分的量化向量,会按比例占用更多内存(RAM)。不过,这部分成本会随着语料库(corpus)规模线性且可预测地增长,不会随着查询流量突然增加。
而重排序深度则完全不同,它是一项持续性的按查询计费成本。
每增加一级过采样因子,就意味着每一次搜索请求都需要从磁盘读取更多全精度候选向量,并对它们重新评分。只要索引仍在提供查询服务,这部分额外开销就会一直存在。
这不仅增加了搜索服务层的计算负载,也增加了 DRAM 的压力。为了应对不断变化的查询并发量,搜索服务层必须几乎实时进行自动扩缩容。
因此,重排序深度直接处于查询延迟(latency)和成本预算的关键路径上,而存储容量以及量化位数本身带来的内存占用,则不属于这一关键路径。
正因为如此,成本函数中给予重排序深度比文档位数更高的权重,才能使自动校准过程真实反映两者在实际 serverless 环境中的成本差异。
高效估算向量量化误差
前面介绍的成本模型能够发挥作用,前提是其背后的召回率(recall)估计足够可靠。而要让召回率估计可信,就必须保证流形(manifold)模型和误差模型都具有较高的准确性。
其中,估算第 k 个到第 N 个最近邻距离的流形模型计算成本很低;相比之下,为某一种候选量化编码估算量化噪声的标准差(standard deviation)在理论上要昂贵得多。
DiskBBQ 使用固定数量的聚类(cluster)来加速最近邻查询。我们的量化方法正是利用了这一特点:它并不是直接量化原始向量,而是仅对向量相对于聚类中心(cluster centroid)的残差(residual)进行量化。
这意味着,随着数据规模不断扩大,被量化的残差向量相对于整个相似度计算中各组成部分的幅度会越来越小,因此量化精度也会随之提高。
因此,当我们根据样本估计整体 segment 的量化误差时,必须将这一现象考虑进去。
一种直接的方法是在多个不同规模的样本上分别进行聚类,并拟合误差如何随着聚类规模变化而变化。这需要:
-
在多个不同规模的真实语料库(corpus)样本上重新执行聚类;
-
建立回归模型,拟合随着有效聚类规模增大,量化误差如何逐渐减小;
-
在拟合结果上额外增加 +3σ 的保守裕量,以抵消模型拟合本身带来的噪声。
这种方法准确,而且足够保守。
然而,在常见稠密 retrieval 数据集上的基准测试中,我们发现,对于每一个候选配置都执行多轮层次化 K-Means 聚类,计算开销非常大。
为了提升速度,我们尝试过使用一种基于各向同性高斯(isotropic Gaussian)的残差近似方法。
这种方法不再对不同规模的数据反复聚类,而是根据流形模型估计出的局部密度,直接生成合成(synthetic)的残差。
它运行速度很快,非常适合后台 merge,而耗时更长的多轮真实聚类则仅保留给 force merge 使用。
然而,这种方法在 embedding(更准确地说,是残差)呈现**各向异性(anisotropic)**时会高估误差。所谓各向异性,是指不同方向上的方差差异很大,某些方向包含远多于其他方向的信息。
因此,在具有明显各向异性的向量数据(例如类似 Fashion-MNIST 的图像 embedding)上,估算得到的误差可能会显著偏大。
于是,我们寻找一种既快速又更加准确的残差计算方法。
最终采用的方法是:
-
仅对一个较小的真实样本(2,048 个向量)执行一次聚类;
-
每次 merge 期间只运行一次聚类;
-
后续评估所有候选量化编码时,都在这次聚类结果的基础上进行 warm start,而无需每次重新聚类。
至于误差如何随着语料库(corpus)规模增长而变化,新的方法也不再通过多个样本重新拟合,而是直接利用流形模型中的 invDim,将其作为一个 plug-in 估计器,依据一次真实测量结果外推到整个语料库,而不是重新拟合规模变化关系。
与此同时,我们还将自动校准阶段用于查询的样本数量从 1,024 个向量减少到了 256 个。
原因是,一旦量化误差来自真实数据而非合成数据(并且已经通过基准测试验证),更小的查询样本也足以获得稳定结果。
最终,这一方案的整体运行时间与之前的合成残差方法基本相当,但由于使用了真实聚类得到的残差,因此准确性更高,也使后台 merge 与 force merge 可以统一采用同一套流程。
例如,我们选择了五个不同的 benchmark 数据集,通过直接测量真实(对于合成残差方法,则是人工生成)的残差中精确点积 与量化点积 之间的差异,计算量化误差的标准差(standard deviation,SD),然后再将这一测量结果外推到整个语料库。
三种方法的区别仅在于外推方式不同:
-
多样本规模拟合法(Multi-sample scaling fit):在 15 种不同样本规模上执行聚类,并拟合误差随聚类规模变化的关系。
-
单次真实残差测量(Single-pass real residual):仅执行一次较大的真实残差聚类,并利用流形模型的内在**维度(dimension)**估计误差随规模变化的趋势。
-
合成残差方法(Synthetic residual formula):完全不使用真实残差,而是依据流形模型预测的排序距离,从高斯分布中生成合成残差。
在本次比较中,我们将多样本规模拟合法视为"真实值(ground truth)"。
这样做并不是因为它能够无误差地测量整个语料库的真实量化误差------它本身也存在采样噪声------而是因为它使用了最多的样本,因此最接近真实情况。
下表总结了三种方法的特点:
| 方法 | 工作原理 | 速度 | 准确性 | 使用场景 |
|---|---|---|---|---|
| 多样本规模拟合法 | 在 15 个不同样本规模上聚类,并拟合回归模型 | 慢 | 黄金标准(Gold standard) | Ground truth 基准 |
| 单次真实残差测量 | 一次聚类 + 使用流形 invDim 进行外推 |
快 | 接近黄金标准 | 后台 merge 与 force merge |
| 合成残差方法 | 基于流形密度估计生成高斯残差 | 快 | 在各向异性数据上会高估误差 | 已废弃 |
为了替换算法,我们只需要确认新旧方法能够给出一致的结果即可。
这个问题可以独立于估计值本身是否绝对准确来验证。而多样本规模拟合法的准确性,我们已经在上一篇文章中进行了验证。
下面的图展示了各方法预测得到的量化误差标准差(SD)以及预测的 recall@10。
其中,recall@10 是依据流形模型计算得到的理论召回率,它描述的是:在给定量化误差分布扰动真实距离排序的情况下,不同量化参数能够达到的理论召回率。
采用这种分析方式,可以单独评估量化误差对排序质量造成的影响,而不会混入 IVF 索引本身可能带来的召回率下降 ------ 后者属于另一种独立的误差来源。

单次真实残差测量(single-pass real residual measurement)计算得到的量化误差标准差(SD)相比合成高斯残差(synthetic Gaussian residuals),更接近多样本规模拟合法(multi-sample scaling fit,我们的黄金标准)。
因此,采用单次真实残差 + 流形插件(manifold plugin)方法得到的召回率预测,也更加接近黄金标准。
实际上,我们发现,这两种模型在最终产生的索引决策方面几乎可以互相替代。
更重要的是,我们将自动校准(calibration)的计算开销降低了一个数量级(an order of magnitude)。

自动校准对索引性能的开销
我们在 18 个公开 benchmark 数据集上,将启用自动校准时的索引成本与 Elasticsearch 默认配置进行了对比。
我们发现:
-
超过 50% 的数据集,其自动校准带来的开销低于 2%;
-
有 3 个数据集 的开销位于 16%~27% 之间;
-
另外有 2 个数据集 的开销位于 31%~35% 之间。
对于较小的数据集(例如 Fashion-MNIST、FiQA),merge 开销会更高。这些数据集通常只需几秒钟即可完成索引,因此用于校准的向量样本数量是固定的,导致校准成本在整体索引过程中更加明显。
这是符合预期的。
事实上,对于更大的数据集,例如 DBPedia-Entity 和 HotpotQA(约 500 万个文档向量 ),自动校准带来的开销有时几乎无法察觉,在最坏情况下也仅在 11% 以内。

自动校准会选择哪些量化参数?
下面我们来看一下,在每个真实数据集上,自动校准最终选择的编码配置:

所有数据集中,查询位数(query bits)均选择为 4 位。
虽然查询位数并未纳入成本公式,但我们仍然会优先遍历更低的查询位数。例如,在文档向量采用 1 位量化时,我们会先评估 1 位查询向量的召回率,然后再评估 4 位查询向量的召回率。因此,某些数据集理论上也可能选择查询向量和文档向量都采用 1 位的对称量化(symmetric 1-bit quantization)。
整体来看,最常见的配置是:
-
文档向量采用 2 位编码;
-
过采样(oversampling)因子位于 1.5× 到 1.75× 之间。
4 位量化只出现在两个真正更具挑战的数据集中:
-
Fashion-MNIST 的图像 embedding;
-
GIST-1M。
而 1 位量化只出现在少数对量化更加鲁棒的文本 embedding 模型中。
事实上,我们自己的模型属于量化效果最好的模型之一:在使用 Jina v3 测试的三个语料库中,我们都选择了 1 位文档量化。
自动校准带来的召回率和 QPS 提升
自动校准在这 18 个数据集上都表现出了广泛收益:
-
在 18 个数据集中有 15 个 的 QPS 得到了提升;
-
在约 10 个数据集 中,QPS 提升达到两位数百分比;
-
在 FiQA GTE、Fashion MNIST 和 Glove-200 上,QPS 提升超过 50%。
与此同时:
-
在 18 个数据集中也有 15 个 的召回率得到提升;
-
Fashion MNIST 的召回率提升尤为明显,达到了 +295.7%。
大多数数据集都能够同时获得 QPS 和召回率提升。
即使是在提升较为有限的数据集上,结果仍然保持明显正向:
-
召回率提升通常位于个位数高位到两位数百分比范围;
-
QPS 提升也呈现类似趋势。
对于少数指标下降的情况,下降幅度都非常有限:
-
3 个 QPS 下降案例中,下降幅度均低于 1.5%;
-
3 个召回率下降案例中,下降幅度均低于 2%。

如何在 Elasticsearch 中启用自动校准向量量化
该功能目前默认未启用,需要通过 bbq_disk 索引选项中的 auto_calibrate 进行选择性启用:
json
`
1. "index_options": {
2. "type": "bbq_disk",
3. "index_type": "ivf",
4. "quantize_bits": 1,
5. "auto_calibrate": true
6. }
`AI写代码
启用此设置后,你不再需要猜测量化位数、过采样参数或预处理方式:每个 segment 会根据自身的向量分布选择预测能够达到 90% recall@10 的最低成本配置,并且每次合并时都会重新评估该选择。
Elasticsearch 中自动向量量化的下一步发展
我们的第一篇文章展示了如何从少量样本中以封闭形式预测 recall。将其转化为运行在真实合并流程中的功能,需要进行第二轮工程决策,而这些决策并不是模型本身能够回答的:如何对候选配置进行排序扫描,使其在常见情况下成本最低;如何根据每种参数在查询时实际产生的成本,在过采样和文档位数之间进行成本权衡;以及如何以较低成本估算误差项,同时避免悄悄破坏预测准确性。
最终,我们实现了一个能够根据数据特征调整索引选择的功能,对于大型索引,索引时间开销不到 11%。这使我们能够在优化量化和过采样选择以提升查询性能的同时,准确控制 recall。在启用此功能后,与之前 DiskBBQ 的默认设置相比,我们的 QPS 平均提升了 16.7%。同时始终可靠地达到目标 recall。将配置负担从用户手中移除,实际上让我们能够做出更好的选择;这是一个双赢的结果。
这只是一个更长期探索的开始,我们正在努力基于对运行环境的更深入理解以及对数据特征的更深入理解相结合,实现自动配置。我们期待在不久的将来与你分享更多这方面的工作。
原文:Auto-calibrating vector quantization in Elasticsearch - Elasticsearch Labs