所有人都希望向量搜索能即时响应,但是高维向量占用的资源很大。一个 1024 维的 float-32 向量会占用大量内存,将其与数百万个其他向量进行比较的计算成本非常高昂。
为了解决这个问题,像 Elasticsearch 这样的搜索引擎使用了两种主要的优化策略:
- 近似搜索(分层可导航小世界 [HNSW]):我们不需要扫描每一份文档,而是建立一个导航图,以便快速跳转到答案的可能邻域。
- 量化:我们对向量进行压缩(例如,从 32 位浮点数压缩为 8 位整数,甚至 1 位二进制值),以减少内存使用量并加快计算速度。
但优化往往会使准确性下降。
这种担忧是有道理的:“如果我在搜索过程中压缩数据并使用快捷方式,我会错过最佳结果吗?”“这种优化是否会降低搜索引擎的相关性?”
为了证明 Elastic 的量化不会降低结果,我们使用DBPedia-14 数据集构建了一个可重复的测试工具,以精确计算在使用 Elasticsearch 的默认优化时,准确率下降了多少(特别是召回率)才能提高速度。
总结:可能比您想象的要少得多。点击此处查看笔记本,亲自试试
定义(面向非专业人士)
在了解代码之前,让我们先明确一些术语。
- 相关性与召回率:相关性具有主观性(我找到的是优质内容吗?),而召回率则是基于数学计算。如果数据库中有 10 份文档与查询在数学层面完美匹配,而搜索引擎找到了其中 9 份,那么召回率就是 90%(或 0.9)。
- 精确搜索(扁平式):有时也被称为“暴力搜索”法。搜索引擎会扫描索引中的每一份文档并计算距离。
- 优点:召回率达到 100%。
- 缺点:计算量大且大规模扩展缓慢。
- 近似搜索 (HNSW):“捷径”方法。搜索引擎生成 HNSW 图表。它遍历图表以找到最近邻。
- 优点:速度极快且可扩展。
- 缺点:如果图表遍历过早停止,可能会错过近邻。
实验:精准与近似
为了测试召回率,我们使用了 DBPedia-14 数据集,这是一个包含 14 个本体类别的大型标题和摘要数据集,通常用于训练和评估文本分类模型。具体而言,我们将重点关注“电影”类别。我们希望将优化的生产设置与数学上完美的基准真值进行比较。
在此次实验中,我们采用 jina-embeddings-v5-text-small 模型。这是一款处于行业领先水平的多语言模型,在文本表征方面树立了行业基准。我们选择该模型,是因为它确立了当下高性能嵌入的标杆标准。通过将 Jina v5 卓越的精准度与Elasticsearch原生量化技术相结合,我们能够展示一种既具备高效计算能力,又在检索质量上毫不妥协的搜索架构。
我们设置了一个具有双重映射的索引。我们同时将相同的文本导入两个不同的字段:
content.raw类型:flat。这会使 Elasticsearch 对全部 Float32 向量执行暴力扫描。通过这种扫描,系统会返回完全匹配的结果,并将用于我们的基线。content类型为semantic_text。默认情况下使用 HNSW + 更好的二进制量化 (BBQ)。这是用于近似匹配的标准、优化生产设置。
Recall@10 测试
在我们的评估指标中,我们使用了 Recall@10。
我们随机挑选了 50 部电影,并对这两个字段运行了相同的查询。
- 如果精确(扁平式)搜索显示前 10 个近邻是 ID [1, 2, 3……10],
- 而近似 (HNSW) 搜索结果显示的是 ID [1,2,3... 9,99]。
- 我们正确地找到了前 10 个中的 9 个。得分为 0.9。
这是我们使用的映射:
结果:成功的“平直线”
我们进行了一次规模测试,重新加载了整个数据集,并对 1,000 到 40,000 个文档的索引规模进行了测试。
召回率得分情况如下:
| 文档 | Recall@10得分 |
|---|---|
| 1,000 | 1.000 (100%) |
| 5,000 | 0.998 (100%) |
| 10,000 | 0.992 (99.4%) |
| 20,000 | 0.999 (99.0%) |
| 40,000 | 0.992 (98.8%) |
结果非常稳定。即使我们扩大了搜索范围,近似搜索也能在 99% 的情况下与暴力精确搜索相匹配。

为什么它如此有效?
您可能会认为将向量压缩成二进制值会对准确性的影响更大。不这样做的原因在于 Elasticsearch 处理检索的方式。
目前大多数嵌入模型输出的是 Float32 向量,这些向量很大。为了提高搜索效率,Elasticsearch 对高维向量使用量化技术。具体来说,自 9.2 版起,它默认使用BBQ。
BBQ 采用重新打分机制:
- 遍历:搜索引擎使用压缩(量化)向量来快速遍历 HNSW 图表。由于向量较小,它可以高效地进行过度采样,收集更大的候选文档列表(例如,前 100 个大致相似的文档),而不会影响性能。
- 重新评分:一旦有了这些候选文件,它就会只检索这几份文件的全精度值,以计算出最终的精确排名。
这样就能两全其美,既能以量化的速度完成繁重的工作,又能以浮点运算的精度完成最终排序。
我们能做得更好吗?
值得注意的是,我们在这里看到的结果是使用默认设置和随机抽样数据得出的。可以将其视为高性能的起点。尽管 Jina v5 性能卓越,但这些召回率分数并非适用于所有数据集的“万能保障”。每个数据集都有其独特之处,虽然您肯定可以进一步调整优化以挖掘出更多性能潜力,但您始终应基于自身特定数据进行基准测试,以明确性能上限所在。
结论
这是一次规模非常小的测试。不过,本次测试的重点并非专门评估嵌入模型或 BBQ 的性能,而是要展示如何通过极简的设置轻松衡量数据集的召回率。
如果您想用自己的数据运行此测试,可以点击此处查看笔记本,亲自试试。




