hnswlib

hnswlib

仅头文件的 C++ HNSW 近邻检索实现,带 Python 绑定,支持增量插入与更新

核心功能

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 不是真正的度量,元素可能离别人比离自己更近