HNSW图索引

wen IT资讯 29

本文目录导读:

HNSW图索引

  1. 核心原理:从“小世界”到“分层”
  2. HNSW 的工作流程(简要)
  3. 关键参数
  4. HNSW vs. 其他主流算法
  5. 在实际项目中的应用
  6. 一个简单的类比
  7. 总结一句话

HNSW(Hierarchical Navigable Small World) 是一种目前最流行、性能最顶尖的近似最近邻搜索(ANNS)算法之一,它被广泛应用于需要快速向量检索的场景,向量数据库(Milvus、Qdrant、Weaviate)、RAG(检索增强生成)、图像搜索、推荐系统等。

HNSW 的核心思想是:用多层图结构,模拟类似“跳表(Skip List)”的快速查找过程。

下面我来详细解释其原理、优缺点以及关键参数。

核心原理:从“小世界”到“分层”

HNSW 由两个核心概念组合而成:

  1. 可导航小世界图:在普通近邻图的基础上,通过引入“长程链接”,使得任意两个节点之间的平均路径长度很短(即“六度分隔”理论),这样,从任意点出发,通过跳跃长链接,能很快到达目标区域。

  2. 层次化结构:虽然NSW图很快,但在数据量极大时,搜索链路依然很长,HNSW 借鉴跳表的思想,将图分层

    • 底层(Layer 0):包含数据集中的所有向量,这一层负责最精确的搜索。
    • 高层(Layer 1, 2, ...):每往上一层,只包含部分“幸运”的点(通常是随机选出来的),层数越高,节点越稀疏,且节点之间拥有更长的“跳跃链接”。

为什么要分层? 想象一下:你要在一本有10万页的旧书里找一页内容。

  • 无分层:你需要一页一页地翻,或者从一个目录索引开始找,在NSW图里,可以从一个点开始,沿着链接一步步走。
  • 有分层:HNSW 相当于让你先飞到书的目录层(高层),目录里标题跨度很大,你很快能定位到大概的章节,然后你再跳回正文层(底层),在每个小段落里精确查找,这大大减少了搜索步数。

HNSW 的工作流程(简要)

建图(插入节点)

当要插入一个新向量 q 时,算法会:

  1. 确定层数:用一个指数衰减的随机函数,给 q 分配一个最高层数 L,层数越高,节点越少。
  2. 自上而下插入
    • 从顶层(L 层)开始,贪婪地寻找到 q 最近的邻居节点 ep
    • 然后进入下一层(L-1 层),继续从 ep 出发搜索,找到该层的新近邻,同时将 q 与其中 efConstruction 个最近邻的节点建立双向连接(并会进行剪枝以控制度数)。
    • 重复这个过程,直到最底层(Layer 0)完成插入。

搜索(查询过程)

当要查询一个向量 q 的最近邻时:

  1. 从顶层开始:从预设的最高层入口点 enter_point 开始。
  2. 贪婪下降:在当前层,执行贪婪搜索(每次都找离 q 最近的邻居移动),不断接近目标区域。
  3. 跳到下一层:当在当前层找不到更近的点时,将当前找到的最近点作为下一层的起点,继续搜索。
  4. 底层精细搜索:到达最底层(Layer 0)后,执行广度优先/优先级队列搜索(如 efSearch 控制),收集 k 个最精确的最近邻。

关键参数

在实际使用中(如 faissmilvusqdrant),你主要会调整以下几个参数:

参数 含义 影响
M 每个节点在图中的最大连接数(度数)。 越大:图越稠密,召回率高,搜索慢,内存占用高。越小:图稀疏,召回率低,搜索快。
efConstruction 建图时动态候选集大小。 越大:建图更精确,质量高(召回率高),但建图时间非常慢。
efSearch 搜索时动态候选集大小。 越大:搜索精度(召回率)越高,但查询速度越慢。
优点 缺点
查询速度快:通常被认为是百万/亿级数据上最快的ANNS算法之一,延迟很低。 内存占用大:需要存储整个图索引(节点和边),内存显式开销高于 IVF(倒排文件)等算法。
召回率高:通过分层结构,通常能在低延迟下达到接近100%的召回率。 建图慢:特别是 efConstruction 设得较大时,构建索引非常耗时。
支持动态插入:可以随时插入新向量,无需重建整个索引(但性能最佳仍建议批量构建)。 不支持删除:标准的HNSW不支持高效的删除操作(删除后边结构会乱)。
算法成熟:有非常优秀的开源实现(如 hnswlibfaiss 中的 HNSW)。 参数敏感:调整 MefSearch 需要在速度和精度之间仔细权衡。

HNSW vs. 其他主流算法

特性 HNSW IVF(倒排文件) PQ(乘积量化)
搜索速度 极快(log n 增长) 快(取决于 nprobe 非常快(内存计算快,但需压缩解码)
内存占用 高(存图结构) 中等(存聚类中心+IVF列表) 极低(存压缩后的码本)
召回率 极高(可达99%+) 高(需平衡) 较高(有损失)
动态插入 ✅ 支持 ❌ 通常需重建 ❌ 重建成本高
适用场景 毫秒级低延迟、高精度、在线系统 平衡型,大数据集 极致节省内存,移动端或超大库

在实际项目中的应用

  • 向量数据库:Milvus、Weaviate、Qdrant 都将 HNSW 作为核心或主要的索引类型。
  • RAG 应用:当你用 LangChain 或 LlamaIndex 搭建 RAG 时,底层的向量存储(如 Chroma、Pinecone、Zilliz)通常默认推荐 HNSW 索引来快速找到相关文档块。
  • Faiss:Meta的Faiss库中,IndexHNSWFlat 是最常用的接口之一。

一个简单的类比

  • 顶层(高层):就像国家地图,你只看到大城市(北京、纽约、伦敦),通过高速高铁(长程链接)快速切换到目标国家区域。
  • 中间层:城市地图,你看到了各个区(朝阳区、曼哈顿区)。
  • 底层:街道地图,你精确地看到每个小区和门牌号(具体向量点)。

总结一句话

HNSW 通过“先跳到远处(高层加快速度),再细查本地(底层保证精度)”的分层图结构,在牺牲一定内存和建库时间的前提下,换取了当今最好的搜索速度与召回率组合。 如果你的应用对查询延迟召回精度有极高的要求,并且数据库内存足够,通常HNSW 是首选方案

希望这个解释能帮你理解 HNSW,如果想深入细节,可以查阅原论文《Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs》。

抱歉,评论功能暂时关闭!