Link Search Menu Expand Document Documentation Menu

Faiss 16 位标量量化

从 2.13 版本开始,OpenSearch 支持在 OpenSearch 内对 Faiss 引擎执行标量量化。在 Faiss 引擎中,标量量化器 (SQfp16) 执行 32 位和 16 位向量之间的转换。在摄入时,当您将 32 位浮点向量上传到 OpenSearch 时,SQfp16 会将它们量化为 16 位浮点向量,并将量化后的向量存储在向量索引中。

在搜索时,SQfp16 将向量值解码回 32 位浮点值以进行距离计算。SQfp16 量化可以将内存占用减少 2 倍。此外,当向量值之间的差异相对于消除其两个最低有效位引入的误差较大时,它只会导致召回率的最小损失。当与 SIMD 优化结合使用时,SQfp16 量化还可以显著降低搜索延迟并提高索引吞吐量。

Windows 不支持 SIMD 优化。在 Windows 上使用 Faiss 标量量化可能会导致性能显著下降,包括索引吞吐量降低和搜索延迟增加。

使用 Faiss 标量量化

要使用 Faiss 标量量化,请在创建向量索引时将 k-NN 向量字段的 method.parameters.encoder.name 设置为 fp16

PUT /test-index
{
  "settings": {
    "index": {
      "knn": true,
      "knn.algo_param.ef_search": 100
    }
  },
  "mappings": {
    "properties": {
      "my_vector1": {
        "type": "knn_vector",
        "dimension": 3,
        "space_type": "l2",
        "method": {
          "name": "hnsw",
          "engine": "faiss",
          "parameters": {
            "encoder": {
              "name": "fp16"
            },
            "ef_construction": 256,
            "m": 8
          }
        }
      }
    }
  }
}

您可以选择在 method.parameters.encoder 中指定参数。有关 encoder 对象参数的更多信息,请参阅SQ 参数

fp16 编码器将 32 位向量转换为其对应的 16 位向量。对于此编码器类型,向量值必须在 [-65504.0, 65504.0] 范围内。为定义如何处理超出范围的值,前面的请求指定了 clip 参数。默认情况下,此参数为 false,任何包含超出范围值的向量都将被拒绝。

clip 设置为 true(如前面的请求所示)时,超出范围的向量值将被向上或向下舍入,使其位于支持的范围内。例如,如果原始的 32 位向量是 [65510.82, -65504.1],则该向量将作为 16 位向量 [65504.0, -65504.0] 进行索引。

仅当很少的元素超出支持范围时,我们才建议将 clip 设置为 true。舍入值可能会导致召回率下降。

以下示例方法定义指定了 Faiss SQfp16 编码器,该编码器会拒绝任何包含超出范围向量值的索引请求(因为 clip 参数默认为 false

PUT /test-index
{
  "settings": {
    "index": {
      "knn": true,
      "knn.algo_param.ef_search": 100
    }
  },
  "mappings": {
    "properties": {
      "my_vector1": {
        "type": "knn_vector",
        "dimension": 3,
        "space_type": "l2",
        "method": {
          "name": "hnsw",
          "engine": "faiss",
          "parameters": {
            "encoder": {
              "name": "sq",
              "parameters": {
                "type": "fp16"
              }
            },
            "ef_construction": 256,
            "m": 8
          }
        }
      }
    }
  }
}

在摄入过程中,请确保每个向量维度都在支持的范围 ([-65504.0, 65504.0]) 内。

PUT test-index/_doc/1
{
  "my_vector1": [-65504.0, 65503.845, 55.82]
}

在查询时,查询向量没有范围限制

GET test-index/_search
{
  "size": 2,
  "query": {
    "knn": {
      "my_vector1": {
        "vector": [265436.876, -120906.256, 99.84],
        "k": 2
      }
    }
  }
}

内存估算

在最佳情况下,Faiss SQfp16 量化器生成的 16 位向量所需的内存是 32 位向量所需内存的 50%。

HNSW 内存估算

分层可导航小世界 (HNSW) 所需的内存估计为 1.1 * (2 * dimension + 8 * m) 字节/向量,其中 m 是在图构建过程中为每个元素创建的最大双向链接数。

例如,假设您有 100 万个向量,维度为 256,m 为 16。内存需求可估算如下:

1.1 * (2 * 256 + 8 * 16) * 1,000,000 ~= 0.656 GB

IVF 内存估算

IVF 所需的内存估计为 1.1 * (((2 * dimension) * num_vectors) + (4 * nlist * dimension)) 字节/向量,其中 nlist 是用于将向量分区到的桶的数量。

例如,假设您有 100 万个向量,维度为 256,nlist 为 128。内存需求可估算如下:

1.1 * (((2 * 256) * 1,000,000) + (4 * 128 * 256))  ~= 0.525 GB

后续步骤

剩余 350 字符

有问题?

想要贡献?