Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
5 changes: 5 additions & 0 deletions docs/changelog/126273.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 126273
summary: Fix LTR rescorer with model alias
area: Ranking
type: bug
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,7 @@ public ModelLoadingService(
this.licenseState = licenseState;
}

// for testing
String getModelId(String modelIdOrAlias) {
public String getModelId(String modelIdOrAlias) {
return modelAliasToId.getOrDefault(modelIdOrAlias, modelIdOrAlias);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public void loadLocalModel(String modelId, ActionListener<LocalModel> listener)
*/
public void loadLearningToRankConfig(String modelId, Map<String, Object> params, ActionListener<LearningToRankConfig> listener) {
trainedModelProvider.getTrainedModel(
modelId,
modelLoadingService.getModelId(modelId),
GetTrainedModelsAction.Includes.all(),
null,
ActionListener.wrap(trainedModelConfig -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.hasSize;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class LearningToRankServiceTests extends ESTestCase {
public static final String GOOD_MODEL = "inference-entity-id";
Expand Down Expand Up @@ -185,7 +187,10 @@ protected NamedXContentRegistry xContentRegistry() {
}

private ModelLoadingService mockModelLoadingService() {
return mock(ModelLoadingService.class);
ModelLoadingService modelLoadingService = mock(ModelLoadingService.class);
when(modelLoadingService.getModelId(anyString())).thenAnswer(i -> i.getArgument(0));

return modelLoadingService;
}

@SuppressWarnings("unchecked")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,15 @@ setup:
{ "index": {} }
{ "product": "Laptop", "cost": 500}

- do:
headers:
Authorization: "Basic eF9wYWNrX3Jlc3RfdXNlcjp4LXBhY2stdGVzdC1wYXNzd29yZA==" # run as x_pack_rest_user, i.e. the test setup superuser
ml.put_trained_model_alias:
model_id: "ltr-model"
model_alias: "ltr-model-alias"

---
"Test rescore with stored model":
- skip:
awaits_fix: "https://github.com/elastic/elasticsearch/issues/80703"

- do:
search:
index: store
Expand Down Expand Up @@ -182,12 +186,11 @@ setup:
- match: { hits.hits.0._score: 6.0 }
- match: { hits.hits.1._score: 6.0 }
- match: { hits.hits.2._score: 3.0 }

---
"Test rescore with stored model and smaller window_size":
- skip:
awaits_fix: "https://github.com/elastic/elasticsearch/issues/80703"

- do:
catch: bad_request
search:
index: store
size: 5
Expand All @@ -198,16 +201,12 @@ setup:
"learning_to_rank": { "model_id": "ltr-model" }
}
}
- match: { hits.hits.0._score: 17.0 }
- match: { hits.hits.1._score: 17.0 }
- match: { hits.hits.2._score: 1.0 }
- match: { hits.hits.3._score: 1.0 }
- match: { hits.hits.4._score: 1.0 }
- match: { status: 400 }
- match: { error.root_cause.0.type: "action_request_validation_exception" }
- match: { error.root_cause.0.reason: "Validation Failed: 1: rescorer [window_size] is too small and should be at least the value of [from + size: 4] but was [2];" }

---
"Test rescore with stored model and chained rescorers":
- skip:
awaits_fix: "https://github.com/elastic/elasticsearch/issues/80703"

- do:
search:
index: store
Expand All @@ -216,11 +215,11 @@ setup:
{
"rescore": [
{
"window_size": 4,
"window_size": 10,
"query": { "rescore_query":{ "script_score": {"query": {"match_all": {}}, "script": {"source": "return 4"}}}}
},
{
"window_size": 3,
"window_size": 5,
"learning_to_rank": { "model_id": "ltr-model" }
},
{
Expand All @@ -232,8 +231,9 @@ setup:
- match: { hits.hits.0._score: 37.0 }
- match: { hits.hits.1._score: 37.0 }
- match: { hits.hits.2._score: 14.0 }
- match: { hits.hits.3._score: 5.0 }
- match: { hits.hits.4._score: 1.0 }
- match: { hits.hits.3._score: 6.0 }
- match: { hits.hits.4._score: 6.0 }

---
"Test rescore with missing model":
- do:
Expand All @@ -247,8 +247,12 @@ setup:
"learning_to_rank": { "model_id": "ltr-missing" }
}
}
- match: { status: 404 }
- match: { error.root_cause.0.type: "resource_not_found_exception" }
- match: { error.root_cause.0.reason: "Could not find trained model [ltr-missing]" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking tip - you could optimize this with something like catch: /Could not find trained model \[ltr-missing\] if you wanted to.


---
"Test rescore with no hits model":
"Test rescore with no hits":
- do:
search:
index: store
Expand All @@ -261,6 +265,26 @@ setup:
}
}
- length: { hits.hits: 0 }

---
"Test rescore using model alias":
- skip:
features: headers
- do:
search:
index: store
size: 3
body: >
{
"rescore": {
"window_size": 10,
"learning_to_rank": { "model_id": "ltr-model-alias" }
}
}
- match: { hits.hits.0._score: 17.0 }
- match: { hits.hits.1._score: 17.0 }
- match: { hits.hits.2._score: 14.0 }

---
"Test model input validation":
- skip:
Expand Down
Loading