结论摘要
| 没有 ADC:对称量化思路 | 有 ADC:复用预量化文档向量 |
|---|---|
| 查询向量和候选文档向量都要映射到低精度空间后才能比较。若候选文档保留的是原始 FP32, 则查询过程中要对每个候选重复量化,候选越多,CPU 重复工作越多。 | 文档在建索引时已经量化并持久化。查询时按 segment 变换一次 FP32 查询向量, 然后直接与候选的量化字节向量计算距离,省掉逐候选文档量化。 |
为什么需要它:量化索引的目标是把高维 FP32 向量变小,以降低内存和成本;但如果查询阶段又反复把候选原始向量做量化, 节省的存储空间会换来额外 CPU 开销。ADC 把“文档量化”前移到索引阶段并复用结果,让量化检索真正成为轻量的候选评分路径。 若业务还要求最终结果尽可能接近全精度,仍可在 ADC/ANN 召回后对少量候选做全精度 rescore。
mode 或查询 DSL。
在我们的 100M × 768 维 on_disk 对比中,3.3 到 3.7 的吞吐从 2.84 QPS 提升到 674.86 QPS。
这不是 ADC 单独带来的 237 倍提升:主因是 3.6 引入、3.7 默认启用的 prefetch 消除了内存极度不足时的随机 I/O 阻塞;
ADC 是同一版本演进中减少 CPU 侧量化开销的辅助优化,内部估算贡献约为 1.2-1.5 倍,不能脱离整体链路单独承诺。
ADC 是什么
对称量化会把查询和文档都压到同一种低精度表示后再计算距离;ADC 则保留查询的浮点信息, 仅让文档保持已写入索引的量化字节表示。这样既避免每次搜索重复量化候选向量,也比纯 Hamming 比较保留更多查询侧信息。
上式是 OpenSearch SegmentLevelQuantizationUtil 源码注释给出的变换语义;实际实现按段读取量化状态,
因而不同 segment 可以有各自的量化参数。
具体功能与边界
| 项目 | 当前能力 | 工程含义 |
|---|---|---|
| 量化文档向量复用 | 直接从 segment 读取已量化的二进制向量,不在查询期重新量化文档。 | 降低候选打分 CPU 与临时对象开销。 |
| 查询向量处理 | 按 segment 的量化状态对 FP32 查询向量变换一次。 | 查询侧仍以浮点信息参与距离计算,属于非对称计算。 |
| 支持的空间 | 上游测试覆盖 L2、inner_product、cosinesimil;hamming 不走 ADC。 |
对二进制原生向量/Hamming 场景没有价值。 |
| 触发条件 | 需要段存在 Scalar Quantization 元数据,且该元数据启用 ADC。 | 不是给业务方单独配置的搜索参数;应通过受支持的量化索引配置获得该路径。 |
| 精确重排序 | 全精度路径仍读取原始 FP32 向量并使用配置的距离度量。 | ADC 不消除 on_disk rescore 的 I/O 成本,也不等价于 full-precision exact search。 |
enableADC 与随机旋转参数会从 OpenSearch 3.2 起随 Scalar Quantization 参数序列化。
而“使用预量化向量执行 ADC”的改动在上游 k-NN PR #3113 中于 2026-02 合入,且可在 3.7 tag 中追溯。
对 Amazon OpenSearch Service,应以目标引擎版本和服务端发布说明为准,不建议依赖未文档化的内部布尔参数手工开启。
执行路径:ADC 在两阶段检索中的位置
ANN 召回候选
HNSW 在内存中的量化码与图结构上返回候选。ef_search 控制图遍历的计算量。
ADC 量化打分
查询向量按段变换一次,直接与预量化字节向量计算距离,省去逐文档的量化工作。
可选全精度 Rescore
若启用重排序,从原始向量存储读取候选并精确计算距离;oversample 决定候选量。
对 on_disk 32x 场景,阶段 1 用量化码加 HNSW 图压缩内存,阶段 3 用原始向量恢复最终排序精度。
ADC 位于量化评分链路,解决的是计算重复;prefetch 则负责让全精度候选读取按物理地址分组、与计算重叠,解决随机 I/O 等待。
两者互补,不能混为同一种优化。
适用场景与不适用边界
| 场景 | 适合度 | 判断理由 |
|---|---|---|
大规模向量 + SQ / on_disk |
推荐 | 文档量化已经是内存与成本优化的前提,ADC 可进一步减少量化候选打分的 CPU 开销。 |
| 成本敏感、可接受约 0.95 召回的语义检索 | 推荐 | 适合将 RAM 需求换为磁盘存储;通过 oversample + rescore 把精度补回来。 |
高并发、内存不足的 on_disk |
需配合 | ADC 仅优化 CPU;必须同时使用 3.6+ prefetch、预热 page cache 和合适的 IOPS,才能解决主瓶颈。 |
| 向量完全在内存、FP32 精度优先 | 收益有限 | 没有量化候选打分的主要成本,ADC 不是首要优化;优先关注 HNSW 参数、SIMD 与副本扩展。 |
| 二进制向量 / Hamming 检索 | 不适合 | 该数据类型本身以二进制距离计算为主,ADC 路径不适用于 Hamming space。 |
| 严格精确检索或极窄半径判定 | 谨慎 | ADC 属于量化路径优化,不应代替 exact search;精确性要求高时需验证 full-precision rescore 或精确检索方案。 |
我们的实际测试结论
以下数据来自知识库中的 2026-08 实测。数据集为 LAION 100M、768 维;单节点 16 vCPU / 123.6 GB RAM / 787 GB gp3;
FAISS HNSW,12 shards、0 replicas,on_disk 32x,m=16、ef_construction=200。
FP32 原始向量约 286 GiB,远超节点内存,因此这是一个典型的 memory-starving 场景。
| 指标 | OpenSearch 3.3 | OpenSearch 3.7 | 解释 |
|---|---|---|---|
| 最大 QPS | 2.84 | 674.86 | 237x;主因是 prefetch 缓解磁盘随机读,ADC 为 CPU 侧辅助增益。 |
| 串行 P95 | 0.913s | 10.6ms | 86x 改善;表明 I/O 等待从主导因素变为可被流水化的成本。 |
| Recall@100 | 0.9494 | 0.9525 | 基本稳定,吞吐提升不是通过牺牲该批测试的召回获得。 |
| 最佳吞吐参数 | - | ef_search=200,oversample=2 |
较 ef=800, oversample=1,QPS +75%,且 Recall@100 更高。 |
对生产调优的直接启示
- 对于 3.6+ 的
on_diskSQ,优先从ef_search=200、oversample=2起测,再按目标 Recall 上调。 - 部署、恢复或扩容后先做 2-3 轮 warmup;冷 page cache 的首查延迟不能代表稳态。
- 单节点约 675 QPS 已饱和时,加并发只会增加排队延迟;扩吞吐应加副本或节点,而不是继续堆客户端并发。
- 不要把
memory_optimized_search的经验直接套用到高召回或径向检索;知识库实测显示其ef_search调节可能失效,需要单独验证。
落地建议
- 先选量化策略,再看 ADC。业务配置的决策对象是 SQ、
on_disk、压缩倍数、ef_search、oversample和 rescore;ADC 是其中自动进入的执行层优化。 - 不要手工依赖内部开关。上游实现存在
enableADC,但本报告未发现面向用户的稳定 DSL 或服务端配置契约。生产上应只使用 OpenSearch 正式文档支持的量化和查询接口。 - 把 I/O 和 CPU 分开诊断。高 ReadIOPS、page fault、冷缓存导致的抖动,优先排查 prefetch、EBS IOPS、page cache 和 rescore 候选数;CPU 饱和再评估 SIMD、ADC 与批量评分路径。
- 用真实语料校验 Recall。ADC 的目标是加快量化路径而非保证精度;压缩比、相似度度量、模型分布、过滤条件和
k都可能改变 Recall/NDCG。
证据与来源
事实来源按“项目实测优先描述项目结论、上游公开实现验证当前机制”的原则整理。
- OpenSearch k-NN PR #3113 - Use pre-quantized vectors for ADC 上游一手实现:明确描述 ADC 直接使用预量化向量,避免搜索时重复量化;已合入主线。
- SegmentLevelQuantizationUtil.java 上游一手源码:ADC 启用条件、按段查询向量变换公式,以及 L2 / inner product 的使用上下文。
-
ScalarQuantizationParams.java
上游一手源码:Scalar Quantization 参数包含
enableADC;3.2+ 的序列化兼容分支可见。 - OpenSearch k-NN 3.7.0.0 tag 版本锚点:用于确认本报告讨论的上游实现与 3.7 分支的关联。
-
私有知识库:
wiki/sources/opensearch-vector-100m-cost-comparison.md2026-08 的 100M × 768d、3.3 vs 3.7on_disk实测:吞吐、延迟、Recall、参数矩阵和归因。 -
私有知识库:
wiki/concepts/opensearch-vector-prefetch.md、wiki/concepts/opensearch-disk-based-vector-search.md两阶段检索、prefetch 的 I/O 机制、内存模型及生产调优边界。
口径说明:ADC 的独立性能收益没有在本次压测中以 A/B 开关方式单独测量。文中的 1.2-1.5x 为知识库中的辅助贡献估计, 不是可对外承诺的基准值;生产容量规划应以目标语料、实例、压缩比、过滤条件与预热状态的实测结果为准。