优化HNSW索引并扩展向量搜索以用于生产环境中的RAG系统
了解 HNSW 的 M 和 ef 参数如何权衡召回率、延迟和内存使用,学习如何在 Chroma 中设置这些参数,以及何时通过垂直扩展或分片的方式来扩展向量数据库。
一个拥有数千个向量的检索增强生成(RAG)原型,在几乎任何配置下都能实现即时响应。当向量数量增长到数百万时,延迟和资源消耗开始成为主要问题,索引配置也变成了需要重点考虑的生产环节。本指南将介绍最重要的两个HNSW参数、如何在Chroma中设置它们,以及如何判断仅靠调整参数已不够用、系统需要进一步扩展的时机。
决定几乎所有功能的两个HNSW参数
调整 HNSW(分层可导航小世界)图结构时无需掌握其完整理论。该索引会将每个向量与多层结构中的邻近向量相连,查询时则沿着此图寻找最近的邻居。有两个参数决定了该图的结构以及查询的路径。如需更多背景信息,请参阅我们关于向量数据库的工作原理,从嵌入模型到混合搜索的解读文章。
M:每个节点的最大连接数
M决定了图中每个节点可保留的邻居连接的最大数量。
- M 值较低:连接数减少,索引规模变小,内存占用降低且查询速度更快,但由于可搜索的有效候选路径较少,召回率也会下降。
在构建索引时 M 值是固定的,因此之后若要更改该值则必须重新构建索引。
ef:每次搜索的努力程度
ef 控制索引在查找查询的最近邻时会考虑多少候选项。
- 低 ef 值:检查的候选项较少,因此检索速度较快,但可能会遗漏相关文档,导致准确率下降。
- 高 ef 值:检查的候选项更多,因此检索速度较慢,但得到的结果集会更接近真正的最近邻。
许多引擎将此分为构建时的参数,用于控制图结构的构建精细程度,以及搜索时的参数,通常无需重新构建即可更改,因此这是最容易用来试验的参数。
平衡精度、速度与内存
HNSW的调优需要在精度、速度和内存之间进行三方权衡。对于常见的项目阶段,这些组合可作为合理的起点,其中ef表示搜索时的参数值:
+----------------+----+-----+----------+
| Use Case | M | ef | Priority |
+----------------+----+-----+----------+
| Prototype | 16 | 40 | Speed |
| Production | 16 | 100 | Balanced |
| High accuracy | 32 | 200 | Accuracy |
+----------------+----+-----+----------+
可将它们视为基准用于对比:在每次更改前后,针对具有代表性的查询来测量召回率和延迟。
在Chroma中设置HNSW参数
不同的向量数据库对这些参数的设置方式各不相同。在Chroma中,可以在创建集合时将它们作为集合元数据传递。下面的示例将M设置为16,构建时的ef设置为100,搜索时的ef设置为50:
#Chroma-HNSW Settings
collection=client.create_collection(
name='new_collection',
metadata={
'hnsw:M':16,
'hnsw:construction_ef': 100,
'hnsw:search_ef': 50
}
)
在较新版本的Chroma中,这种元数据键的形式可能会发生变化,因为该版本还提供了专用的配置对象,因此请查阅对应版本的文档。由于这些参数会被嵌入到图中,因此应在导入数据之前设置M和构建时的ef值。
当仅靠调优已不够时
即便经过精心调优的索引最终也会达到性能上限。当数据检索时间经常超过100毫秒时,常见的原因就是索引已无法完全容纳在内存中,而进一步的参数调整也无法解决这一问题。一个粗略的估算方法是:原始向量存储的空间需求为向量数量乘以每个向量的维度,再乘以32位浮点数所需的4字节;而HNSW图还会带来随M值增长的额外开销。此时就需要考虑扩展方案,具体有两种形式。
垂直扩展
对于包含大约500万到1000万个向量的数据集,通常首先考虑在现有机器上增加RAM或CPU资源。有了足够的内存后,整个索引就能全部存储在RAM中,从而恢复快速的检索速度并提升整体效率。
垂直扩展无需进行架构或代码上的修改,但单台机器存在内存上限,而且规模更大的实例成本会迅速上升。
水平扩展
当向量数量超过约1000万时,水平扩展成为更实际的选择。此时数据会被分片处理,即把数据分散到多台实例中,每片负责存储和查询自己的那部分数据。
这种方式消除了单台机器的限制,但代价是复杂性:每个查询都需要分发到各个分片上,随后还需将各分片的部分结果合并为一份排序后的列表,这会增加延迟并带来更多的运维工作。
关键要点
M值会影响模型性能:数值越高,召回率和内存使用量越大,且调整该值需要重新构建模型。ef值会影响搜索效果:提高搜索时间参数是牺牲延迟以提升召回率的最低成本方式。
M 16 配合 100 的搜索 ef 值,然后针对自己的查询进行基准测试。