Vamana#
Vamana 是著名的 DiskANN 向量搜索解决方案背后的图构造算法。cuVS 实现的 Vamana/DiskANN 是该算法的定制 GPU 加速版本,旨在利用 NVIDIA GPU 缩短索引构建时间。
#include <cuvs/neighbors/vamana.hpp>
namespace cuvs::neighbors::vamana
索引构建参数#
-
struct index_params : public cuvs::neighbors::index_params#
- #include <vamana.hpp>
用于构建 DiskANN 索引的参数。
graph_degree
:图的最大度;对应于文献中 Vamana 算法的 R 参数。visited_size
:Vamana 算法期间每次搜索访问的最大节点数。大致对应于文献中的 L 参数。vamana_iters
:所有向量插入图的次数。如果 > 1,所有向量将被重新插入以提高图质量。max_fraction
:最大批处理大小占总数据集大小的该分数。值越大,构建速度越快,但图质量越低。alpha
:用于确定剪枝的积极程度。
索引#
-
template<typename T, typename IdxT>
struct index : public cuvs::neighbors::index# - #include <vamana.hpp>
Vamana 索引。
索引在设备内存中存储数据集和 Vamana 图。
- 模板参数:
T – 数据元素类型
IdxT – 向量索引的类型(表示 dataset.extent(0))
索引构建#
-
uint32_t graph_degree = 32
输出图的最大度对应于原始 Vamana 文献中的 R 参数。
-
uint32_t visited_size = 64#
每次搜索访问的最大节点数对应于 Vamana 文献中的 L 参数
-
uint32_t vamana_iters = 1#
Vamana 向量插入迭代次数(每次迭代插入所有向量)。
-
float alpha = 1.2#
用于剪枝参数的 Alpha 值
-
float max_fraction = 0.06#
每次分批插入的最大数据集比例。* 更大的最大批处理会降低图质量,但提高速度
-
float batch_base = 2#
批处理大小增长率的基数
-
uint32_t queue_size = 127#
候选队列结构的大小 - 应为 (2^x)-1
-
uint32_t reverse_batchsize = 1000000#
反向边处理的最大批处理大小(减少内存占用)
-
inline cuvs::distance::DistanceType metric() const noexcept
用于聚类的距离度量。
-
inline IdxT size() const noexcept
索引的总长度(向量数)。
-
inline uint32_t dim() const noexcept
数据的维度。
-
inline uint32_t graph_degree() const noexcept
图的度
- inline const cuvs::neighbors::dataset<int64_t> &data(
数据集 [size, dim]
- inline raft::device_matrix_view<const IdxT, int64_t, raft::row_major> graph(
vamana 图 [size, graph-degree]
-
inline IdxT medoid() const noexcept#
返回被选为中心点的向量 ID。
-
index(const index&) = delete
-
index(index&&) = default
- index &=delete operator= (const index &)
- index &=default operator= (index &&)
-
~index() = default
- inline index(
- raft::resources const &res,
- cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded
构造一个空索引。
-
template<typename data_accessor, typename graph_accessor>
inline index( - raft::resources const &res,
- cuvs::distance::DistanceType metric,
- raft::mdspan<const T, raft::matrix_extent<int64_t>, raft::row_major, data_accessor> dataset,
- raft::mdspan<const IdxT, raft::matrix_extent<int64_t>, raft::row_major, graph_accessor> vamana_graph,
- IdxT medoid_id
从数据集和 vamana 图构造索引
- inline void update_graph(
- raft::resources const &res,
- raft::device_matrix_view<const IdxT, int64_t, raft::row_major> new_graph
用新图替换现有图。
由于新图是设备数组,我们存储对其的引用,调用方有责任确保 knn_graph 在索引的生命周期内保持有效。
- inline void update_graph(
- raft::resources const &res,
- raft::host_matrix_view<const IdxT, int64_t, raft::row_major> new_graph
用新图替换现有图。
我们在设备上创建图的副本。索引管理此副本的生命周期。
- cuvs::neighbors::vamana::index<float, uint32_t> build(
- raft::resources const &res,
- const cuvs::neighbors::vamana::index_params ¶ms,
- raft::device_matrix_view<const float, int64_t, raft::row_major> dataset
从数据集构建索引以实现高效的 DiskANN 搜索。
构建利用基于 Vamana 插入的算法创建图。该算法从空图开始,迭代插入批处理节点。每个批处理都涉及对每个要插入的向量执行贪婪搜索,并将其以及与搜索过程中遍历的所有节点的边一起插入。还插入反向边并应用 robustPrune 以提高图质量。index_params 结构控制最终图的度。
支持以下距离度量
L2
使用示例
using namespace cuvs::neighbors; // use default index parameters; vamana::index_params index_params; // create and fill index from a [N, D] dataset; auto index = vamana::build(res, index_params, dataset); // write index to file to be used by CPU-based DiskANN search (cuVS does not yet support search) vamana::serialize(res, filename, index);
- 参数:
res – [in]
params – [in] 构建索引的参数
dataset – [in] 到行主序矩阵 [n_rows, dim] 的矩阵视图(设备)
- 返回:
构建的 vamana 索引
- cuvs::neighbors::vamana::index<float, uint32_t> build(
- raft::resources const &res,
- const cuvs::neighbors::vamana::index_params ¶ms,
- raft::host_matrix_view<const float, int64_t, raft::row_major> dataset
从数据集构建索引以实现高效的 DiskANN 搜索。
构建利用基于 Vamana 插入的算法创建图。该算法从空图开始,迭代插入批处理节点。每个批处理都涉及对每个要插入的向量执行贪婪搜索,并将其以及与搜索过程中遍历的所有节点的边一起插入。还插入反向边并应用 robustPrune 以提高图质量。index_params 结构控制最终图的度。
支持以下距离度量
L2
使用示例
using namespace cuvs::neighbors; // use default index parameters; vamana::index_params index_params; // create and fill index from a [N, D] dataset; auto index = vamana::build(res, index_params, dataset); // write index to file to be used by CPU-based DiskANN search (cuVS does not yet support search) vamana::serialize(res, filename, index);
- 参数:
res – [in]
params – [in] 构建索引的参数
dataset – [in] 到行主序矩阵 [n_rows, dim] 的矩阵视图(主机)
- 返回:
构建的 vamana 索引
- cuvs::neighbors::vamana::index<int8_t, uint32_t> build(
- raft::resources const &res,
- const cuvs::neighbors::vamana::index_params ¶ms,
- raft::device_matrix_view<const int8_t, int64_t, raft::row_major> dataset
从数据集构建索引以实现高效的 DiskANN 搜索。
构建利用基于 Vamana 插入的算法创建图。该算法从空图开始,迭代插入批处理节点。每个批处理都涉及对每个要插入的向量执行贪婪搜索,并将其以及与搜索过程中遍历的所有节点的边一起插入。还插入反向边并应用 robustPrune 以提高图质量。index_params 结构控制最终图的度。
支持以下距离度量
L2
使用示例
using namespace cuvs::neighbors; // use default index parameters; vamana::index_params index_params; // create and fill index from a [N, D] dataset; auto index = vamana::build(res, index_params, dataset); // write index to file to be used by CPU-based DiskANN search (cuVS does not yet support search) vamana::serialize(res, filename, index);
- 参数:
res – [in]
params – [in] 构建索引的参数
dataset – [in] 到行主序矩阵 [n_rows, dim] 的矩阵视图(设备)
- 返回:
构建的 vamana 索引
- cuvs::neighbors::vamana::index<int8_t, uint32_t> build(
- raft::resources const &res,
- const cuvs::neighbors::vamana::index_params ¶ms,
- raft::host_matrix_view<const int8_t, int64_t, raft::row_major> dataset
从数据集构建索引以实现高效的 DiskANN 搜索。
构建利用基于 Vamana 插入的算法创建图。该算法从空图开始,迭代插入批处理节点。每个批处理都涉及对每个要插入的向量执行贪婪搜索,并将其以及与搜索过程中遍历的所有节点的边一起插入。还插入反向边并应用 robustPrune 以提高图质量。index_params 结构控制最终图的度。
支持以下距离度量
L2
使用示例
using namespace cuvs::neighbors; // use default index parameters; vamana::index_params index_params; // create and fill index from a [N, D] dataset; auto index = vamana::build(res, index_params, dataset); // write index to file to be used by CPU-based DiskANN search (cuVS does not yet support search) vamana::serialize(res, filename, index);
- 参数:
res – [in]
params – [in] 构建索引的参数
dataset – [in] 到行主序矩阵 [n_rows, dim] 的矩阵视图(主机)
- 返回:
构建的 vamana 索引
- cuvs::neighbors::vamana::index<uint8_t, uint32_t> build(
- raft::resources const &res,
- const cuvs::neighbors::vamana::index_params ¶ms,
- raft::device_matrix_view<const uint8_t, int64_t, raft::row_major> dataset
从数据集构建索引以实现高效的 DiskANN 搜索。
构建利用基于 Vamana 插入的算法创建图。该算法从空图开始,迭代插入批处理节点。每个批处理都涉及对每个要插入的向量执行贪婪搜索,并将其以及与搜索过程中遍历的所有节点的边一起插入。还插入反向边并应用 robustPrune 以提高图质量。index_params 结构控制最终图的度。
支持以下距离度量
L2
使用示例
using namespace cuvs::neighbors; // use default index parameters; vamana::index_params index_params; // create and fill index from a [N, D] dataset; auto index = vamana::build(res, index_params, dataset); // write index to file to be used by CPU-based DiskANN search (cuVS does not yet support search) vamana::serialize(res, filename, index);
- 参数:
res – [in]
params – [in] 构建索引的参数
dataset – [in] 到行主序矩阵 [n_rows, dim] 的矩阵视图(设备)
- 返回:
构建的 vamana 索引
- cuvs::neighbors::vamana::index<uint8_t, uint32_t> build(
- raft::resources const &res,
- const cuvs::neighbors::vamana::index_params ¶ms,
- raft::host_matrix_view<const uint8_t, int64_t, raft::row_major> dataset
从数据集构建索引以实现高效的 DiskANN 搜索。
构建利用基于 Vamana 插入的算法创建图。该算法从空图开始,迭代插入批处理节点。每个批处理都涉及对每个要插入的向量执行贪婪搜索,并将其以及与搜索过程中遍历的所有节点的边一起插入。还插入反向边并应用 robustPrune 以提高图质量。index_params 结构控制最终图的度。
支持以下距离度量
L2
使用示例
using namespace cuvs::neighbors; // use default index parameters; vamana::index_params index_params; // create and fill index from a [N, D] dataset; auto index = vamana::build(res, index_params, dataset); // write index to file to be used by CPU-based DiskANN search (cuVS does not yet support search) vamana::serialize(res, filename, index);
- 参数:
res – [in]
params – [in] 构建索引的参数
dataset – [in] 到行主序矩阵 [n_rows, dim] 的矩阵视图(主机)
- 返回:
构建的 vamana 索引
索引序列化#
- void serialize(
- raft::resources const &handle,
- const std::string &file_prefix,
- const cuvs::neighbors::vamana::index<float, uint32_t> &index,
- bool include_dataset = true
将索引保存到文件。
匹配 DiskANN 开源仓库使用的文件格式,实现跨兼容性。
#include <raft/core/resources.hpp> #include <cuvs/neighbors/vamana.hpp> raft::resources handle; // create a string with a filepath std::string file_prefix("/path/to/index/prefix"); // create an index with `auto index = cuvs::neighbors::vamana::build(...);` cuvs::neighbors::vamana::serialize(handle, file_prefix, index);
- 参数:
handle – [in] raft 句柄
file_prefix – [in] 索引文件的路径和名称前缀
index – [in] Vamana 索引
include_dataset – [in] 是否序列化数据集
- void serialize(
- raft::resources const &handle,
- const std::string &file_prefix,
- const cuvs::neighbors::vamana::index<int8_t, uint32_t> &index,
- bool include_dataset = true
将索引保存到文件。
匹配 DiskANN 开源仓库使用的文件格式,实现跨兼容性。
#include <raft/core/resources.hpp> #include <cuvs/neighbors/vamana.hpp> raft::resources handle; // create a string with a filepath std::string file_prefix("/path/to/index/prefix"); // create an index with `auto index = cuvs::neighbors::vamana::build(...);` cuvs::neighbors::vamana::serialize(handle, file_prefix, index);
- 参数:
handle – [in] raft 句柄
file_prefix – [in] 索引文件的路径和名称前缀
index – [in] Vamana 索引
include_dataset – [in] 是否序列化数据集
- void serialize(
- raft::resources const &handle,
- const std::string &file_prefix,
- const cuvs::neighbors::vamana::index<uint8_t, uint32_t> &index,
- bool include_dataset = true
将索引保存到文件。
匹配 DiskANN 开源仓库使用的文件格式,实现跨兼容性。
#include <raft/core/resources.hpp> #include <cuvs/neighbors/vamana.hpp> raft::resources handle; // create a string with a filepath std::string file_prefix("/path/to/index/prefix"); // create an index with `auto index = cuvs::neighbors::vamana::build(...);` cuvs::neighbors::vamana::serialize(handle, file_prefix, index);
- 参数:
handle – [in] raft 句柄
file_prefix – [in] 索引文件的路径和名称前缀
index – [in] Vamana 索引
include_dataset – [in] 是否序列化数据集