跳到主要内容

IVF_PQ

IVF_PQ index 是一种基于量化的索引算法,用于高维空间中的近似最近邻搜索。虽然速度不如某些基于图的方法快,但 IVF_PQ 通常需要显著更少的内存,使其成为大型数据集的实用选择。

概述

IVF_PQ 代表带有乘积量化的倒排文件,这是一种结合索引和压缩的混合方法,用于高效的向量搜索和检索。它利用两个核心组件:倒排文件 (IVF)乘积量化 (PQ)

IVF

IVF 就像创建一本书的索引。不是扫描每一页(或在我们的情况下,每个向量),而是在索引中查找特定关键词(聚类)以快速找到相关页面(向量)。在我们的场景中,向量被分组为聚类,算法将在接近查询向量的几个聚类内搜索。

它的工作原理如下:

  1. 聚类: 您的向量数据集使用聚类算法(如 k-means)被划分为指定数量的聚类。每个聚类都有一个质心(聚类的代表向量)。

  2. 分配: 每个向量被分配到其质心最接近它的聚类。

  3. 倒排索引: 创建一个索引,将每个聚类质心映射到分配给该聚类的向量列表。

  4. 搜索: 当您搜索最近邻时,搜索算法将您的查询向量与聚类质心进行比较,并选择最有希望的聚类。然后将搜索范围缩小到那些选定聚类内的向量。

要了解更多技术细节,请参阅 IVF_FLAT

PQ

乘积量化 (PQ) 是一种用于高维向量的压缩方法,可显著减少存储需求,同时支持快速相似性搜索操作。

PQ 过程包括以下关键阶段:

Ivf Pq 1

  1. 维度分解:算法首先将每个高维向量分解为 m 个等大小的子向量。这种分解将原始 D 维空间转换为 m 个不相交的子空间,其中每个子空间包含 D/m 维。参数 m 控制分解的粒度并直接影响压缩比。

  2. 子空间码本生成:在每个子空间内,算法应用 k-means 聚类 来学习一组代表向量(质心)。这些质心共同形成该子空间的码本。每个码本中的质心数量由参数 nbits 确定,其中每个码本包含 2^nbits 个质心。例如,如果 nbits = 8,每个码本将包含 256 个质心。每个质心都分配有一个具有 nbits 位的唯一索引。

  3. 向量量化:对于原始向量中的每个子向量,PQ 使用特定度量类型在相应子空间内识别其最近的质心。此过程有效地将每个子向量映射到码本中其最接近的代表向量。不是存储完整的子向量坐标,而是只保留匹配质心的索引。

  4. 压缩表示:最终的压缩表示由 m 个索引组成,每个子空间一个,统称为 PQ 代码。这种编码将存储需求从 D × 32 位(假设 32 位浮点数)减少到 m × nbits 位,在保持近似向量距离能力的同时实现大幅压缩。

有关参数调优和优化的更多详细信息,请参阅 Index 参数

考虑一个具有 D = 128 维且使用 32 位浮点数的向量。使用 PQ 参数 m = 64(子向量)和 nbits = 8(因此 k = 2^8 = 256 个每个子空间的质心),我们可以比较存储需求:

  • 原始向量:128 维 × 32 位 = 4,096 位

  • PQ 压缩向量:64 个子向量 × 8 位 = 512 位

这代表了 8 倍的存储需求减少。

使用 PQ 的距离计算

在使用查询向量执行相似性搜索时,PQ 通过以下步骤实现高效的距离计算:

  1. 查询预处理

    • 查询向量被分解为 m 个子向量,匹配原始 PQ 分解结构。

    • 对于每个查询子向量及其相应的码本(包含 2^nbits 个质心),计算并存储到所有质心的距离。

    • 这生成 m 个查找表,其中每个表包含 2^nbits 个距离。

  2. 距离近似

    对于由 PQ 代码表示的任何数据库向量,其与查询向量的近似距离按如下方式计算:

    • 对于 m 个子向量中的每一个,使用存储的质心索引从相应的查找表中检索预计算的距离。

    • 将这些 m 个距离相加,以基于特定度量类型(例如欧几里得距离)获得近似距离。

Ivf Pq 2

IVF + PQ

IVF_PQ index 结合了 IVFPQ 的优势来加速搜索。该过程分为两步工作:

  1. 使用 IVF 进行粗过滤:IVF 将向量空间分割为聚类,减少搜索范围。算法不是评估整个数据集,而是只关注最接近查询向量的聚类。

  2. 使用 PQ 进行细粒度比较:在选定的聚类内,PQ 使用压缩和量化的向量表示来快速计算近似距离。

