来源:互联网 更新时间:2026-07-29 07:47
有了度量方法,接下来就是拿查询向量跟所有存储向量逐条算相似度,排个序,取出Top-K。这个问题的学名叫做KNN(K-Nearest Neighbors,K最近邻)。解法呢,有两条路:
精确KNN就是全量遍历——N条向量,每条D维,逐一算相似度。百万级数据,一次查询一百万次1536维向量运算,脑子过一下就明白:这真不行。
打个MySQL的比方:就像SELECT ... ORDER BY score LIMIT 10没建索引——每次查询全表扫描,数据少还能忍,百万行起步就崩了。ANN则像给向量建了索引,查询走索引快速定位候选行,只对命中的少量行做精确计算,跟MySQL走B+Tree只扫少数数据页是一个道理。
所以实际都用ANN近似路线——用可控的召回损失,换数量级的查询性能提升。这个思路类似布隆过滤器:用极小的误判概率换极致的空间和速度,在工程上是笔很划算的买卖。HNSW是ANN里最主流的算法,但不是唯一的。除了HNSW,还有IVF(K-Means聚类+倒排索引)、PQ(向量压缩)、LSH(局部敏感哈希)等方案。选型简单说就是:百万级以内用HNSW,千万级用IVF,亿级考虑DiskANN或分片。
HNSW之所以最流行,是因为它在精度和速度之间取得了最好的平衡,而且实现成熟、生态完善。ES、Faiss、Milvus都默认支持。
M = 每个节点最多有几条路
efConstruction = 修路时,勘察多少个邻居再决定连哪几条路
efSearch = 查路时,愿意试探多少个候选节点
Top-K = 最后带走几个结果
HNSW是一张分层图:
0 层包含全部节点;越高层节点越少、边越稀疏。对查询向量 Q,HNSW从最高层的入口节点开始查找。
第 2 层:节点最少,边最稀疏
第 1 层:节点更多,边更密
第 0 层:包含全部节点,边最密
在第 2 层,假设入口是节点 A。系统计算 A 与 Q 的距离,然后检查 A 在本层通过边连接的邻居节点。
若 B 比 A 更接近 Q:A → B
若 C 比 B 更接近 Q:B → C
只要当前层有邻居比当前节点更接近 Q,就继续沿边移动。直到当前节点的所有本层邻居都不比它更接近 Q,本层停止。
第 2 层停止在 C
系统从同一节点 C 下降到第 1 层,而不是从任意节点重新开始:
第 2 层:停止在 C ↓
第 1 层:从 C 开始,重复检查邻居、沿边移动的过程
假设第 1 层停止在 E,再从 E 下降到第 0 层。第 0 层不只保留一个当前节点,而是会维护一批候选节点,探索这些节点的邻居,最后从候选中返回距离 Q 最近的 Top-K 节点。
第 2 层:A → B → C,停止 ↓
第 1 层:C → D → E,停止 ↓
第 0 层:从 E 开始,维护并扩展候选节点集合 ↓
返回距离 Q 最近的 Top-K 节点
efSearch 控制的就是第 0 层候选节点集合的搜索规模。
efConstruction 在建图过程中是什么,以及它如何挑选邻居HNSW是一张分层图:
0 层包含全部节点;越高层节点越少、边越稀疏。当新节点 X 加入 HNSW 时,系统会随机为 X 分配一个最高层级。X 会出现在第 0 层,以及从第 1 层到该最高层级的若干层中。
建图时,系统先从现有图的最高入口节点开始,在高于 X 最高层的各层中沿边贪心移动,找到靠近 X 的区域;再在 X 要加入的每一层中,寻找 X 的邻居并建立边。
efConstruction 表示:
例如:
M = 16
efConstruction = 200
可以理解为:
新节点 X 加入某一层
→ 从当前层的入口节点开始,沿边探索候选节点
→ 保留和比较的候选节点规模最多约为 200
→ 计算 X 到候选节点的距离
→ 从候选节点中挑选合适的少量节点
→ 与它们建立边
efConstruction 小时,X 看到的候选节点少,建图较快,但可能没有找到质量足够好的邻居;图的导航能力可能较差。
efConstruction 大时,X 会在更多候选中选择邻居,建图较慢,但节点之间的边通常更合理,后续查询的召回率通常更好。
挑选邻居时,通常会优先选择距离 X 较近的候选节点;同时还会进行连接多样性筛选,避免所有边都集中指向同一局部节点簇。这样 X 的邻居边既保持接近,也覆盖多个可继续导航的方向。
它只影响建索引阶段。索引建好以后,修改它通常需要重新建图。
efConstruction = 200 是否代表可以连 200 条边不是。
efConstruction = 200
表示“挑选邻居时考察约多少候选节点”,而不是“最终连接多少条边”。
最终每个节点可以保留多少邻居边,主要由 M 决定:
M = 16
efConstruction = 200
对应的过程是:
新节点 X
→ 搜索并比较约 200 个候选节点
→ 从候选中选择合适的节点
→ 最终通常最多保留约 16 条邻居边
实际选择时,不一定只取“距离最近的前 M 个节点”。实现通常还会避免所有边都指向同一小片局部区域,保留一定的连接多样性,以提高图的可导航性。
不同向量库实现会有细节差异:例如第 0 层允许的连接数有时会高于 M,可能是 2 × M。但核心不变:
M = 最终保留多少邻居边
efConstruction = 为选出这些边,建图时考察多少候选节点
efSearch 是什么efSearch 是查询阶段的参数。
用户问题会先变成查询向量 Q。查询过程只涉及查询向量 Q、节点、节点之间的边,以及 HNSW 的不同层。
efSearch 所在的完整查询过程假设图共有第 2、1、0 层:
第 2 层:节点最少,边最稀疏
第 1 层:节点更多,边更密
第 0 层:包含全部节点,边最密
查询从最高层的入口节点开始。
当前节点:入口节点 A
查询向量:Q
系统计算 A 与 Q 的距离,并检查 A 在第 2 层通过边连接的邻居节点。
如果邻居节点 B 比 A 更接近 Q:A → B
如果 B 的某个邻居 C 又比 B 更接近 Q:B → C
只要当前层存在比当前位置更接近 Q 的邻居节点,就继续沿边移动。直到当前节点在这一层的所有邻居都不比它更接近 Q:
第 2 层停止在节点 C
这表示:在稀疏的第 2 层中,C 是当前搜索路径上最靠近 Q 的区域入口。
系统不从第 1 层的任意节点重新开始,而是从同一节点 C 的第 1 层位置开始:
第 2 层:停止在 C ↓
第 1 层:从 C 开始
然后重复相同规则:检查 C 的第 1 层邻居;若某个邻居更接近 Q,就沿边移动;直到这一层也没有更接近 Q 的邻居。
C → D → E
第 1 层停止在 E
再从节点 E 下降到第 0 层:
第 1 层:停止在 E ↓
第 0 层:从 E 开始
第 0 层节点和边最多。此时系统不只保留单一当前节点,而会维护一批候选节点:
候选节点集合:E、F、G、H、...
系统不断从候选节点中取出更接近 Q 的节点,检查该节点的邻居,并把值得继续检查的邻居加入候选集合;同时淘汰距离 Q 较远的候选节点。
efSearch 控制的就是第 0 层这批候选节点允许保留和探索的规模。
efSearch 表示:
例如:
Top-K = 5
efSearch = 128
表示:
查询向量 Q 从最高层逐层下降到第 0 层
→ 在第 0 层保留、比较约 128 个候选节点
→ 从候选中选出距离 Q 最近的 5 个节点
→ 返回 Top-5
efSearch 小:
探索节点少 → 查询更快 → 更可能错过真正接近 Q 的节点
efSearch 大:
探索节点多 → 查询更慢 → 更不容易遗漏接近 Q 的节点,召回率通常更高
它影响查询阶段,通常可以在线调整,不需要重建索引。
M = 每个节点最多有几条路
efConstruction = 修路时,勘察多少个邻居再决定连哪几条路
efSearch = 查路时,愿意试探多少个候选节点
Top-K = 最后带走几个结果
最常见的关系是:
efConstruction > M
efSearch > Top-K
例如可作为起点:
M = 16
efConstruction = 200
efSearch = 64
Top-K = 5
对大多数RAG项目,建议先从这组开始:
M = 16
efConstruction = 200
efSearch = 64
如果资料很重要、宁可慢一点也不要漏,可以先试:
M = 32
efConstruction = 200 或 400
efSearch = 128
可以把它理解为建城市地图:
| 参数 | 建议起点 | 什么时候调大 |
|---|---|---|
M | 16 | 结果常找不准,且内存够用 |
efConstruction | 200 | 可以接受更长的建库时间,希望索引质量更好 |
efSearch | 64 | 线上查询漏得多,想提高召回率 |
最常见的调参顺序是:
先固定 M=16、efConstruction=200
↓
只调 efSearch:64 → 128 → 256
↓
观察召回率是否提升、接口是否变慢
↓
仍不够,再考虑把 M 提到 32
因为 efSearch 是查询时参数,最适合线上灵活调节;而 M 和 efConstruction 是建索引时参数,改了通常要重新建索引。
例如你的RAG需要返回 Top-5 文档:
Top-K = 5
efSearch = 64
意思是:HNSW最终只返回5条,但搜索过程中愿意多考察大约64个候选。候选多一些,漏掉正确文档的概率会下降。
不要把 efSearch 设成5;它通常应该明显大于Top-K。常见起点:
Top-5 → efSearch 64
Top-10 → efSearch 64 或 128
真正上线前,应该用你自己的真实问题集验证,而不是只相信参数经验:
准备 50~100 个真实问题
↓
人工标注每个问题“正确答案应来自哪些文档”
↓
分别测试 efSearch = 32、64、128、256
↓
记录:召回率、P95 响应时间、内存占用
↓
选一个“召回够高、速度能接受”的点
例如:
| efSearch | 召回率 | 平均查询耗时 |
|---|---|---|
| 32 | 88% | 15 ms |
| 64 | 94% | 24 ms |
| 128 | 97% | 45 ms |
| 256 | 97.5% | 90 ms |
这时很多团队会选 64 或 128:因为从128到256,速度慢了一倍,召回却只多了0.5%。
一句实战建议:
摩托车活塞环性能如何
ThinkBook系列最新价格全解析:2026年选购避坑与实时询价指南
GPT5.6惨遭切脑,Fable 5回归要变弱鸡版?
Ondo将于今日上线股票永续合约
电视剧《罗曼诺夫后裔》剧情介绍
暗黑4S14野蛮人终局BD攻略
区块链OTC交易所有哪几家比较正规?
什么是山寨币?山寨币指数如何查看?全球前10大山寨币盘点
Binance新增15种bStocks代币化证券为杠杆抵押资产
全球十大加密货币APP v3.11.5正版下载
GLM-4.5发布,全网最全测评和使用教程来了!
洛的网名三字男生霸气(精选100个)
本周比特币行情预判:BTC后市的三种推演与两强对决
剑侠世界3雪峰论剑怎么打-剑侠世界3雪峰论剑打法介绍
Meme币DOGS今晚上线!开局就解锁91%代币是否带来风险?
五千元以下的笔记本几乎消失!经销商:至少一年看不到涨价尽头
姓徐和李取网名男生霸气(精选100个)
25年来最惨单月 微软市值本月重挫近4万亿:押注AI也没赢麻
超长高标准质保+总部直保售后体系:小牛真实售后体验大起底
比特币守住关键支撑,HYPE市值升至第九并反超DOGE
手机号码测吉凶
本站所有软件,都由网友上传,如有侵犯你的版权,请发邮件haolingcc@hotmail.com 联系删除。 版权所有 Copyright@2012-2013 haoling.cc