游乐游手机版
首页/AI热点日报/热点详情

深度解读HNSW算法:平衡向量检索速度与精度

类型:热点整理2026-06-28
向量检索(Vector Retrieval),又称向量相似性搜索(Vector Similarity Search),已成为AI时代不可或缺的核心技术之一。无论是推荐系统、检索增强生成(RAG),还是各类前沿的生成式AI应用,其背后都离不开这一技术的支撑。那么,向量检索究竟具备哪些独特优势?答案并不

向量检索(Vector Retrieval),又称向量相似性搜索(Vector Similarity Search),已成为AI时代不可或缺的核心技术之一。无论是推荐系统、检索增强生成(RAG),还是各类前沿的生成式AI应用,其背后都离不开这一技术的支撑。

那么,向量检索究竟具备哪些独特优势?答案并不复杂:它完美兼顾了检索精度与查询速度。

在过去,向量搜索通常采用一种堪称“笨功夫”的方法——暴力扫描,即kNN(K近邻)算法。其核心思路是将查询向量与库中所有向量的距离逐一对比,虽然原理直观,但计算开销极大。以100个文档为例,它必须硬生生完成100次相似度计算。优势在于结果高度精确,但缺陷同样明显:检索时间随数据规模线性增长。当数据量突破百万级甚至更高时,成本、效率和响应速度都将成为难以逾越的瓶颈。

图:kNN算法工作流程示意

正是在这样的技术背景下,一个名为HNSWlib的向量检索库进入了我们的视野。它基于Hierarchical Navigable Small World(HNSW)算法实现——这也是当前在检索效率与召回率之间取得最佳平衡的方案之一。接下来,我们就来深入剖析这项关键技术。

01. 什么是向量检索

在解读HNSWlib之前,有必要先厘清向量检索的基本概念。

向量检索是信息检索领域的一种主流方法,专门用于从海量非结构化数据(如图像、文档、音频)中找出与查询内容最相似的条目。简单来说,文档和查询内容都会经由Embedding模型转化为高维向量空间中的一个点。向量的维度取决于所使用的模型。举个例子,如果采用'all-MiniLM-L6-v2'模型,每个查询或文档都会生成一个384维的向量。

到了查询环节,我们同样用Embedding模型将查询内容转化为向量,然后在向量空间中计算它与所有文档向量的相似度。语义相近的内容在空间中的距离会更近,最终返回相似度最高(或距离最短)的结果——这就是向量检索的完整逻辑。

图:2D向量空间中语义相似的单词所对应的向量嵌入分布

02. 什么是HNSW

为了突破kNN在性能上的固有局限,业界近年来开发了多种索引算法,而HNSW是其中检索效率最为出色的一种。

HNSW是一种基于图结构的高效向量检索算法,其核心创意源自两个经典概念:跳表(Skip List)和可导航小世界(NSW)图。

跳表:概率驱动的高效搜索机制

跳表本质上是一种概率数据结构,由多层链表堆叠而成。层数越高,链表中被跳过的元素就越多。从下面的可视化图可以清晰看到:最底层包含了链表中的全部元素;越往上层走,被跳过的元素越多,保留下来的节点也越来越少。

图:跳表工作流程示意

现在,假设我们要从一个三层结构、包含8个元素的链表中查找数字7。搜索从最高层开始:先检查第一个元素是否小于7,条件成立则继续向后遍历;如果遇到大于7的元素,就将当前这个元素作为下一层搜索的起点。随后在较低层重复相同的流程,逐步下降至最低层,最终准确定位目标元素。这种层层“跨越”大量无关元素的机制,使得跳表在执行搜索时极为高效。

NSW图:贪婪路径上的局部最优策略

理解了跳表,再来看NSW图。在NSW图中,每个节点(或称为顶点)都会与相似的节点建立连接,最终构成一张完整的网络。它的检索逻辑可以概括为:从一个随机节点出发,不断跳转至与查询向量更为相似的邻居,直到找到局部最优解——也就是那个比周围所有节点都更接近目标的“最佳匹配”。这一过程被称为贪婪路由搜索。

