Hann:Go 语言的快速近似最近邻搜索库

habedi / hann Public generated from habedi/template-go-project

一个为 Go 语言设计的快速近似最近邻搜索库。

License

MIT license 53 stars 0 forks

A fast approximate nearest neighbor search library for Go

Hann 是一个高性能的 Go 语言近似最近邻搜索 (ANN) 库。它提供了一系列索引数据结构,用于在高维空间中进行高效的相似性搜索。目前,支持的索引包括 Hierarchical Navigable Small World (HNSW)、Product Quantization Inverted File (PQIVF) 和 Random Projection Tree (RPT)。

Hann 可以看作是向量数据库(例如 Milvus、Pinecone、Weaviate、Qdrant 等)的核心组件。它可用于为您的 Go 应用程序添加快速的内存相似性搜索功能。

特性

索引

| 索引名称 | 空间复杂度 | 构建复杂度 | 搜索复杂度 | |---|---|---|---| | HNSW | $O(nd + nM)$ | $O(n\log n)$ | $O(\log n)$ 平均情况, $O(n)$ 最坏情况 | | PQIVF | $O(nk + kd)$ | $O(nki)$ | $O(\frac{n}{k})$ | | RPT | $O(nd)$ | $O(n\log n)$ | $O(\log n)$ 平均情况, $O(n)$ 最坏情况 |

支持的距离计算方式

HNSW 索引支持使用 Euclidean 距离、平方 Euclidean 距离、Manhattan 距离和余弦距离。如果使用余弦距离,则向量在读取时会被归一化(在索引中使用或搜索之前)。请注意,平方 Euclidean 距离的计算速度略快于 Euclidean 距离,并且给出与 Euclidean 距离相同的最近向量顺序。如果只需要查询向量的最近向量顺序,而不需要实际距离,则可以使用它来代替 Euclidean 距离。

PQIVFRPT 索引仅支持 Euclidean 距离。

安装

可以使用以下命令将 Hann 作为典型的 Go module 安装:

go get github.com/habedi/hann@main

Hann 需要 Go 1.21 或更高版本,一个 C (或 C++) 编译器,以及一个支持 AVX 指令的 CPU。

示例

| 示例文件 | 描述 | |---|---| | simple_hnsw.go | 创建和使用带有 inline 数据的 HNSW 索引 | | hnsw.go | 创建和使用 HNSW 索引 | | hnsw_large.go | 创建和使用 HNSW 索引 (使用大型数据集) | | pqivf.go | 创建和使用 PQIVF 索引 | | pqivf_large.go | 创建和使用 PQIVF 索引 (使用大型数据集) | | rpt.go | 创建和使用 RPT 索引 | | rpt_large.go | 创建和使用 RPT 索引 (使用大型数据集) | | load_data.go | 用于加载示例数据集的 Helper 函数 | | utils.go | 示例的额外 Helper 函数 | | run_datasets.go | 用于创建不同索引并在不同数据集上尝试的代码 |

数据集

使用以下命令下载示例中使用的数据集:

make download-data
# 仅在运行使用大型数据集的示例时需要
make download-data-large

请注意,要运行使用大型数据集的示例,可能需要一台具有大量内存的机器,例如 32 GB 或更多。

查看 data 目录,了解有关数据集的信息。

文档

有关 Hann 包的详细文档,请访问 pkg.go.dev

HNSW 索引

hnsw 包(hnsw)提供了由 Malkov 和 Yashunin (2016) 提出的 HNSW 图索引的实现。HNSW 将数据组织成临近图的多个层,从而可以通过从上到下贪婪地遍历图来实现快速的近似最近邻搜索。

该索引具有以下参数:

PQIVF 索引

pqivf 包(pqivf)提供了由 Jegou et al. (2011) 提出的 PQIVF 索引的实现。PQIVF 首先将数据聚类成粗略的组(倒排列表),然后使用 product quantization 压缩每个集群中的向量。这允许通过将查询限制到相关集群并有效比较压缩向量来快速进行近似最近邻搜索,从而减少搜索时间和存储需求。

该索引具有以下参数:

RPT 索引

rpt 包(rpt)提供了由 Dasgupta 和 Freund (2008) 提出的 RPT 索引的实现。RPT 使用随机生成的超平面递归地对数据进行分区以构建树结构,从而可以通过树遍历过程实现高效的近似最近邻搜索。

该索引具有以下参数:

日志

可以使用 HANN_LOG 环境变量控制 Hann 产生的日志的详细程度。可能的值包括:

随机种子

为了在不同运行中获得更一致的索引和搜索结果,请将 HANN_SEED 环境变量设置为一个整数。这将初始化随机数生成器,但某些变化仍然可能发生(例如,由于多线程)。

贡献

有关如何做出贡献的详细信息,请参阅 CONTRIBUTING.md

Logo

该 logo 名为 "Hiking Gopher",由 Egon Elbre 创建。

License

Hann 在 MIT 许可证下发布 (LICENSE)。

关于

一个为 Go 语言设计的快速近似最近邻搜索库

主题

go golang nearest-neighbor-search approximate-nearest-neighbor-search search-algorithms similarity-search vector-search indexing-algorithms

资源

Readme

License

MIT license

行为准则

Code of conduct