Skip to content

Commit ea83e41

Browse files
benwtrentelasticsearchmachine
andauthored
[8.19] New vector_rescore parameter as a quantized index type option (#124581) (#127644)
* New `vector_rescore` parameter as a quantized index type option (#124581) This adds a new parameter to the quantized index mapping that allows default oversampling and rescoring to occur. This doesn't adjust any of the defaults. It allows it to be configured. When the user provides `rescore_vector: {oversample: <number>}` in the query it will overwrite it. For example, here is how to use it with bbq: ``` PUT rescored_bbq { "mappings": { "properties": { "vector": { "type": "dense_vector", "index_options": { "type": "bbq_hnsw", "rescore_vector": {"oversample": 3.0} } } } } } ``` Then, when querying, it will auto oversample the `k` by `3x` and rerank with the raw vectors. ``` POST _search { "knn": { "query_vector": [...], "field": "vector" } } ``` (cherry picked from commit b2c1c4e) * Adds new BWC version for 8.19 backport of (#124581) (#127647) * [CI] Auto commit changes from spotless --------- Co-authored-by: elasticsearchmachine <[email protected]>
1 parent 8c18619 commit ea83e41

File tree

12 files changed

+860
-58
lines changed

12 files changed

+860
-58
lines changed

docs/changelog/124581.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 124581
2+
summary: New `vector_rescore` parameter as a quantized index type option
3+
area: Vector Search
4+
type: enhancement
5+
issues: []

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.vectors/41_knn_search_bbq_hnsw.yml

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,93 @@ setup:
250250
index: dynamic_dim_bbq_hnsw
251251
body:
252252
vector: [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0]
253+
---
254+
"Test index configured rescore vector":
255+
- requires:
256+
cluster_features: ["mapper.dense_vector.rescore_vector"]
257+
reason: Needs rescore_vector feature
258+
- skip:
259+
features: "headers"
260+
- do:
261+
indices.create:
262+
index: bbq_rescore_hnsw
263+
body:
264+
settings:
265+
index:
266+
number_of_shards: 1
267+
mappings:
268+
properties:
269+
vector:
270+
type: dense_vector
271+
dims: 64
272+
index: true
273+
similarity: max_inner_product
274+
index_options:
275+
type: bbq_hnsw
276+
rescore_vector:
277+
oversample: 1.5
278+
279+
- do:
280+
bulk:
281+
index: bbq_rescore_hnsw
282+
refresh: true
283+
body: |
284+
{ "index": {"_id": "1"}}
285+
{ "vector": [0.077, 0.32 , -0.205, 0.63 , 0.032, 0.201, 0.167, -0.313, 0.176, 0.531, -0.375, 0.334, -0.046, 0.078, -0.349, 0.272, 0.307, -0.083, 0.504, 0.255, -0.404, 0.289, -0.226, -0.132, -0.216, 0.49 , 0.039, 0.507, -0.307, 0.107, 0.09 , -0.265, -0.285, 0.336, -0.272, 0.369, -0.282, 0.086, -0.132, 0.475, -0.224, 0.203, 0.439, 0.064, 0.246, -0.396, 0.297, 0.242, -0.028, 0.321, -0.022, -0.009, -0.001 , 0.031, -0.533, 0.45, -0.683, 1.331, 0.194, -0.157, -0.1 , -0.279, -0.098, -0.176] }
286+
{ "index": {"_id": "2"}}
287+
{ "vector": [0.196, 0.514, 0.039, 0.555, -0.042, 0.242, 0.463, -0.348, -0.08 , 0.442, -0.067, -0.05 , -0.001, 0.298, -0.377, 0.048, 0.307, 0.159, 0.278, 0.119, -0.057, 0.333, -0.289, -0.438, -0.014, 0.361, -0.169, 0.292, -0.229, 0.123, 0.031, -0.138, -0.139, 0.315, -0.216, 0.322, -0.445, -0.059, 0.071, 0.429, -0.602, -0.142, 0.11 , 0.192, 0.259, -0.241, 0.181, -0.166, 0.082, 0.107, -0.05 , 0.155, 0.011, 0.161, -0.486, 0.569, -0.489, 0.901, 0.208, 0.011, -0.209, -0.153, -0.27 , -0.013] }
288+
{ "index": {"_id": "3"}}
289+
{ "vector": [0.196, 0.514, 0.039, 0.555, -0.042, 0.242, 0.463, -0.348, -0.08 , 0.442, -0.067, -0.05 , -0.001, 0.298, -0.377, 0.048, 0.307, 0.159, 0.278, 0.119, -0.057, 0.333, -0.289, -0.438, -0.014, 0.361, -0.169, 0.292, -0.229, 0.123, 0.031, -0.138, -0.139, 0.315, -0.216, 0.322, -0.445, -0.059, 0.071, 0.429, -0.602, -0.142, 0.11 , 0.192, 0.259, -0.241, 0.181, -0.166, 0.082, 0.107, -0.05 , 0.155, 0.011, 0.161, -0.486, 0.569, -0.489, 0.901, 0.208, 0.011, -0.209, -0.153, -0.27 , -0.013] }
290+
291+
- do:
292+
headers:
293+
Content-Type: application/json
294+
search:
295+
rest_total_hits_as_int: true
296+
index: bbq_rescore_hnsw
297+
body:
298+
knn:
299+
field: vector
300+
query_vector: [0.128, 0.067, -0.08 , 0.395, -0.11 , -0.259, 0.473, -0.393,
301+
0.292, 0.571, -0.491, 0.444, -0.288, 0.198, -0.343, 0.015,
302+
0.232, 0.088, 0.228, 0.151, -0.136, 0.236, -0.273, -0.259,
303+
-0.217, 0.359, -0.207, 0.352, -0.142, 0.192, -0.061, -0.17 ,
304+
-0.343, 0.189, -0.221, 0.32 , -0.301, -0.1 , 0.005, 0.232,
305+
-0.344, 0.136, 0.252, 0.157, -0.13 , -0.244, 0.193, -0.034,
306+
-0.12 , -0.193, -0.102, 0.252, -0.185, -0.167, -0.575, 0.582,
307+
-0.426, 0.983, 0.212, 0.204, 0.03 , -0.276, -0.425, -0.158]
308+
k: 3
309+
num_candidates: 3
310+
311+
- match: { hits.total: 3 }
312+
- set: { hits.hits.0._score: rescore_score0 }
313+
- set: { hits.hits.1._score: rescore_score1 }
314+
- set: { hits.hits.2._score: rescore_score2 }
315+
316+
- do:
317+
headers:
318+
Content-Type: application/json
319+
search:
320+
rest_total_hits_as_int: true
321+
index: bbq_rescore_hnsw
322+
body:
323+
query:
324+
script_score:
325+
query: {match_all: {} }
326+
script:
327+
source: "double similarity = dotProduct(params.query_vector, 'vector'); return similarity < 0 ? 1 / (1 + -1 * similarity) : similarity + 1"
328+
params:
329+
query_vector: [0.128, 0.067, -0.08 , 0.395, -0.11 , -0.259, 0.473, -0.393,
330+
0.292, 0.571, -0.491, 0.444, -0.288, 0.198, -0.343, 0.015,
331+
0.232, 0.088, 0.228, 0.151, -0.136, 0.236, -0.273, -0.259,
332+
-0.217, 0.359, -0.207, 0.352, -0.142, 0.192, -0.061, -0.17 ,
333+
-0.343, 0.189, -0.221, 0.32 , -0.301, -0.1 , 0.005, 0.232,
334+
-0.344, 0.136, 0.252, 0.157, -0.13 , -0.244, 0.193, -0.034,
335+
-0.12 , -0.193, -0.102, 0.252, -0.185, -0.167, -0.575, 0.582,
336+
-0.426, 0.983, 0.212, 0.204, 0.03 , -0.276, -0.425, -0.158]
337+
338+
# Compare scores as hit IDs may change depending on how things are distributed
339+
- match: { hits.total: 3 }
340+
- match: { hits.hits.0._score: $rescore_score0 }
341+
- match: { hits.hits.1._score: $rescore_score1 }
342+
- match: { hits.hits.2._score: $rescore_score2 }

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.vectors/41_knn_search_byte_quantized.yml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,3 +611,92 @@ setup:
611611
- match: { hits.hits.0._id: "1"}
612612
- match: { hits.hits.1._id: "2"}
613613
- match: { hits.hits.2._id: "3"}
614+
---
615+
"Test index configured rescore vector":
616+
- requires:
617+
cluster_features: ["mapper.dense_vector.rescore_vector"]
618+
reason: Needs rescore_vector feature
619+
- skip:
620+
features: "headers"
621+
- do:
622+
indices.create:
623+
index: int8_rescore_hnsw
624+
body:
625+
settings:
626+
index:
627+
number_of_shards: 1
628+
mappings:
629+
properties:
630+
vector:
631+
type: dense_vector
632+
dims: 64
633+
index: true
634+
similarity: max_inner_product
635+
index_options:
636+
type: int8_hnsw
637+
rescore_vector:
638+
oversample: 1.5
639+
640+
- do:
641+
bulk:
642+
index: int8_rescore_hnsw
643+
refresh: true
644+
body: |
645+
{ "index": {"_id": "1"}}
646+
{ "vector": [0.077, 0.32 , -0.205, 0.63 , 0.032, 0.201, 0.167, -0.313, 0.176, 0.531, -0.375, 0.334, -0.046, 0.078, -0.349, 0.272, 0.307, -0.083, 0.504, 0.255, -0.404, 0.289, -0.226, -0.132, -0.216, 0.49 , 0.039, 0.507, -0.307, 0.107, 0.09 , -0.265, -0.285, 0.336, -0.272, 0.369, -0.282, 0.086, -0.132, 0.475, -0.224, 0.203, 0.439, 0.064, 0.246, -0.396, 0.297, 0.242, -0.028, 0.321, -0.022, -0.009, -0.001 , 0.031, -0.533, 0.45, -0.683, 1.331, 0.194, -0.157, -0.1 , -0.279, -0.098, -0.176] }
647+
{ "index": {"_id": "2"}}
648+
{ "vector": [0.196, 0.514, 0.039, 0.555, -0.042, 0.242, 0.463, -0.348, -0.08 , 0.442, -0.067, -0.05 , -0.001, 0.298, -0.377, 0.048, 0.307, 0.159, 0.278, 0.119, -0.057, 0.333, -0.289, -0.438, -0.014, 0.361, -0.169, 0.292, -0.229, 0.123, 0.031, -0.138, -0.139, 0.315, -0.216, 0.322, -0.445, -0.059, 0.071, 0.429, -0.602, -0.142, 0.11 , 0.192, 0.259, -0.241, 0.181, -0.166, 0.082, 0.107, -0.05 , 0.155, 0.011, 0.161, -0.486, 0.569, -0.489, 0.901, 0.208, 0.011, -0.209, -0.153, -0.27 , -0.013] }
649+
{ "index": {"_id": "3"}}
650+
{ "vector": [0.196, 0.514, 0.039, 0.555, -0.042, 0.242, 0.463, -0.348, -0.08 , 0.442, -0.067, -0.05 , -0.001, 0.298, -0.377, 0.048, 0.307, 0.159, 0.278, 0.119, -0.057, 0.333, -0.289, -0.438, -0.014, 0.361, -0.169, 0.292, -0.229, 0.123, 0.031, -0.138, -0.139, 0.315, -0.216, 0.322, -0.445, -0.059, 0.071, 0.429, -0.602, -0.142, 0.11 , 0.192, 0.259, -0.241, 0.181, -0.166, 0.082, 0.107, -0.05 , 0.155, 0.011, 0.161, -0.486, 0.569, -0.489, 0.901, 0.208, 0.011, -0.209, -0.153, -0.27 , -0.013] }
651+
652+
- do:
653+
headers:
654+
Content-Type: application/json
655+
search:
656+
rest_total_hits_as_int: true
657+
index: int8_rescore_hnsw
658+
body:
659+
knn:
660+
field: vector
661+
query_vector: [0.128, 0.067, -0.08 , 0.395, -0.11 , -0.259, 0.473, -0.393,
662+
0.292, 0.571, -0.491, 0.444, -0.288, 0.198, -0.343, 0.015,
663+
0.232, 0.088, 0.228, 0.151, -0.136, 0.236, -0.273, -0.259,
664+
-0.217, 0.359, -0.207, 0.352, -0.142, 0.192, -0.061, -0.17 ,
665+
-0.343, 0.189, -0.221, 0.32 , -0.301, -0.1 , 0.005, 0.232,
666+
-0.344, 0.136, 0.252, 0.157, -0.13 , -0.244, 0.193, -0.034,
667+
-0.12 , -0.193, -0.102, 0.252, -0.185, -0.167, -0.575, 0.582,
668+
-0.426, 0.983, 0.212, 0.204, 0.03 , -0.276, -0.425, -0.158]
669+
k: 3
670+
num_candidates: 3
671+
672+
- match: { hits.total: 3 }
673+
- set: { hits.hits.0._score: rescore_score0 }
674+
- set: { hits.hits.1._score: rescore_score1 }
675+
- set: { hits.hits.2._score: rescore_score2 }
676+
677+
- do:
678+
headers:
679+
Content-Type: application/json
680+
search:
681+
rest_total_hits_as_int: true
682+
body:
683+
query:
684+
script_score:
685+
query: {match_all: {} }
686+
script:
687+
source: "double similarity = dotProduct(params.query_vector, 'vector'); return similarity < 0 ? 1 / (1 + -1 * similarity) : similarity + 1"
688+
params:
689+
query_vector: [0.128, 0.067, -0.08 , 0.395, -0.11 , -0.259, 0.473, -0.393,
690+
0.292, 0.571, -0.491, 0.444, -0.288, 0.198, -0.343, 0.015,
691+
0.232, 0.088, 0.228, 0.151, -0.136, 0.236, -0.273, -0.259,
692+
-0.217, 0.359, -0.207, 0.352, -0.142, 0.192, -0.061, -0.17 ,
693+
-0.343, 0.189, -0.221, 0.32 , -0.301, -0.1 , 0.005, 0.232,
694+
-0.344, 0.136, 0.252, 0.157, -0.13 , -0.244, 0.193, -0.034,
695+
-0.12 , -0.193, -0.102, 0.252, -0.185, -0.167, -0.575, 0.582,
696+
-0.426, 0.983, 0.212, 0.204, 0.03 , -0.276, -0.425, -0.158]
697+
698+
# Compare scores as hit IDs may change depending on how things are distributed
699+
- match: { hits.total: 3 }
700+
- match: { hits.hits.0._score: $rescore_score0 }
701+
- match: { hits.hits.1._score: $rescore_score1 }
702+
- match: { hits.hits.2._score: $rescore_score2 }

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.vectors/41_knn_search_half_byte_quantized.yml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,3 +645,92 @@ setup:
645645
index: dynamic_dim_hnsw_quantized
646646
body:
647647
vector: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
648+
---
649+
"Test index configured rescore vector":
650+
- requires:
651+
cluster_features: ["mapper.dense_vector.rescore_vector"]
652+
reason: Needs rescore_vector feature
653+
- skip:
654+
features: "headers"
655+
- do:
656+
indices.create:
657+
index: int4_rescore_hnsw
658+
body:
659+
settings:
660+
index:
661+
number_of_shards: 1
662+
mappings:
663+
properties:
664+
vector:
665+
type: dense_vector
666+
dims: 64
667+
index: true
668+
similarity: max_inner_product
669+
index_options:
670+
type: int4_hnsw
671+
rescore_vector:
672+
oversample: 1.5
673+
674+
- do:
675+
bulk:
676+
index: int4_rescore_hnsw
677+
refresh: true
678+
body: |
679+
{ "index": {"_id": "1"}}
680+
{ "vector": [0.077, 0.32 , -0.205, 0.63 , 0.032, 0.201, 0.167, -0.313, 0.176, 0.531, -0.375, 0.334, -0.046, 0.078, -0.349, 0.272, 0.307, -0.083, 0.504, 0.255, -0.404, 0.289, -0.226, -0.132, -0.216, 0.49 , 0.039, 0.507, -0.307, 0.107, 0.09 , -0.265, -0.285, 0.336, -0.272, 0.369, -0.282, 0.086, -0.132, 0.475, -0.224, 0.203, 0.439, 0.064, 0.246, -0.396, 0.297, 0.242, -0.028, 0.321, -0.022, -0.009, -0.001 , 0.031, -0.533, 0.45, -0.683, 1.331, 0.194, -0.157, -0.1 , -0.279, -0.098, -0.176] }
681+
{ "index": {"_id": "2"}}
682+
{ "vector": [0.196, 0.514, 0.039, 0.555, -0.042, 0.242, 0.463, -0.348, -0.08 , 0.442, -0.067, -0.05 , -0.001, 0.298, -0.377, 0.048, 0.307, 0.159, 0.278, 0.119, -0.057, 0.333, -0.289, -0.438, -0.014, 0.361, -0.169, 0.292, -0.229, 0.123, 0.031, -0.138, -0.139, 0.315, -0.216, 0.322, -0.445, -0.059, 0.071, 0.429, -0.602, -0.142, 0.11 , 0.192, 0.259, -0.241, 0.181, -0.166, 0.082, 0.107, -0.05 , 0.155, 0.011, 0.161, -0.486, 0.569, -0.489, 0.901, 0.208, 0.011, -0.209, -0.153, -0.27 , -0.013] }
683+
{ "index": {"_id": "3"}}
684+
{ "vector": [0.196, 0.514, 0.039, 0.555, -0.042, 0.242, 0.463, -0.348, -0.08 , 0.442, -0.067, -0.05 , -0.001, 0.298, -0.377, 0.048, 0.307, 0.159, 0.278, 0.119, -0.057, 0.333, -0.289, -0.438, -0.014, 0.361, -0.169, 0.292, -0.229, 0.123, 0.031, -0.138, -0.139, 0.315, -0.216, 0.322, -0.445, -0.059, 0.071, 0.429, -0.602, -0.142, 0.11 , 0.192, 0.259, -0.241, 0.181, -0.166, 0.082, 0.107, -0.05 , 0.155, 0.011, 0.161, -0.486, 0.569, -0.489, 0.901, 0.208, 0.011, -0.209, -0.153, -0.27 , -0.013] }
685+
686+
- do:
687+
headers:
688+
Content-Type: application/json
689+
search:
690+
rest_total_hits_as_int: true
691+
index: int4_rescore_hnsw
692+
body:
693+
knn:
694+
field: vector
695+
query_vector: [0.128, 0.067, -0.08 , 0.395, -0.11 , -0.259, 0.473, -0.393,
696+
0.292, 0.571, -0.491, 0.444, -0.288, 0.198, -0.343, 0.015,
697+
0.232, 0.088, 0.228, 0.151, -0.136, 0.236, -0.273, -0.259,
698+
-0.217, 0.359, -0.207, 0.352, -0.142, 0.192, -0.061, -0.17 ,
699+
-0.343, 0.189, -0.221, 0.32 , -0.301, -0.1 , 0.005, 0.232,
700+
-0.344, 0.136, 0.252, 0.157, -0.13 , -0.244, 0.193, -0.034,
701+
-0.12 , -0.193, -0.102, 0.252, -0.185, -0.167, -0.575, 0.582,
702+
-0.426, 0.983, 0.212, 0.204, 0.03 , -0.276, -0.425, -0.158]
703+
k: 3
704+
num_candidates: 3
705+
706+
- match: { hits.total: 3 }
707+
- set: { hits.hits.0._score: rescore_score0 }
708+
- set: { hits.hits.1._score: rescore_score1 }
709+
- set: { hits.hits.2._score: rescore_score2 }
710+
711+
- do:
712+
headers:
713+
Content-Type: application/json
714+
search:
715+
rest_total_hits_as_int: true
716+
body:
717+
query:
718+
script_score:
719+
query: {match_all: {} }
720+
script:
721+
source: "double similarity = dotProduct(params.query_vector, 'vector'); return similarity < 0 ? 1 / (1 + -1 * similarity) : similarity + 1"
722+
params:
723+
query_vector: [0.128, 0.067, -0.08 , 0.395, -0.11 , -0.259, 0.473, -0.393,
724+
0.292, 0.571, -0.491, 0.444, -0.288, 0.198, -0.343, 0.015,
725+
0.232, 0.088, 0.228, 0.151, -0.136, 0.236, -0.273, -0.259,
726+
-0.217, 0.359, -0.207, 0.352, -0.142, 0.192, -0.061, -0.17 ,
727+
-0.343, 0.189, -0.221, 0.32 , -0.301, -0.1 , 0.005, 0.232,
728+
-0.344, 0.136, 0.252, 0.157, -0.13 , -0.244, 0.193, -0.034,
729+
-0.12 , -0.193, -0.102, 0.252, -0.185, -0.167, -0.575, 0.582,
730+
-0.426, 0.983, 0.212, 0.204, 0.03 , -0.276, -0.425, -0.158]
731+
732+
# Compare scores as hit IDs may change depending on how things are distributed
733+
- match: { hits.total: 3 }
734+
- match: { hits.hits.0._score: $rescore_score0 }
735+
- match: { hits.hits.1._score: $rescore_score1 }
736+
- match: { hits.hits.2._score: $rescore_score2 }

0 commit comments

Comments
 (0)