图:NSW图的构建过程示意

HNSW算法巧妙地将跳表和NSW图的优势融合在了一起。它不再只是一个简单的二维图,而是由多层图构成的多层级结构。类似于跳表,最底层包含所有元素,层数越高,被跳过的元素就越多。

具体到图的构建过程,HNSW会为每个元素分配一个从0到I的随机数——其中I代表该元素在多层图中能够出现的最大层数。假设某个元素的I等于2,总层数为4,那么它就会从第0层一直延续到第2层,但不会出现在第3层。

图:使用HNSW算法进行向量检索的流程示意

在搜索阶段,HNSW算法从最高层的任意节点出发,通过NSW图的贪婪路由找到局部最小值;然后进入下一层,重复同样的流程,一步步逼近目标节点,直到找到与查询向量最为接近的那个节点。

这一设计的精妙之处在于,HNSW无需检索那些离查询点较远、相关度较低的元素,检索效率自然大幅提升。当然,这也意味着它并不适合做精确匹配——因为在搜索过程中跳过了不少元素,本质上是一种近似最近邻(ANN)方法。其他ANN方法,如FAISS、ScaNN,也具备类似的特性。

那么,如何在不需要极度精确、但仍希望保持较高召回率的情况下使用HNSW呢?答案在于调节它的三个核心超参数:

  • M:NSW图中每个元素的最大边数。M值越大,搜索精度通常越高,但索引构建的速度会相应变慢。

  • efConstruction:构建索引时的动态候选列表大小。候选队列越长,索引质量越高,但构建时间也会随之增加。

  • efSearch:搜索阶段的动态候选列表大小。efSearch值越高,召回率表现越好,但搜索速度会有所下降。

除了精度与速度之间的权衡,内存消耗也是一个需要重点关注的方面。HNSW要求将整个数据集全部加载到RAM中——如果你的数据集大到内存无法容纳,就会面临不小的挑战。M值越高,每个元素存储相邻信息所需的内存就越多;随着元素数量和邻居信息的不断增长,内存需求会呈现线性上升趋势。因此,在大规模应用中,精细调优M和efConstruction是绕不开的关键步骤。

整体来看,HNSW的时间复杂度呈对数级(O(log N)),召回率表现出色,并且支持动态更新——可以随时添加新数据,无需重建索引。但代价同样明显:相比其他ANN方法,HNSW的内存消耗更高,索引构建速度相对较慢,且原生不支持删除元素。

但即便如此,在大型数据集上,HNSW的表现依然极具竞争力。参考GIST1M数据集(包含100万个960维向量)上的基准测试结果:HNSW整体表现优于FAISS、Annoy、pgvector等方案,尤其是在高召回率场景下优势更为明显。在排名上,它仅次于Milvus的Knowhere和Zilliz Cloud的Glass算法,稳稳占据前三的位置。

图:GIST1M数据集上的ANN基准测试结果对比

HNSWlib是一个基于C++的开源HNSW算法实现库。它非常适合为向量检索搭建简单的应用场景,但如果数据量动辄上亿甚至数十亿,可能会显得有些力不从心。问题在于它作为一个轻量级ANN库,功能相对有限,随着数据点的增长,内存消耗会迅速成为瓶颈。

对于大规模应用场景,更成熟的方案是使用像Milvus这样的专业向量数据库。它支持云原生架构和多租户服务,能够高效存储、索引和检索数百万甚至数十亿个数据点。当然,HNSWlib也可以作为核心算法集成到这类数据库中——我们接下来就演示这一过程。

03. 如何将HNSWlib与Milvus集成

首先通过pip安装HNSWlib:

pip install hnswlib

然后,我们来创建100个虚拟数据点,每个点128维。接着构建一个M为8、efConstruction为25的HNSW图。最后,执行一次最近邻查询。

import hnswlib
import numpy as np
import pickle

