向量数据库

HNSW 参数调优实践

进阶索引算法约 25 分钟kp-009

前置知识

一句话定义

HNSW 调优是一套以评测为裁判的工程流程:先用 ground truth 建立召回标尺,再按"先 efSearch、后 efConstruction、最后 M"的顺序逐层动参数,在召回-延迟-内存三角里找到业务工作点——不 rebuild 就能解决的,绝不 rebuild。

为什么重要

HNSW 的默认参数(M=16、efConstruction=200、efSearch 按库各异)是"通用安全值",不是你的业务最优值。调优失误的两种极端都很贵:盲目拉 M/efConstruction 让建库从小时变天、内存翻倍;只调 efSearch 到天花板却想要 99.9% 召回,方向错了白烧 CPU。

前置知识

kp-008(HNSW 原理与各参数语义)、kp-024(召回率/QPS/p99 的测法)。

核心概念

原理与机制

七步调参流程(可执行):

  1. 固定评测基准:抽样 1k~10k 条真实查询,用 Flat 算 ground truth(top-10)。
  2. 以默认值 M=16、efConstruction=200 起建,efSearch 从 k 起步(如 64)。
  3. 只调 efSearch:取 64/128/256/512 各测 recall@10 与 p99,画曲线,先确认"在线旋钮"的天花板够不够。
  4. 天花板不够(目标召回达不到)才动建库参数:efConstruction 提到 300~500 重建对比;仍不够再提 M 至 32/48。
  5. 延迟超标:回落 efSearch,或叠加 int8 SQ 压缩后重跑第 3 步(压缩会掉召回,用 efSearch 补偿)。
  6. 内存超标:先 SQ(-75%),再考虑降 M;每步重跑金标准集确认召回。
  7. 固化工作点写入配置与变更记录;数据分布变化时重跑第 1 步。

每一步都要记录:参数、recall@10、p99、QPS、内存、建库耗时——没有表格就没有调优。

公式或模型

本节不适用:本篇是流程方法篇,量化公式见 kp-008 内存式与 kp-026 成本账。

图示

决策顺序(由便宜到昂贵):
 efSearch(在线,秒级) ──不够──► efConstruction(重建) ──不够──► M(重建+内存)
 压缩(SQ)插在"延迟/内存超标"分支: 先压后补 efSearch

实例或案例

某 RAG 库 800 万条 1024 维,目标 recall@10 ≥ 0.97、p99 ≤ 5 毫秒:

直观类比

调 HNSW 像调汽车:先调方向盘(efSearch,实时可回),不够再换轮胎(efConstruction,要进厂),最后才动发动机(M,贵且影响油耗/内存)。

常见误区(排错清单)

症状常见根因处置
召回突然下降数据分布漂移;过滤后候选不足;只写入未重建导致图劣化重跑金标准集分段定位;见 kp-017、kp-030
建库越来越慢M/efConstruction 过大;按时间有序插入使图退化为长链降参;随机化插入顺序或分批乱序
内存 OOM图+向量双大头被低估;副本数翻倍未计入按 kp-008 公式重算;先 SQ 再谈扩容
查询延迟抖动efSearch 与并发不匹配;冷页缓存;GC/NUMA压测并发-延迟曲线;预热;看 p99 而非均值

自测题

  1. 为什么调参顺序是 efSearch → efConstruction → M?
  2. 答:按改动成本与生效速度排序:efSearch 在线秒级、可随时回退;efConstruction 与 M 都要重建索引,M 还永久抬高内存;先用最便宜的旋钮探到天花板再考虑昂贵的。

  3. 开了 int8 压缩后召回从 0.98 掉到 0.95,第一步做什么?
  4. 答:先在线提 efSearch 补偿(通常能拉回大半),确认补偿后仍不达标才考虑升 M 或改用更低失真的量化,因为 efSearch 不需要重建。

  5. 建库耗时随时间显著变长的可疑点?
  6. 答:按写入时间有序插入会让新点总在图的"末梢",图退化为长链、贪心路径变长;处置是打乱插入顺序或周期性重建。

与其他知识点的关系

kp-024 提供本流程依赖的指标测量;kp-027 把调参结论放进系统级选型决策树;kp-030 把排错清单扩展到全系统运维。

延伸阅读

Aumüller, Bernhardsson, Faithfull, "ANN-Benchmarks"(SISAP 2017)——"以召回-延迟曲线选工作点"的方法论出处。

相关知识点