Faiss 16位标量量化
UDB-SX 支持在 Faiss 引擎内部执行标量量化。在 Faiss 引擎中,标量量化器执行 32 位向量与 16 位向量之间的转换。在数据摄入时,当您将 32 位浮点向量上传到 UDB-SX 时,SQfp16 会将它们量化为 16 位浮点向量,并将量化后的向量存储在向量索引中。
在搜索时,SQfp16 将向量值解码回 32 位浮点值以进行距离计算。SQfp16 量化可以将内存占用减少一半。此外,当向量值之间的差异远大于因消除其最低有效两位而引入的误差时,量化导致的召回率损失微乎其微。当与 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": "sq"
},
"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 内存估算
分层可导航小世界图所需的内存估算为 1.1 * (2 * 维度 + 8 * m) 字节/向量,其中 m 是在图构建过程中为每个元素创建的最大双向链接数。
举例说明,假设您有 100 万个向量,维度为 256,m 值为 16。内存需求估算如下:
1.1 * (2 * 256 + 8 * 16) * 1,000,000 ≈ 0.656 GB
IVF 内存估算
IVF 所需的内存估算为 1.1 * (((2 * 维度) * 向量数) + (4 * nlist * 维度)) 字节/向量,其中 nlist 是将向量分区到的桶的数量。
举例说明,假设您有 100 万个向量,维度为 256,nlist 值为 128。内存需求估算如下:
1.1 * (((2 * 256) * 1,000,000) + (4 * 128 * 256)) ≈ 0.525 GB