Lucene 标量量化
OpenSearch 从 2.16 版本开始支持 Lucene 引擎的内置标量量化。与需要您在摄取文档之前对向量进行量化的字节向量不同,Lucene 标量量化器在 OpenSearch 摄取期间对输入向量进行量化。Lucene 标量量化器使用基于 confidence_interval
参数计算的最小和最大分位数,将每个段中的 32 位浮点输入向量转换为 7 位整数向量。在搜索期间,查询向量在每个段中使用该段的最小和最大分位数进行量化,以便计算查询向量与该段量化输入向量之间的距离。
量化可以将内存占用减少 4 倍,但会牺牲一定的召回率。此外,量化会略微增加磁盘使用量,因为它需要同时存储原始输入向量和量化向量。
使用 Lucene 标量量化
要使用 Lucene 标量量化器,请在创建向量索引时将 k-NN 向量字段的 method.parameters.encoder.name
设置为 sq
PUT /test-index
{
"settings": {
"index": {
"knn": true
}
},
"mappings": {
"properties": {
"my_vector1": {
"type": "knn_vector",
"dimension": 2,
"space_type": "l2",
"method": {
"name": "hnsw",
"engine": "lucene",
"parameters": {
"encoder": {
"name": "sq"
},
"ef_construction": 256,
"m": 8
}
}
}
}
}
}
置信区间
(可选)您可以在 method.parameters.encoder
对象中指定 confidence_interval
参数。confidence_interval
用于计算最小和最大分位数,以便对向量进行量化
- 如果将
confidence_interval
设置为0.9
到1.0
(含)范围内的值,则分位数是静态计算的。例如,将confidence_interval
设置为0.9
表示根据向量值中间的 90% 计算最小和最大分位数,排除最小值 5% 和最大值 5% 的值。 - 将
confidence_interval
设置为0
表示动态计算分位数,这涉及到对输入数据进行过采样和额外的计算。 - 当未设置
confidence_interval
时,它将根据向量维度 \(d\) 使用公式 \(max(0.9, 1 - \frac{1}{1 + d})\) 进行计算。
Lucene 标量量化仅适用于 float
向量。如果您在映射 k-NN 向量时将 data_type
参数的默认值从 float
更改为 byte
或任何其他类型,则请求将被拒绝。
以下示例方法定义指定了 Lucene sq
编码器,其 confidence_interval
设置为 1.0
。此 confidence_interval
指定在计算最小和最大分位数时考虑所有输入向量。向量默认量化为 7 位
PUT /test-index
{
"settings": {
"index": {
"knn": true
}
},
"mappings": {
"properties": {
"my_vector1": {
"type": "knn_vector",
"dimension": 2,
"space_type": "l2",
"method": {
"name": "hnsw",
"engine": "lucene",
"parameters": {
"encoder": {
"name": "sq",
"parameters": {
"confidence_interval": 1.0
}
},
"ef_construction": 256,
"m": 8
}
}
}
}
}
}
摄取或查询映射没有变化,输入向量也没有范围限制。
内存估算
在理想情况下,Lucene 标量量化器创建的 7 位向量仅使用 32 位向量所需内存的 25%。
HNSW 内存估算
分层可导航小世界 (HNSW) 图所需的内存可估算为 1.1 * (dimension + 8 * m)
字节/向量,其中 m
是在图构建期间为每个元素创建的最大双向链接数。
举例来说,假设您有 100 万个维度为 256 且 M 为 16 的向量。内存需求可估算如下:
1.1 * (256 + 8 * 16) * 1,000,000 ~= 0.4 GB