OpenSearch k-NN / Technical Brief

OpenSearch ADC 向量检索技术说明

ADC 解决的是量化检索中的重复计算问题:索引已经把文档向量量化并写入磁盘或段文件, 查询时不应再把每个候选文档的原始向量重新量化一遍。ADC 复用这些预量化文档向量, 只变换一次查询向量即可完成候选打分,从而降低 CPU 和数据访问开销。

更新时间:2026-08-11 实测环境:Amazon OpenSearch Service / us-east-1 实测版本:OpenSearch 3.3 与 3.7

结论摘要

一句话说明:ADC(Asymmetric Distance Computation,非对称距离计算)让“保持 FP32 的查询向量” 与“索引中已经存在的量化文档向量”直接计算距离。它的作用不是提高量化率,也不是替代精确重排序; 它的作用是避免在每次搜索的候选打分阶段,重复量化文档向量。
没有 ADC:对称量化思路 有 ADC:复用预量化文档向量
查询向量和候选文档向量都要映射到低精度空间后才能比较。若候选文档保留的是原始 FP32, 则查询过程中要对每个候选重复量化,候选越多,CPU 重复工作越多。 文档在建索引时已经量化并持久化。查询时按 segment 变换一次 FP32 查询向量, 然后直接与候选的量化字节向量计算距离,省掉逐候选文档量化。

为什么需要它:量化索引的目标是把高维 FP32 向量变小,以降低内存和成本;但如果查询阶段又反复把候选原始向量做量化, 节省的存储空间会换来额外 CPU 开销。ADC 把“文档量化”前移到索引阶段并复用结果,让量化检索真正成为轻量的候选评分路径。 若业务还要求最终结果尽可能接近全精度,仍可在 ADC/ANN 召回后对少量候选做全精度 rescore。

CPU 优化 消除逐文档量化的重复工作;收益发生在量化候选的打分路径。
非独立模式 ADC 依附于 Scalar Quantization(SQ)和段级量化元数据,不是新的 mode 或查询 DSL。
不替代 Rescore 需要全精度结果时,重排序仍须读取原始向量并做精确距离计算。

在我们的 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 比较保留更多查询侧信息。

ADC query transform (per segment, conceptual) q'_d = (q_d - x_d) / (y_d - x_d) x_d = dimension d 中被量化为 0 的文档值均值 y_d = dimension d 中被量化为 1 的文档值均值 随后:score(q', quantized_doc) -> L2 / inner product / cosine 的对应距离计算

上式是 OpenSearch SegmentLevelQuantizationUtil 源码注释给出的变换语义;实际实现按段读取量化状态, 因而不同 segment 可以有各自的量化参数。

具体功能与边界

项目 当前能力 工程含义
量化文档向量复用 直接从 segment 读取已量化的二进制向量,不在查询期重新量化文档。 降低候选打分 CPU 与临时对象开销。
查询向量处理 按 segment 的量化状态对 FP32 查询向量变换一次。 查询侧仍以浮点信息参与距离计算,属于非对称计算。
支持的空间 上游测试覆盖 L2inner_productcosinesimilhamming 不走 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 在两阶段检索中的位置

1

ANN 召回候选

HNSW 在内存中的量化码与图结构上返回候选。ef_search 控制图遍历的计算量。

2

ADC 量化打分

查询向量按段变换一次,直接与预量化字节向量计算距离,省去逐文档的量化工作。

3

可选全精度 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=16ef_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=200oversample=2 ef=800, oversample=1,QPS +75%,且 Recall@100 更高。
实测解释:ADC 不能被单独从 3.3/3.7 的总增益中剥离出来。当前最佳证据是: 上游代码明确说明其目标为避免 search-time redundant quantization;而本次版本差异的压倒性因素是 prefetch。 因此,ADC 应被视为量化检索链路的“免费 CPU 优化”,而不是独立容量规划或升级 ROI 的唯一理由。

对生产调优的直接启示

  • 对于 3.6+ 的 on_disk SQ,优先从 ef_search=200oversample=2 起测,再按目标 Recall 上调。
  • 部署、恢复或扩容后先做 2-3 轮 warmup;冷 page cache 的首查延迟不能代表稳态。
  • 单节点约 675 QPS 已饱和时,加并发只会增加排队延迟;扩吞吐应加副本或节点,而不是继续堆客户端并发。
  • 不要把 memory_optimized_search 的经验直接套用到高召回或径向检索;知识库实测显示其 ef_search 调节可能失效,需要单独验证。

落地建议

  1. 先选量化策略,再看 ADC。业务配置的决策对象是 SQ、on_disk、压缩倍数、ef_searchoversample 和 rescore;ADC 是其中自动进入的执行层优化。
  2. 不要手工依赖内部开关。上游实现存在 enableADC,但本报告未发现面向用户的稳定 DSL 或服务端配置契约。生产上应只使用 OpenSearch 正式文档支持的量化和查询接口。
  3. 把 I/O 和 CPU 分开诊断。高 ReadIOPS、page fault、冷缓存导致的抖动,优先排查 prefetch、EBS IOPS、page cache 和 rescore 候选数;CPU 饱和再评估 SIMD、ADC 与批量评分路径。
  4. 用真实语料校验 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.md 2026-08 的 100M × 768d、3.3 vs 3.7 on_disk 实测:吞吐、延迟、Recall、参数矩阵和归因。
  • 私有知识库:wiki/concepts/opensearch-vector-prefetch.mdwiki/concepts/opensearch-disk-based-vector-search.md 两阶段检索、prefetch 的 I/O 机制、内存模型及生产调优边界。

口径说明:ADC 的独立性能收益没有在本次压测中以 A/B 开关方式单独测量。文中的 1.2-1.5x 为知识库中的辅助贡献估计, 不是可对外承诺的基准值;生产容量规划应以目标语料、实例、压缩比、过滤条件与预热状态的实测结果为准。