推荐算法:HNSW算法简介 1. HNSW算法概述 2. HNSW算法原理 1. Delaunay图 2. NSW算法 3. HNSW算法 3. HNSW算法原理 现在,我们来看一下HNSW算法的具体原理。 如前所述,HNSW算法是其前作NSW算法的优化算法,因此,在介绍HNSW算法的细节之前,我们需要首先来介绍一下NSW算法。 我们给出原文献中hnsw构造算法伪代码和检索算法伪代码如下: hnsw构造 检索算法 3. HNSW算法实现 现在,我们来看一下hnsw算法的具体实现,我们以网上常用的几个开源库为例进行说明。 参考链接 Hierarchical Navigable Small Worlds (HNSW) HNSW学习笔记 一文看懂HNSW算法理论的来龙去脉 HNSW算法详解 HNSW的基本原理及使用 ANN召回算法之
区分 HNSW 和 IVF 当将 HNSW 与倒排文件 (IVF) 索引方法进行比较时,HNSW 的一个突出特点是它能够适应动态数据集——它可以高效地管理插入和删除,而无需完全重建索引。 HNSW 的设计绕过了这种限制,为数据不断变化的数据库提供了更可持续的解决方案。 HNSW 如何工作? HNSW 的原理 HNSW 利用图结构来组织数据,以反映数据点之间固有的相似性,形成可导航的小世界网络。 如何创建 HNSW? 创建 HNSW 索引涉及几个步骤,重点是构建分层结构,使用其多层方法构建图,以及实现的实际方面。 在实现 HNSW 时,对这些领域的关注可以显著影响索引的性能和可扩展性,使其适用于高维空间中搜索和数据检索的广泛应用。 HNSW 方法:优点和挑战 HNSW 索引算法带来了几个优点和挑战。
本文讨论了过滤 HNSW 搜索的挑战,解释了为什么随着过滤的增加,性能会变慢,以及我们如何使用 ACORN-1 算法改进 Apache Lucene 中的 HNSW 向量搜索。 然而,在 HNSW 图中,主要成本是识别 k 个最近邻所需的向量比较数量。在某些过滤器设置大小下,向量比较的数量可能会显著增加,导致搜索性能变慢。这是一个未过滤的图搜索示例。 由于 Apache Lucene 中的 HNSW 图在构建时并不知道过滤条件,它完全基于向量相似性构建。当应用过滤器以检索 k 个最近邻时,搜索过程会遍历更多图。 实际上,HNSW 图已经是稀疏连接的。如果我们在探索过程中只考虑匹配的节点,搜索过程可能会轻易地卡住,无法有效遍历图。注意在入口点和第一个有效过滤集之间的过滤“鸿沟”。
图的搜索首先,简单回顾一下HNSW图是如何工作的。HNSW图是一种分层的数据结构,遵循以下规则:所有向量都存在于底层(第0层);每个向量在该层由一个图节点表示。 Lucene索引的每个段都有自己独立的HNSW图,仅包含该段中的向量。多个段会独立进行搜索。无论向量的维数是多少,HNSW图都能正常工作,因为它基于两个向量的相似性进行操作。 创建HNSW图时使用的是这些相似性数值,而不是向量本身。HNSW图的搜索,通过以下阶段来找到与查询向量最近的k个向量:搜索从入口节点开始。 HNSW图常见问题解答:以下是理解M和ef_construction图构建参数的关键点:问题答案什么是HNSW图? 为什么HNSW图重要?HNSW图重要,因为它们支持快速且可扩展的近似最近邻搜索。分层结构允许高效探索向量空间,减少搜索时间,同时保持高召回率。HNSW图如何构建?
第五章:HNSW 算法原理与核心实现 5.1 HNSW 算法概述 5.1.1 算法背景 HNSW(Hierarchical Navigable Small World)是目前最先进的近似最近邻(ANN) 大部分节点在底层(level 0) 高层节点数量指数递减 5.2.3 连接数量控制 M:每层的目标连接数 maxM:第0层的最大连接数(通常为) efConstruction:构建时的候选集大小 5.3 HNSW import java.util.concurrent.ConcurrentHashMap; import java.util.Set; import java.util.Map; /** * HNSW // 合并结果 return mergeResults(leftResults, rightResults, k); } } } 小结 本章深入介绍了HNSW 思考题: 为什么HNSW使用指数分布来分配节点层级? 连接剪枝算法如何平衡搜索性能和索引质量? 如何根据数据特性调整HNSW的关键参数?
向量相似性搜索 向量相似性搜索算法有多种,本文介绍以下四种:余弦相似度搜索、Flat Index、倒排文件索引(IVF)、HNSW(层次化可导航小世界)。 层次化可导航小世界(HNSW) 理解 HNSW 之前,需要先掌握两个基础概念:跳表和可导航小世界。 图中 2 是次优解,实际上存在更接近目标的节点 层次化可导航小世界(HNSW) HNSW 把跳表的层次结构和 NSW 的贪心搜索结合在一起。 HNSW 算法 从顶层的入口点开始 查看当前节点的所有邻居 移动到距离查询最近的邻居 重复直到没有更近的邻居(局部最小值) 下降一层,以当前位置作为新的起点 重复直到第 0 层 在第 0 层,使用 ef 实际工程中,数据规模在几万以下可以直接用 Flat Index;百万级别的数据 IVF 是一个性价比很高的选择;对延迟和召回率都有严格要求的在线服务,HNSW 通常是首选方案。
查询时间却缩短到原来的1/10,我们今天就来介绍HNSW算法。 传统搜索方法在高纬度下会崩溃,并且最近邻搜索(NNS)的线性时间复杂度让成本变得不可控。HNSW图的出现改变了搜索的方式。 HNSW为什么这么块 HNSW的效率来自概率连接和受控探索。两个超参数决定了性能权衡: M(连接度):决定每个节点的链接数量。M越大准确率越高,但内存占用和索引时间也会上升。 超大规模系统可以把HNSW和乘积量化(PQ)混用,压缩内存的同时保持召回率。 代码实现详解 这个脚本演示了如何用HNSW替代UCI乳腺癌数据集上的暴力k-NN。 最佳:准确率={hnsw_out['acc']:.4f},F1={hnsw_out['f1']:.4f}," f"查询={hnsw_out['query_time_s']:.4f}s 不同几何结构会改变HNSW的最佳工作点。 压缩+混合索引 结合HNSW和PQ/OPQ来压缩内存,量化召回率和延迟的损失。超大语料库可以评估基于磁盘的HNSW(比如mmap)和热缓存行为。
这个问题有许多的解法,限于篇幅今天我们主要介绍基于HNSW的方法。 1. 前言 进入正题之前,我们先介绍一些基本概念,以便有更加清晰的认识。 最后,会主要介绍Malkov在基于NSW上对ANN问题的优化,即最终要介绍的HNSW算法以及在小程序近邻检索场景的改进。 2. 5.HNSW[ref3] 先讲一下对HNSW宏观理解,HNSW其实构建的是L-ANN的结构,L指图的层数,层与层之间存在连接,查询的时候L层分为两个阶段,阶段1为ep的查找,阶段2为通过ep寻找每一层的最近点 参数 先说明参数的意义: HNSW:指我们构建的L层的ANN GRAPH。 q:需要插入HNSW的向量点。 M:新插入的点在第三阶段每一层建立的连接数。 Mmax:每一层每个点最多的连接数。 基于B+树的HNSW实现 目前流行的HNSW开源基本都是全内存的实现,在海量高维的情况将占据非常大的内存,对于小程序近邻检索场景来说将是较大的开销。
层次化可导航小世界(HNSW)图是向量相似性搜索中表现最佳的索引之一。HNSW 技术以其超级快速的搜索速度和出色的召回率,在近似最近邻(ANN)搜索中表现卓越。 尽管 HNSW 是近似最近邻搜索中强大且受欢迎的算法,但理解其工作原理并不容易。 本文旨在揭开 HNSW 的神秘面纱,并以易于理解的方式解释这种智能算法。 在文章的最后,将探讨如何使用 Faiss 实现 HNSW,并讨论哪些参数设置可以实现所需的性能。 HNSW的基础 我们可以将ANN算法分为三个不同的类别;树、哈希和图。HNSW属于图类别。 初始化HNSW索引 通过以下Python代码初始化HNSW索引: # 初始化HNSW参数 d = 128 # 向量维度 M = 32 # 每个顶点的邻居数量 index = faiss.IndexHNSWFlat HNSW性能 在深入了解了HNSW(分层导航小世界图)的理论基础和Faiss库的实现细节后,现在转向评估不同参数对HNSW索引性能的具体影响。将重点分析召回率、搜索时间、构建时间以及内存使用情况。
Hnswlib是一个强大的近邻搜索(ANN)库, 官方介绍 Header-only C++ HNSW implementation with python bindings, insertions and 热门的向量数据库Milvus底层的ANN库之一就是Hnswlib, 为milvus提供HNSW检索。 HNSW 原理 HNSW 原理 将节点划分成不同层级,贪婪地遍历来自上层的元素,直到达到局部最小值,然后切换到下一层,以上一层中的局部最小值作为新元素重新开始遍历,直到遍历完最低一层。 = "hnsw.bin"; alg_hnsw->saveIndex(hnsw_path); delete alg_hnsw; // Deserialize index and check recall alg_hnsw = new hnswlib::HierarchicalNSW<float>(&space, hnsw_path); correct = 0;
Hnswlib是一个强大的近邻搜索(ANN)库, 官方介绍 Header-only C++ HNSW implementation with python bindings, insertions and 热门的向量数据库Milvus底层的ANN库之一就是Hnswlib, 为milvus提供HNSW检索。 HNSW 原理 HNSW 原理 将节点划分成不同层级,贪婪地遍历来自上层的元素,直到达到局部最小值,然后切换到下一层,以上一层中的局部最小值作为新元素重新开始遍历,直到遍历完最低一层。 = "hnsw.bin"; alg_hnsw->saveIndex(hnsw_path); delete alg_hnsw; // Deserialize index and check recall alg_hnsw = new hnswlib::HierarchicalNSW<float>(&space, hnsw_path); correct = 0;
二、HNSW索引:图结构索引的革命性突破1. 案例:在推荐系统中,使用HNSW索引可将10亿级用户行为向量的检索延迟从分钟级降至毫秒级,同时保持95%以上的召回率。三、HNSW vs. 增量索引)适用场景小规模、低维数据大规模、高维数据四、HNSW在大模型场景中的核心价值1. 应对数据洪峰可扩展性:HNSW的分层结构使其能够轻松处理十亿级向量,支持分布式部署。实时性:毫秒级延迟满足实时推荐、语义搜索等场景需求。2. 结语从FLAT到HNSW,向量索引技术的演进反映了AI应用对检索效率的极致追求。HNSW通过图结构索引的突破,为向量数据库应对大模型数据洪峰提供了核心能力。
我们接着上期说,矢量向量查询中,大部分情况下应该首选HNSW的方案来对矢量的数据进行索引的添加。 HNSW HNSW 和核心是多图结构,他把数据分成多层结构,从下到上分成 0 - N层,最底层包含所有的节点,越往上节点越稀疏,同时每层包含临近的节点的列表。 同时HNSW的索引形成后,对于数据的删除和修改会比较复杂。 今天学习到的几个点总结 1 HNSW的索引是常用的PG VECTOR 的索引使用的方案 2 shared_buffers 给出需要评估 HNSW常用的索引大小,应该至少存放70%以上的HNSW的索引。 3 在使用中应不要混用矢量计算和HNSW的数据库产品 4 合理建立HNSW索引中赋予的参数
客户对HNSW爱恨交织 HNSW近8年向量搜索性能No.1 为了应对海量向量数据的挑战,向量索引技术发展出了多种类型。 HNSW索引依旧不完美 规模上涨让性价比变低 HNSW通过分层导航图,实现高效的向量检索,然而HNSW导航每一层的每个节点会存放有多条边去构建这个分层图结构,HNSWlib实现中默认是采用4字节的节点ID 数组来实现的,以下是一个HNSW元素的内存示意图。 HNSW其它问题 HNSW除上述性价比问题外,还有写入性能不稳定、读写并发度低、空间占用高(标记删除不能及时回收空间)、图连通性差(数据聚集,可能导致部分节点入度为0)等诸多问题。 recall@10=0.99 search ef HNSW默认 381 HNSW FP16 384 HNSW BF16 无法达到0.99召回 查看该数据集下的一条样本数据如下,整数位范围很小[-10,
基于图的索引:cuVS CAGRA对比Faiss HNSW(CPU)CAGRA是一种GPU优化的、固定度数的平面图索引,与基于CPU的HNSW相比具有显著的性能优势,包括:构建时间:CAGRA构建速度最快提升 CAGRA与CPU HNSW的批量吞吐量。 (用于CPU搜索)CAGRA索引可以通过新的faiss.IndexHNSWCagra CPU类自动转换为HNSW格式,从而实现GPU加速的索引构建,随后进行基于CPU的搜索:# 为96维向量创建HNSW M = 16cpu_hnsw_index = faiss.IndexHNSWCagra(96, M, faiss.METRIC_L2)cpu_hnsw_index.base_level_only=False # 用CAGRA图初始化HNSW基础层。
World, HNSW) 在 HNSW 中,作者描述了一种使用多层图的 ANN 算法。 HNSW 图结构。最近邻搜索从最顶层开始(粗放搜索),在最底层结束(精细搜索)。 HNSW Python 包 整个 HNSW 算法代码已经用带有 Python 绑定的 C++ 实现了,用户可以通过键入以下命令将其安装在机器上:pip install hnswlib。 fit_hnsw_index(features, ef=100, M=16, save_index_file=False): # Convenience function to create HNSW 从表中已经能够看出,HNSW ANN 完全超越了 KNN。 以表格形式呈现的结果。
为了提供一个有效的 kNN 近似,Elasticsearch 和 Lucene 使用分层导航小世界 HNSW。HNSW 是一种图数据结构,在不同层次上保持元素之间的链接。 节点的互联性取决于 HNSW 结构的创建方式。HNSW 的优点取决于几个因素:构造方式。HNSW 的构建过程会考虑一些候选者作为特定节点的最接近的节点。 总体而言,HNSW 在性能和召回率之间提供了良好的权衡,并允许在索引和查询方面进行微调。使用 HNSW 搜索可以在大多数情况下使用 kNN 搜索部分。 HNSW 类型(包括 hnsw 和 int8_hnsw)创建 HNSW 数据结构,允许使用近似的 kNN 搜索。这是否意味着你不能用 HNSW 字段类型使用精确的 kNN?并非如此! 量化使用量化,无论是 flat(int8_flat)还是 HNSW(int8_hnsw)类型的索引都将帮助你减小嵌入大小,从而使用更少的内存和磁盘存储来保存嵌入信息。
合理得出:.vex和.vem文件是 HNSW 索引的 data 文件和 metadata 文件在 HNSW 索引模式下,除了 HNSW 索引,还会生成一套 Flat 索引此外,我们注意到.ve*文件中间的编码名全部变成了 vex作为 HNSW 索引的 Data 文件,却也只占了 55MB。事实上,.vex仅仅存储了 HNSW 图的结构,不包含任何实际数据。 所以多出来这套索引就是int8_hnsw吗?不是的。 基于我们刚刚对 HNSW 索引的分析,我们知道 HNSW 索引不存储向量值本身,大小是到不了这个级别的。 int8_hnsw / int4_hnsw 标量量化 HNSW 索引 ES814HnswScalarQuantizedVectorsFormat.veq .vemq
Lucene 目前使用 hierarchical navigable small world (HNSW) 算法来索引向量。在较高层次上,HNSW 将向量组织成一个图表,其中相似的向量可能会连接起来。 Lucene 当前从没有删除的最大输入段创建 HNSW 图的副本,然后将来自其他段的向量添加到此 HNSW 图。 通过并行搜索段可以减轻对延迟的影响,与搜索单个 HNSW 图相比,这种方法仍然会产生一些开销。RAM 需要随着数据集的大小进行扩展以保持最佳性能遍历 HNSW 图会产生大量随机访问。 使用就地突变的单个 HNSW 图不可能实现增量快照。 使用单个共享 HNSW 图而不是多个段来实现索引和搜索的这种分离是不可能的,除非每次需要在新搜索中反映更改时通过网络发送完整的 HNSW 图。
它是分层可导航小世界 (HNSW) 的一种替代方案,通过将向量划分为较小的簇,以更有效地处理低内存场景,同时提供良好的查询性能。HNSW 的问题是什么?我们非常喜欢 HNSW。 为了让 HNSW 良好运作,所有向量都需要驻留在内存中。尽管我们通过引入更好的量化水平降低了成本,但仍然存在向量超出内存导致性能下降的问题。此外,在进行索引时,您必须搜索现有的 HNSW 图。 数据胜于雄辩HNSW 以对数级缩放。因此,它必定比需要搜索质心然后评分质心中所有向量的方案快得多,对吧?我们一直在努力让 DiskBBQ 完全与 HNSW 竞争。 确实,它开始变慢,但随着内存进一步受限,HNSW 的延迟开始呈指数级上升。什么时候应该使用 DiskBBQ?DiskBBQ 和 HNSW 都将在 Elasticsearch 中继续得到改进。 目前,DiskBBQ 在非常高召回率(99% 以上)和非常低延迟方面的性能不如 HNSW。我们希望在继续投资 HNSW 的同时改善这一点。