核心功能
hnswlib 是 HNSW(分层可导航小世界图)算法的 header-only C++ 实现,附带 Python 绑定,除 C++11 外没有任何依赖。官方称相比 nmslib 中的实现内存占用显著更低、建索引更快。它是嵌入进程内的算法库而非服务,常被向量数据库和检索框架当作图索引后端;与 FAISS 的多索引家族相比,它只专注把 HNSW 一件事做好。
功能亮点
零依赖头文件
官方 Highlights 第一条即 lightweight、header-only,除 C++11 标准库外不引入任何第三方依赖
支持增量更新
add_items 可多次调用追加数据,删除以标记实现,开启 allow_replace_deleted 后能复用被删位置
ef 在线调召回
set_ef 在查询阶段调节精度与速度折中,官方注明 ef 必须大于要返回的近邻数量 k
比 nmslib 更省
README 称与当时 nmslib 的实现相比,内存占用显著更低且索引构建时间明显更短
适用场景
• 在 Python 服务里对百万级 embedding 做近邻召回,索引常驻进程内存不额外部署服务
• C++ 项目需要嵌入一个无第三方依赖的 ANN 索引,直接包含头文件参与编译
• 边写入边查询的动态数据集,用增量插入和删除标记维护索引而不整体重建
安装配置
bash
pip 安装(README): pip install hnswlib 从源码安装(README 原文): apt-get install -y python-setuptools python-pip git clone https://github.com/nmslib/hnswlib.git cd hnswlib pip install . C++ 侧为 header-only,直接包含仓库中的头文件即可,无需额外依赖(README Highlights 第 1 条)。
使用方法
python
README 中的 Python 示例: import hnswlib import numpy as np import pickle dim = 128 num_elements = 10000 # Generating sample data data = np.float32(np.random.random((num_elements, dim))) ids = np.arange(num_elements) # Declaring index p = hnswlib.Index(space = 'l2', dim = dim) # possible options are l2, cosine or ip # Initializing index - the maximum number of elements should be known beforehand p.init_index(max_elements = num_elements, ef_construction = 200, M = 16) # Element insertion (can be called several times): p.add_items(data, ids) # Controlling the recall by setting ef: p.set_ef(50) # ef should always be > k # Query dataset, k - number of the closest elements (returns 2 numpy arrays) labels, distances = p.knn_query(data, k = 1) 要点(来自官方 API 说明): - hnswlib.Index(space, dim) 创建未初始化索引,space 取 'l2'、'ip' 或 'cosine' - init_index(max_elements, M = 16, ef_construction = 200, random_seed = 100, allow_replace_deleted = False) - add_items(data, ids, num_threads = -1, replace_deleted = False) - knn_query(data, k = 1, num_threads = -1, filter = None) - 算法参数含义见仓库中的 ALGO_PARAMS.md
关键指标
尚未核验对标产品,此处只列本工具自身指标,不做对比结论。
指标hnswlib
价格免费
开源是
上手难度进阶
相关工具
优点
- header-only 且仅依赖 C++11,集成成本极低,官方 Highlights 把这条列在第一位
- 完整支持增量建索引与元素更新,被标记删除的位置可被后续插入复用,不必整体重建索引
- 官方称相比 nmslib 当前的实现,内存占用显著更低、构建时间更短
- Python 索引对象支持 pickle 序列化,space、dim、M、ef_construction、ef 等参数都以类属性暴露
缺点
- init_index 要求预先知道最大元素数量(官方原文 the maximum number of elements should be known beforehand),超出后需显式调用 resize_index
- 线程安全有明确约束:add_items 与 knn_query 不能并发调用,resize_index 与二者都不能并发
- ef 参数不随索引一起保存,加载索引后必须手动重新 set_ef
- 只支持 l2、ip、cosine 三种空间,其他距离官方建议改用 nmslib;且官方注明 ip 不是真正的度量,元素可能离别人比离自己更近