Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/reference/elasticsearch/mapping-reference/bbq.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,13 @@ A lower `visit_percentage` can further reduce memory use and speed up queries, w
stack: ga 9.4
```
By default, BBQ performs asymmetric quantization: it performs 1-bit quantization for the indexed vectors and 4-bit quantization for query vectors.
For fields of type `bbq_disk` it is possible to change the level of quantization for indexed vectors by setting the `bits` parameter in `index_options` to `1` (default), `2` or `4`.
For fields of type `bbq_disk` it is possible to change the level of quantization for indexed vectors by setting the `bits` parameter in `index_options` to `1` (default), `2`, `4` or `7`.

If no `oversampling_factor` is specified, setting `bits` will automatically adjust that as follows:
* `bits = 1` --> `oversampling_factor = 3.0`
* `bits = 2` --> `oversampling_factor = 1.5`
* `bits = 4` --> `oversampling_factor = 0` (no oversampling)
* `bits = 7` --> `oversampling_factor = 0` (no oversampling)

```console
PUT bbq_disk-index/_mapping
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1836,9 +1836,9 @@ public DenseVectorIndexOptions parseIndexOptions(
if (indexVersion.onOrAfter(DISK_BBQ_QUANTIZE_BITS) && experimentalFeaturesEnabled) {
Object quantizeBitsNode = indexOptionsMap.remove("bits");
quantizeBits = XContentMapValues.nodeIntegerValue(quantizeBitsNode, DEFAULT_BBQ_IVF_QUANTIZE_BITS);
if ((quantizeBits == 1 || quantizeBits == 2 || quantizeBits == 4) == false) {
if ((quantizeBits == 1 || quantizeBits == 2 || quantizeBits == 4 || quantizeBits == 7) == false) {
throw new IllegalArgumentException(
"'bits' must be 1, 2 or 4, got: " + quantizeBits + " for field [" + fieldName + "]"
"'bits' must be 1, 2, 4 or 7, got: " + quantizeBits + " for field [" + fieldName + "]"
);
}
} else {
Expand Down Expand Up @@ -2562,7 +2562,7 @@ KnnVectorsFormat getVectorsFormat(ElementType elementType, ExecutorService mergi
}
if (experimentalFeaturesEnabled) {
return new ESNextDiskBBQVectorsFormat(
ESNextDiskBBQVectorsFormat.QuantEncoding.fromId(bits >> 1),
ESNextDiskBBQVectorsFormat.QuantEncoding.fromBits((byte) bits),
clusterSize,
ES920DiskBBQVectorsFormat.DEFAULT_CENTROIDS_PER_PARENT_CLUSTER,
elementType,
Expand Down Expand Up @@ -2653,6 +2653,10 @@ public boolean isOnDiskRescore() {
public boolean doPrecondition() {
return doPrecondition;
}

public int getBits() {
return bits;
}
}

public record RescoreVector(float oversample) implements ToXContentObject {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,25 @@ public void testIVFParsing() throws IOException {
assertEquals(-1, indexOptions.getFlatIndexThreshold());
assertEquals(DYNAMIC_VISIT_RATIO, indexOptions.defaultVisitPercentage, 0.0);
}
{
DocumentMapper mapperService = createMapperService(experimentalEnabled, fieldMapping(b -> {
b.field("type", "dense_vector");
b.field("dims", 128);
b.field("index", true);
b.field("similarity", "dot_product");
b.startObject("index_options");
b.field("type", "bbq_disk");
b.field("bits", 7);
b.endObject();
})).documentMapper();

DenseVectorFieldMapper denseVectorFieldMapper = (DenseVectorFieldMapper) mapperService.mappers().getMapper("field");
DenseVectorFieldMapper.BBQIVFIndexOptions indexOptions = (DenseVectorFieldMapper.BBQIVFIndexOptions) denseVectorFieldMapper
.fieldType()
.getIndexOptions();
assertEquals(7, indexOptions.bits, 0.0F);
assertNull(indexOptions.rescoreVector);
}
{
DocumentMapper mapperService = createMapperService(experimentalDisabled, fieldMapping(b -> {
b.field("type", "dense_vector");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public VectorsFormatProvider getVectorsFormatProvider() {
int flatIndexThreshold = diskbbq.getFlatIndexThreshold();
if (Build.current().isSnapshot()) {
return new ESNextDiskBBQVectorsFormat(
ESNextDiskBBQVectorsFormat.QuantEncoding.ONE_BIT_4BIT_QUERY,
ESNextDiskBBQVectorsFormat.QuantEncoding.fromBits((byte) diskbbq.getBits()),
clusterSize,
ES920DiskBBQVectorsFormat.DEFAULT_CENTROIDS_PER_PARENT_CLUSTER,
elementType,
Expand Down
Loading