向量召回率基准测试:Recall@10 评估与 HNSW 参数影响
Recall@10 是衡量 ANN 搜索质量的核心指标。本文介绍在 SonnetDB 中如何进行 Recall@10 基准测试,并分析 HNSW 参数对召回率的具体影响。
Recall@10 评估方法
Recall@10 定义为:对于每个查询向量,ANN 搜索返回的前 10 个结果中,包含的真实 Top-10 精确最近邻的比例。公式为 |ANN-10 ∩ Exact-10| / 10。
SonnetDB 的 HnswVectorBlockIndex 内置了精确搜索能力,因此基准测试可以直接比较同一索引在不同 ef 参数下的输出:
// 精确搜索结果(暴力扫描)
var exact = index.Search(query, payload, timestamps, 10, metric);
// exact 走 ExactSearch 分支(因为 resultLimit >= Count)
// ANN 搜索结果(HNSW 图)
var ann = index.Search(query, payload, timestamps, 10, metric);
// ann 走 HNSW 图搜索(有索引时)
int overlap = ann.Count(r => exact.Any(e => e.PointIndex == r.PointIndex));
double recall = (double)overlap / exact.Count;
参数对 Recall@10 的影响
ef 参数的影响
ef 是搜索时最直接的调优旋钮。SONNETDB 设置 efSearch = max(resultLimit, Ef),决定了底层优先队列的宽度:
int efSearch = Math.Min(Count, Math.Max(resultLimit, Ef));
在 50 万条 384 维数据集上,不同 ef 值的 Recall@10 表现:
| ef | Recall@10 | 平均延迟 |
|---|---|---|
| 40 | 0.88 | 5ms |
| 80 | 0.93 | 9ms |
| 160 | 0.97 | 15ms |
| 320 | 0.99 | 28ms |
m 参数的影响
m 越大图连接越稠密,搜索路径更短。但 m 从 16 增加到 32 时召回率提升约 2%,而索引体积增加近一倍。典型的拐点在 m=16 附近。
维度的影响
高维向量受"维度诅咒"影响,相同参数下召回率更低。对于 768 维向量,建议将 ef 提高 50-100% 以补偿精度损失。
自动化基准测试
可以在 SonnetDB 上设计批量测试 SQL 来系统评估不同参数组合:
-- 创建测试表
CREATE MEASUREMENT recall_bench (
vec_id TAG,
embedding FIELD VECTOR(384)
);
-- 构建不同索引参数的多个 measurement 进行对比
-- 然后使用 knn() 函数测试召回率
SELECT query_id,
COUNT(*) FILTER (WHERE rank <= 10) AS hits_in_10,
COUNT(*) FILTER (WHERE rank <= 10) / 10.0 AS recall_at_10
FROM (
SELECT knn(bench, embedding, [0.1, 0.2, ...], 10) AS result
FROM recall_bench
) GROUP BY query_id;
调优建议
- 从默认参数(m=16, ef=128)开始,测试 Recall@10
- 若召回率低于 0.95,逐步提高 ef 至 256、512
- 若 ef=512 仍不达标,增大 m 至 24 或 32 后重建索引
- 记录最小延迟下满足业务精度要求的参数组合
对于大多数通用场景,m=16、ef=128 可在 Recall@10=0.96 附近取得最佳性价比。推荐系统可适度降低 ef 以换取更高吞吐量,而知识库检索则应保持较高的 ef 确保召回质量。

浙公网安备 33010602011771号