dim = 128
num_elements = 100

# 生成样本数据
data = np.float32(np.random.random((num_elements, dim)))
ids = np.arange(num_elements)

# 生成查询点
query = np.float32(np.random.random((1, dim)))

# 声明索引
p = hnswlib.Index(space = 'l2', dim = dim) # 可选选项: l2, cosine 或 ip

# 初始化索引 - 需要事先知道最大元素数
p.init_index(max_elements = num_elements, ef_construction = 25, M = 8)

# 插入元素(可以多次调用):
p.add_items(data, ids)

# 通过设置ef控制召回率:
p.set_ef(50) # ef 必须始终大于 k

# 查询数据集,k - 最近邻个数(返回两个numpy数组)
labels, distances = p.knn_query(query, k = 1)

这就是HNSWlib的原生用法,操作非常简单直观。

接下来,看看如何在Milvus中集成HNSW。最便捷的方式是使用Milvus Lite——它可以直接导入到你的Python应用中。安装同样使用pip:

!pip install -U pymilvus
!pip install pymilvus[model]

现在,我们从创建集合、定义索引方法开始。先定义一个集合模式,并指定HNSW作为索引方法——Milvus会在后台自动调用HNSW进行索引构建。之后就可以插入数据,开始索引构建流程了。

from pymilvus import MilvusClient, DataType
from pymilvus import model

client = MilvusClient("demo.db")

# 1. 创建模式
schema = MilvusClient.create_schema(
auto_id=False,
enable_dynamic_field=False,
)

# 2. 向模式中添加字段
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=768)
schema.add_field(field_name="text", datatype=DataType.VARCHAR, max_length=200)

# 3. 准备索引参数
index_params = client.prepare_index_params()

# 4. 添加索引配置
index_params.add_index(
field_name="vector",
index_type="HNSW",
metric_type="L2"
)

# 创建集合
if client.has_collection(collection_name="demo_collection"):
client.drop_collection(collection_name="demo_collection")

client.create_collection(
collection_name="demo_collection",
schema=schema,
index_params=index_params
)

# 定义Embedding模型
embedding_fn = model.DefaultEmbeddingFunction()

# 待搜索的文本数据
docs = [
"Artificial intelligence was founded as an academic discipline in 1956.",
"Alan Turing was the first person to conduct substantial research in AI.",
"Born in Maida Vale, London, Turing was raised in southern England.",
]

# 将文本转换为Embedding向量
vectors = embedding_fn.encode_documents(docs)

data = [
{"id": i, "vector": vectors[i], "text": docs[i]}
for i in range(len(vectors))
]

# 将Embedding向量插入Milvus
res = client.insert(collection_name="demo_collection", data=data)

最后,如果想要进行向量搜索,可以按照以下方式操作:

SAMPLE_QUESTION = "What's Alan Turing achievement?"
query_vectors = embedding_fn.encode_queries([SAMPLE_QUESTION])

res = client.search(
collection_name="demo_collection",
data=query_vectors,
limit=1,
output_fields=["text"],

)

context = res[0][0]["entity"]["text"]

04. 结论

向量检索之所以在AI应用中占据如此重要的地位,归根结底在于它对检索精度和查询速度的极致追求。而HNSW算法,正是在这种技术诉求下应运而生的一项创新方案。当kNN的穷举搜索在面对大规模数据集时显得力不从心之际,HNSW凭借其多层图结构,在检索速度与准确性之间找到了一个理想的平衡点。

通过融合跳表和NSW图的各自优势,HNSW实现了快速、近似的向量搜索,足以应对海量数据的检索需求。通过灵活调优M、efConstruction和efSearch这些核心超参数,还可以根据具体业务场景在搜索速度、召回率和内存消耗之间找到最适配的配置。而在实际工程应用中,将HNSWlib集成到Milvus这类专业的向量数据库中,则能进一步优化整体的检索体验与系统性能。

来源:https://www.53ai.com/news/RAG/2024121419784.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。