IVF_PQ index 的性能受控制 IVF 和 PQ 算法的参数显著影响。调整这些参数对于为给定数据集和应用程序实现最佳结果至关重要。有关这些参数及其调整方法的更详细信息,请参阅 Index 参数

构建 Index

要在 Milvus 中的向量 field 上构建 IVF_PQ index,使用 add_index() 方法,指定 index_typemetric_type 和 index 的其他参数。

from pymilvus import MilvusClient

# Prepare index building params
index_params = MilvusClient.prepare_index_params()

index_params.add_index(
field_name="your_vector_field_name", # Name of the vector field to be indexed
index_type="IVF_PQ", # Type of the index to create
index_name="vector_index", # Name of the index to create
metric_type="L2", # Metric type used to measure similarity
params={
"m": 4, # Number of sub-vectors to split eahc vector into
} # Index building params
)

在此配置中:

  • index_type:要构建的 index 类型。在此示例中,将值设置为 IVF_PQ

  • metric_type:用于计算向量之间距离的方法。支持的值包括 COSINEL2IP。有关详细信息,请参阅 度量类型

  • params:构建 index 的其他配置选项。

    • m:将向量分割成的子向量数量。

    要了解 IVF_PQ index 可用的更多构建参数,请参阅 Index 构建参数

配置 index 参数后,您可以直接使用 create_index() 方法创建 index,或在 create_collection 方法中传递 index 参数。有关详细信息,请参阅 创建 Collection

在 Index 上搜索

构建 index 并插入 entity 后,您可以在 index 上执行相似性搜索。

search_params = {
"params": {
"nprobe": 10, # Number of clusters to search
}
}

res = MilvusClient.search(
collection_name="your_collection_name", # Collection name
anns_field="vector_field", # Vector field name
data=[[0.1, 0.2, 0.3, 0.4, 0.5]], # Query vector
limit=3, # TopK results to return
search_params=search_params
)

在此配置中:

  • params:在 index 上搜索的其他配置选项。

    • nprobe:要搜索的聚类数量。

    要了解 IVF_PQ index 可用的更多搜索参数,请参阅 Index 特定搜索参数

Index 参数

本节概述了用于构建 index 和在 index 上执行搜索的参数。

Index 构建参数

下表列出了在构建 index 时可以在 params 中配置的参数。

参数

描述

值范围

调优建议

IVF

nlist

在索引构建期间使用 k-means 算法创建的聚类数量。

类型:整数 范围:[1, 65536]

默认值128

更大的 nlist 值通过创建更精细的聚类来提高召回率,但会增加索引构建时间。根据数据集大小和可用资源进行优化。在大多数情况下,我们建议您在此范围内设置值:[32, 4096]。

PQ

m

在量化过程中将每个高维向量分割成的子向量(用于量化)数量。

类型:整数 范围:[1, 65536]

默认值:无

更高的 m 值可以提高准确性,但也会增加计算复杂性和内存使用。m 必须是向量维度(D)的除数以确保正确分解。常见推荐值是 m = D/2

在大多数情况下,我们建议您在此范围内设置值:[D/8, D]。

nbits

用于在压缩形式中表示每个子向量质心索引的位数。它直接确定每个码本的大小。每个码本将包含 2^nbits 个质心。例如,如果 nbits 设置为 8,每个子向量将由 8 位质心索引表示。这允许该子向量的码本中有 2^8 (256) 个可能的质心。

类型:整数 范围:[1, 64]

默认值8

更高的 nbits 值允许更大的码本,可能导致原始向量的更准确表示。但是,这也意味着使用更多位来存储每个索引,导致较少的压缩。在大多数情况下,我们建议您在此范围内设置值:[1, 16]。

Index 特定搜索参数

下表列出了在在 index 上搜索时可以在 search_params.params 中配置的参数。

参数

描述

值范围

调优建议

IVF

nprobe

要搜索候选的聚类数量。

类型:整数 范围:[1, nlist]

默认值8

更高的值允许搜索更多聚类,通过扩展搜索范围来提高召回率,但会增加查询延迟。将 nprobenlist 成比例设置以平衡速度和准确性。

在大多数情况下,我们建议您在此范围内设置值:[1, nlist]。