Rescore radial search quantized complete - #3337
Conversation
Signed-off-by: Dooyong Kim <kdooyong@amazon.com>
PR Reviewer Guide 🔍(Review updated until commit 3146536)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 3146536 Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit b43bbc5
Suggestions up to commit eedbae2
Suggestions up to commit bccd36f
Suggestions up to commit 7cab05e
Suggestions up to commit a86e85c
|
348d623 to
1760bb0
Compare
|
Persistent review updated to latest commit 1760bb0 |
1760bb0 to
a86e85c
Compare
|
Persistent review updated to latest commit a86e85c |
a86e85c to
7cab05e
Compare
|
Persistent review updated to latest commit 7cab05e |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## rescore-radial-quantized #3337 +/- ##
==============================================================
+ Coverage 83.52% 83.56% +0.04%
- Complexity 4294 4297 +3
==============================================================
Files 451 451
Lines 15564 15611 +47
Branches 2016 2022 +6
==============================================================
+ Hits 13000 13046 +46
- Misses 1774 1775 +1
Partials 790 790 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
7cab05e to
bccd36f
Compare
|
Persistent review updated to latest commit bccd36f |
bccd36f to
eedbae2
Compare
|
Persistent review updated to latest commit eedbae2 |
|
Is this PR is ready for Review , I see in Draft? @0ctopus13prime |
|
@Vikasht34 |
eedbae2 to
b43bbc5
Compare
|
Persistent review updated to latest commit b43bbc5 |
Signed-off-by: Dooyong Kim <kdooyong@amazon.com>
b43bbc5 to
3146536
Compare
|
Persistent review updated to latest commit 3146536 |
| final TopDocs rescored = EXACT_SEARCHER_SINGLETON.searchLeaf(context, exactSearcherContext); | ||
|
|
||
| // 6. Return scorer over rescored results | ||
| return new KNNScorer(rescored, boost); |
There was a problem hiding this comment.
One of the potential optimizations here is to have exact searcher return a scorer rather than topdocs. Returning topDocs here is redundant because TopScoreDocCollector will do it again. Collecting topDocs forces to loop through the entire results unnecessarily. This breaks the lazy behavior of lucene and bypasses early termination and leap frogging if at all its needed.
The idea is simple here, wrap the bulkScoring logic in an iterator and return a scorer from exact search level removing the redundant loop for creating TopDocs and packaging it again in KNNScorer. I have been thinking through this idea and see where this scorer is beneficial apart from radial search because exactsearch does not need to have topk either
There was a problem hiding this comment.
Agree. We can directly pull and sort docs from min-heap without having to convert them to TopDocs since as you mentioned, TopScoreDocCollector will do it again anyway.
And I think the lazy behavior will only be matter when it was used as a sub query, like Conjunction(TermQuery, Radial) for example. And in most case I believe radial search will be used as a top level query.
I believe we should find a way to get the entire query tree then decide whether to return iterator wrapper having exact searcher in it. But for that, we probably need core's support.
There was a problem hiding this comment.
We can directly pull and sort docs from min-heap without having to convert them to TopDocs
We don't even need a minHeap its additional JVM heap use followed by GC cleanup. Just a scorer which tells how to compute should be enough. We just need to make sure that the DocIdSetIterator of the scorer iterates the docs in sequence. No sorting, No looping through
And in most case I believe radial search will be used as a top level query.
Correct, it will still avoid the extra minHeap and looping through all results to get TopDocs again to hold those in memory, I understand these are minor things but might matter in a high throughput environments
I believe we should find a way to get the entire query tree then decide whether to return iterator wrapper having exact searcher in it. But for that, we probably need core's support.
Not necessarily if we abide by the lucene scorer contract, traversing a query tree is not needed.
There was a problem hiding this comment.
Hm, I think it's better to have a quick sync on this
But I think believe we still need the min heap when the intermediate result size > 10k though to extract top-10k vectors. If the result from 1st phase < 10k, then yes, it's not needed and this PR already has it.
Also be able to look at the entire query tree is essential in the optimization, as in my view, if radial search is at the top level, then we should run exact search aggressively otherwise we should get benefit from lazy evaluation.
shatejas
left a comment
There was a problem hiding this comment.
Looks good for now, we can take scorer optimization as followup
e981427
into
opensearch-project:rescore-radial-quantized
* Rescoring after radial search on quantized index. [Task 1 - 4] (#3300) * Bumped gradle to 9.4.1 and jacoco to 0.8.14 (#3308) Signed-off-by: Andrew Klepchick <aklepchi@amazon.com> * Use KNN1040ScalarQuantizedVectorsFormat for Faiss SQ flat format (#3302) The Faiss SQ format was using Lucene's Lucene104ScalarQuantizedVectorsFormat directly, which lacks the prefetch-enabled raw vector reader that KNN1040ScalarQuantizedVectorsFormat provides. This meant exact search rescoring was missing I/O prefetch during graph traversal. Changes: - Switch faissSqFlatFormat from Lucene104ScalarQuantizedVectorsFormat to KNN1040ScalarQuantizedVectorsFormat in Faiss1040ScalarQuantizedKnnVectorsFormat - Add @VisibleForTesting getFlatVectorsReader() to Faiss1040ScalarQuantizedKnnVectorsReader to replace reflection in tests - Add testGetRandomVectorScorer_returnsPrefetchableScorer in KNN1040ScalarQuantizedVectorsFormatTests verifying the scorer is PrefetchableRandomVectorScorer via a real write/read cycle - Replace reflection with getter in Faiss1040ScalarQuantizedKnnVectorsFormatTests.testFieldsReader_thenWrapsFlatReaderWithPrefetchSupport Signed-off-by: Vijayan Balasubramanian <balasvij@amazon.com> * Allow minScore, maxDistance for 32x SQ index. Signed-off-by: Dooyong Kim <kdooyong@amazon.com> Pass compression and quantization config to RNN query builder. Signed-off-by: Dooyong Kim <kdooyong@amazon.com> Added RescoreRadialSearchQuery. Signed-off-by: Dooyong Kim <kdooyong@amazon.com> Wiring `RescoreRadialSearchQuery` wrapper in `RNNQueryFactory` Signed-off-by: Dooyong Kim <kdooyong@amazon.com> --------- Signed-off-by: Andrew Klepchick <aklepchi@amazon.com> Signed-off-by: Vijayan Balasubramanian <balasvij@amazon.com> Signed-off-by: Dooyong Kim <kdooyong@amazon.com> Co-authored-by: Andrew Klepchick <aklepchi@amazon.com> Co-authored-by: Vijayan Balasubramanian <balasvij@amazon.com> * Rescore radial search quantized complete (#3337) * Added exact search logic after radial. Signed-off-by: Dooyong Kim <kdooyong@amazon.com> * Adding 2nd rescoring after radial search on quantized index. Signed-off-by: Dooyong Kim <kdooyong@amazon.com> --------- Signed-off-by: Dooyong Kim <kdooyong@amazon.com> * Update changelog Signed-off-by: Dooyong Kim <kdooyong@amazon.com> --------- Signed-off-by: Andrew Klepchick <aklepchi@amazon.com> Signed-off-by: Vijayan Balasubramanian <balasvij@amazon.com> Signed-off-by: Dooyong Kim <kdooyong@amazon.com> Co-authored-by: Andrew Klepchick <aklepchi@amazon.com> Co-authored-by: Vijayan Balasubramanian <balasvij@amazon.com>
* Enhance unit test coverage for 32x defaults Signed-off-by: Kunal Kotwani <kkotwani@amazon.com> * Add BwC test coverage (#3329) Signed-off-by: Kunal Kotwani <kkotwani@amazon.com> * Add base64 binary encoding as default format for knn_vector docvalue_fields (#3324) Signed-off-by: Navneet Verma <navneev@amazon.com> * Add issues write permission to untriaged label workflow (#3332) Signed-off-by: shreyah963 <shreyab963@gmail.com> * Fix score to radius conversion for IP with faiss (#3336) Signed-off-by: Kunal Kotwani <kkotwani@amazon.com> Co-authored-by: Tejas Shah <shatejas@amazon.com> * Add ci.opensearch.org maven2 mirror to avoid throttling (#3345) Signed-off-by: Sayali Gaikawad <gaiksaya@amazon.com> * [AUTO] Add release notes for 3.7.0 (#3342) Signed-off-by: opensearch-ci-bot <opensearch-infra@amazon.com> * Fix derived source for mixed-case vector fields (#3313) * Fix derived source for mixed-case vector fields Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> * Add BWC coverage for derived source field casing Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> * Add changelog entry for mixed-case derived source fix Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> * Handle case-insensitive conflicts by preferring vector field Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> * Avoid stream wrappers for derived field lookup Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> * Handle ambiguous case-insensitive matches without vector hints Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> * Update src/main/java/org/opensearch/knn/index/codec/KNN10010Codec/KNN10010DerivedSourceStoredFieldsFormat.java Co-authored-by: Tejas Shah <shatejas@amazon.com> Signed-off-by: Wonjae Lee <38933452+leewjae@users.noreply.github.com> * Apply spotless formatting for derived source field resolution Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> * Avoid guessing when case-insensitive matches lack vector hints Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> * Simplify case-insensitive derived field matching Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> * Trigger CI rerun for BWC investigation Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> * Add native engine field info coverage Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> --------- Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> Signed-off-by: Wonjae Lee <38933452+leewjae@users.noreply.github.com> Signed-off-by: Tejas Shah <shatejas@amazon.com> Co-authored-by: Tejas Shah <shatejas@amazon.com> Co-authored-by: Navneet Verma <navneev@amazon.com> * Fixes RescoreParser to pass the rescore flag (#3343) * Fixes RescoreParser to pass the rescore flag For multinode or coordinator-data node setup, rescore set to false is not passed through streams. This causes rescoring to execute even when its not disabled explicitly by user Signed-off-by: Tejas Shah <shatejas@amazon.com> * Updates Changelogs, improves code cov Signed-off-by: Tejas Shah <shatejas@amazon.com> * Makes the coordinator port dynamic Signed-off-by: Tejas Shah <shatejas@amazon.com> * Adds BWC test for mode and compression Signed-off-by: Tejas Shah <shatejas@amazon.com> * Does not create compressed indices before 2.18 Signed-off-by: Tejas Shah <shatejas@amazon.com> * Fixes bwc Signed-off-by: Tejas Shah <shatejas@amazon.com> --------- Signed-off-by: Tejas Shah <shatejas@amazon.com> * Merge rescore-radial-quantized feature branch to main (#3347) * Rescoring after radial search on quantized index. [Task 1 - 4] (#3300) * Bumped gradle to 9.4.1 and jacoco to 0.8.14 (#3308) Signed-off-by: Andrew Klepchick <aklepchi@amazon.com> * Use KNN1040ScalarQuantizedVectorsFormat for Faiss SQ flat format (#3302) The Faiss SQ format was using Lucene's Lucene104ScalarQuantizedVectorsFormat directly, which lacks the prefetch-enabled raw vector reader that KNN1040ScalarQuantizedVectorsFormat provides. This meant exact search rescoring was missing I/O prefetch during graph traversal. Changes: - Switch faissSqFlatFormat from Lucene104ScalarQuantizedVectorsFormat to KNN1040ScalarQuantizedVectorsFormat in Faiss1040ScalarQuantizedKnnVectorsFormat - Add @VisibleForTesting getFlatVectorsReader() to Faiss1040ScalarQuantizedKnnVectorsReader to replace reflection in tests - Add testGetRandomVectorScorer_returnsPrefetchableScorer in KNN1040ScalarQuantizedVectorsFormatTests verifying the scorer is PrefetchableRandomVectorScorer via a real write/read cycle - Replace reflection with getter in Faiss1040ScalarQuantizedKnnVectorsFormatTests.testFieldsReader_thenWrapsFlatReaderWithPrefetchSupport Signed-off-by: Vijayan Balasubramanian <balasvij@amazon.com> * Allow minScore, maxDistance for 32x SQ index. Signed-off-by: Dooyong Kim <kdooyong@amazon.com> Pass compression and quantization config to RNN query builder. Signed-off-by: Dooyong Kim <kdooyong@amazon.com> Added RescoreRadialSearchQuery. Signed-off-by: Dooyong Kim <kdooyong@amazon.com> Wiring `RescoreRadialSearchQuery` wrapper in `RNNQueryFactory` Signed-off-by: Dooyong Kim <kdooyong@amazon.com> --------- Signed-off-by: Andrew Klepchick <aklepchi@amazon.com> Signed-off-by: Vijayan Balasubramanian <balasvij@amazon.com> Signed-off-by: Dooyong Kim <kdooyong@amazon.com> Co-authored-by: Andrew Klepchick <aklepchi@amazon.com> Co-authored-by: Vijayan Balasubramanian <balasvij@amazon.com> * Rescore radial search quantized complete (#3337) * Added exact search logic after radial. Signed-off-by: Dooyong Kim <kdooyong@amazon.com> * Adding 2nd rescoring after radial search on quantized index. Signed-off-by: Dooyong Kim <kdooyong@amazon.com> --------- Signed-off-by: Dooyong Kim <kdooyong@amazon.com> * Update changelog Signed-off-by: Dooyong Kim <kdooyong@amazon.com> --------- Signed-off-by: Andrew Klepchick <aklepchi@amazon.com> Signed-off-by: Vijayan Balasubramanian <balasvij@amazon.com> Signed-off-by: Dooyong Kim <kdooyong@amazon.com> Co-authored-by: Andrew Klepchick <aklepchi@amazon.com> Co-authored-by: Vijayan Balasubramanian <balasvij@amazon.com> * Add support for binary and byte field support in doc_values (#3340) Signed-off-by: Navneet Verma <navneev@amazon.com> * Pin GitHub Actions to commit SHAs (#3339) Signed-off-by: Divya Madala <divyaasm@amazon.com> Co-authored-by: Tejas Shah <shatejas@amazon.com> * Turn off ACORN for MOS (#3346) Signed-off-by: Andrew Klepchick <aklepchi@amazon.com> * Add base64 encoded vector indexing support for knn_vector fields (#3350) Vectors can now be indexed as base64-encoded strings in addition to JSON arrays. Float vectors use little-endian byte encoding (symmetric with the doc_values binary output format), while byte/binary vectors use raw byte encoding. This enables efficient bulk ingestion pipelines that avoid JSON array serialization overhead. Signed-off-by: Navneet Verma <navneev@amazon.com> * Made MemoryOptimizedSearchWarmup skip MemoryOptimizedSearchOldIndicesNotSupportedException. (#3344) Signed-off-by: Dooyong Kim <kdooyong@amazon.com> Signed-off-by: Doo Yong Kim <kdooyong@amazon.com> * Integrated proper ef_search functionality into MOS and Lucene with oversample_factor (#3331) * Check to see if Lucene's search budget has exhausted when deciding to exact search (#3354) * Update opensearch-build workflow references from commit SHA to main (#3363) Signed-off-by: Divya Madala <divyaasm@amazon.com> * Pinned the commit for tj-actions/changed-files for version v47.0.0 (#3367) Signed-off-by: Navneet Verma <navneev@amazon.com> --------- Signed-off-by: Kunal Kotwani <kkotwani@amazon.com> Signed-off-by: Navneet Verma <navneev@amazon.com> Signed-off-by: shreyah963 <shreyab963@gmail.com> Signed-off-by: Sayali Gaikawad <gaiksaya@amazon.com> Signed-off-by: opensearch-ci-bot <opensearch-infra@amazon.com> Signed-off-by: Wonjae Lee <wonjae.lee@dremio.com> Signed-off-by: Wonjae Lee <38933452+leewjae@users.noreply.github.com> Signed-off-by: Tejas Shah <shatejas@amazon.com> Signed-off-by: Andrew Klepchick <aklepchi@amazon.com> Signed-off-by: Vijayan Balasubramanian <balasvij@amazon.com> Signed-off-by: Dooyong Kim <kdooyong@amazon.com> Signed-off-by: Divya Madala <divyaasm@amazon.com> Signed-off-by: Doo Yong Kim <kdooyong@amazon.com> Co-authored-by: Navneet Verma <navneev@amazon.com> Co-authored-by: Shreya Bhatta <shreyab963@gmail.com> Co-authored-by: Tejas Shah <shatejas@amazon.com> Co-authored-by: Sayali Gaikawad <gaiksaya@amazon.com> Co-authored-by: opensearch-ci <83309141+opensearch-ci-bot@users.noreply.github.com> Co-authored-by: Wonjae Lee <38933452+leewjae@users.noreply.github.com> Co-authored-by: Doo Yong Kim <kdooyong@amazon.com> Co-authored-by: Andrew Klepchick <aklepchi@amazon.com> Co-authored-by: Vijayan Balasubramanian <balasvij@amazon.com> Co-authored-by: Divya Madala <113469545+Divyaasm@users.noreply.github.com>
Description
Radial search (max_distance/min_score) was previously blocked for all quantized indices due to scoring inaccuracy from quantization error. This PR enables radial search on 1-bit SQ (32x compression) indices by introducing RescoreRadialSearchQuery — a wrapper query that runs quantized radial search as a first pass, then rescores
candidates using full-precision vectors to filter out false positives (vectors whose quantized score fell within the radius but
whose true score does not).
Results are capped at 10k per segment. Supports both Faiss and Lucene engines across all space types (L2, cosine, inner product).
Related Issues
Resolves #[Issue number to be closed when this PR is merged]
N/A
Check List
--signoff.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.