Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 2.17] Update Default Rescore Context based on Dimension (#2149) (#2150) #2152

Open
wants to merge 4 commits into
base: 2.17
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
## [Unreleased 2.x](https://github.com/opensearch-project/k-NN/compare/2.17...2.x)
### Features
### Enhancements
* Update Default Rescore Context based on Dimension [#2149](https://github.com/opensearch-project/k-NN/pull/2149)
### Bug Fixes
### Infrastructure
### Documentation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,34 @@ public static boolean isConfigured(CompressionLevel compressionLevel) {
return compressionLevel != null && compressionLevel != NOT_CONFIGURED;
}

public RescoreContext getDefaultRescoreContext(Mode mode) {
/**
* Returns the appropriate {@link RescoreContext} based on the given {@code mode} and {@code dimension}.
*
* <p>If the {@code mode} is present in the valid {@code modesForRescore} set, the method checks the value of
* {@code dimension}:
* <ul>
* <li>If {@code dimension} is less than or equal to 1000, it returns a {@link RescoreContext} with an
* oversample factor of 5.0f.</li>
* <li>If {@code dimension} is greater than 1000, it returns the default {@link RescoreContext} associated with
* the {@link CompressionLevel}. If no default is set, it falls back to {@link RescoreContext#getDefault()}.</li>
* </ul>
* If the {@code mode} is not valid, the method returns {@code null}.
*
* @param mode The {@link Mode} for which to retrieve the {@link RescoreContext}.
* @param dimension The dimensional value that determines the {@link RescoreContext} behavior.
* @return A {@link RescoreContext} with an oversample factor of 5.0f if {@code dimension} is less than
* or equal to 1000, the default {@link RescoreContext} if greater, or {@code null} if the mode
* is invalid.
*/
public RescoreContext getDefaultRescoreContext(Mode mode, int dimension) {
if (modesForRescore.contains(mode)) {
return defaultRescoreContext;
// Adjust RescoreContext based on dimension
if (dimension <= RescoreContext.DIMENSION_THRESHOLD) {
// For dimensions <= 1000, return a RescoreContext with 5.0f oversample factor
return RescoreContext.builder().oversampleFactor(RescoreContext.OVERSAMPLE_FACTOR_BELOW_DIMENSION_THRESHOLD).build();
} else {
return defaultRescoreContext;
}
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ public RescoreContext resolveRescoreContext(RescoreContext userProvidedContext)
if (userProvidedContext != null) {
return userProvidedContext;
}
return getKnnMappingConfig().getCompressionLevel().getDefaultRescoreContext(getKnnMappingConfig().getMode());
KNNMappingConfig knnMappingConfig = getKnnMappingConfig();
int dimension = knnMappingConfig.getDimension();
CompressionLevel compressionLevel = knnMappingConfig.getCompressionLevel();
Mode mode = knnMappingConfig.getMode();
return compressionLevel.getDefaultRescoreContext(mode, dimension);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public final class RescoreContext {
public static final float MIN_OVERSAMPLE_FACTOR = 1.0f;

public static final int MAX_FIRST_PASS_RESULTS = 10000;
public static final int DIMENSION_THRESHOLD = 1000;
public static final float OVERSAMPLE_FACTOR_BELOW_DIMENSION_THRESHOLD = 5.0f;

// Todo:- We will improve this in upcoming releases
public static final int MIN_FIRST_PASS_RESULTS = 100;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,64 @@ public void testIsConfigured() {
public void testGetDefaultRescoreContext() {
// Test rescore context for ON_DISK mode
Mode mode = Mode.ON_DISK;
int belowThresholdDimension = 500; // A dimension below the threshold
int aboveThresholdDimension = 1500; // A dimension above the threshold

// x32 should have RescoreContext with an oversample factor of 3.0f
RescoreContext rescoreContext = CompressionLevel.x32.getDefaultRescoreContext(mode);
// x32 with dimension <= 1000 should have an oversample factor of 5.0f
RescoreContext rescoreContext = CompressionLevel.x32.getDefaultRescoreContext(mode, belowThresholdDimension);
assertNotNull(rescoreContext);
assertEquals(5.0f, rescoreContext.getOversampleFactor(), 0.0f);

// x32 with dimension > 1000 should have an oversample factor of 3.0f
rescoreContext = CompressionLevel.x32.getDefaultRescoreContext(mode, aboveThresholdDimension);
assertNotNull(rescoreContext);
assertEquals(3.0f, rescoreContext.getOversampleFactor(), 0.0f);

// x16 should have RescoreContext with an oversample factor of 3.0f
rescoreContext = CompressionLevel.x16.getDefaultRescoreContext(mode);
// x16 with dimension <= 1000 should have an oversample factor of 5.0f
rescoreContext = CompressionLevel.x16.getDefaultRescoreContext(mode, belowThresholdDimension);
assertNotNull(rescoreContext);
assertEquals(5.0f, rescoreContext.getOversampleFactor(), 0.0f);

// x16 with dimension > 1000 should have an oversample factor of 3.0f
rescoreContext = CompressionLevel.x16.getDefaultRescoreContext(mode, aboveThresholdDimension);
assertNotNull(rescoreContext);
assertEquals(3.0f, rescoreContext.getOversampleFactor(), 0.0f);

// x8 should have RescoreContext with an oversample factor of 2.0f
rescoreContext = CompressionLevel.x8.getDefaultRescoreContext(mode);
// x8 with dimension <= 1000 should have an oversample factor of 5.0f
rescoreContext = CompressionLevel.x8.getDefaultRescoreContext(mode, belowThresholdDimension);
assertNotNull(rescoreContext);
assertEquals(5.0f, rescoreContext.getOversampleFactor(), 0.0f);

// x8 with dimension > 1000 should have an oversample factor of 2.0f
rescoreContext = CompressionLevel.x8.getDefaultRescoreContext(mode, aboveThresholdDimension);
assertNotNull(rescoreContext);
assertEquals(2.0f, rescoreContext.getOversampleFactor(), 0.0f);

// Other compression levels should not have a RescoreContext for ON_DISK mode
assertNull(CompressionLevel.x4.getDefaultRescoreContext(mode));
assertNull(CompressionLevel.x2.getDefaultRescoreContext(mode));
assertNull(CompressionLevel.x1.getDefaultRescoreContext(mode));
assertNull(CompressionLevel.NOT_CONFIGURED.getDefaultRescoreContext(mode));
// x4 with dimension <= 1000 should have an oversample factor of 5.0f (though it doesn't have its own RescoreContext)
rescoreContext = CompressionLevel.x4.getDefaultRescoreContext(mode, belowThresholdDimension);
assertNull(rescoreContext);
// x4 with dimension > 1000 should return null (no RescoreContext is configured for x4)
rescoreContext = CompressionLevel.x4.getDefaultRescoreContext(mode, aboveThresholdDimension);
assertNull(rescoreContext);

// Other compression levels should behave similarly with respect to dimension

rescoreContext = CompressionLevel.x2.getDefaultRescoreContext(mode, belowThresholdDimension);
assertNull(rescoreContext);

// x2 with dimension > 1000 should return null
rescoreContext = CompressionLevel.x2.getDefaultRescoreContext(mode, aboveThresholdDimension);
assertNull(rescoreContext);

rescoreContext = CompressionLevel.x1.getDefaultRescoreContext(mode, belowThresholdDimension);
assertNull(rescoreContext);

// x1 with dimension > 1000 should return null
rescoreContext = CompressionLevel.x1.getDefaultRescoreContext(mode, aboveThresholdDimension);
assertNull(rescoreContext);

// NOT_CONFIGURED with dimension <= 1000 should return a RescoreContext with an oversample factor of 5.0f
rescoreContext = CompressionLevel.NOT_CONFIGURED.getDefaultRescoreContext(mode, belowThresholdDimension);
assertNull(rescoreContext);
}
}
Loading