Skip to content

Commit 156d5da

Browse files
Revert endpoint creation validation for ELSER and E5 (elastic#126792) (elastic#126801)
* Revert endpoint creation validation for ELSER and E5 * Update docs/changelog/126792.yaml * Revert start model deployment being in TransportPutInferenceModelAction --------- Co-authored-by: Elastic Machine <[email protected]>
1 parent f6f6a4a commit 156d5da

File tree

5 files changed

+293
-154
lines changed

5 files changed

+293
-154
lines changed

docs/changelog/126792.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 126792
2+
summary: Revert endpoint creation validation for ELSER and E5
3+
area: Machine Learning
4+
type: bug
5+
issues: []

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/action/TransportPutInferenceModelAction.java

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -195,23 +195,19 @@ private void parseAndStoreModel(
195195
ActionListener<Model> storeModelListener = listener.delegateFailureAndWrap(
196196
(delegate, verifiedModel) -> modelRegistry.storeModel(
197197
verifiedModel,
198-
ActionListener.wrap(
199-
r -> listener.onResponse(new PutInferenceModelAction.Response(verifiedModel.getConfigurations())),
200-
e -> {
201-
if (e.getCause() instanceof StrictDynamicMappingException
202-
&& e.getCause().getMessage().contains("chunking_settings")) {
203-
delegate.onFailure(
204-
new ElasticsearchStatusException(
205-
"One or more nodes in your cluster does not support chunking_settings. "
206-
+ "Please update all nodes in your cluster to the latest version to use chunking_settings.",
207-
RestStatus.BAD_REQUEST
208-
)
209-
);
210-
} else {
211-
delegate.onFailure(e);
212-
}
198+
ActionListener.wrap(r -> startInferenceEndpoint(service, timeout, verifiedModel, delegate), e -> {
199+
if (e.getCause() instanceof StrictDynamicMappingException && e.getCause().getMessage().contains("chunking_settings")) {
200+
delegate.onFailure(
201+
new ElasticsearchStatusException(
202+
"One or more nodes in your cluster does not support chunking_settings. "
203+
+ "Please update all nodes in your cluster to the latest version to use chunking_settings.",
204+
RestStatus.BAD_REQUEST
205+
)
206+
);
207+
} else {
208+
delegate.onFailure(e);
213209
}
214-
),
210+
}),
215211
timeout
216212
)
217213
);
@@ -228,6 +224,19 @@ private void parseAndStoreModel(
228224
service.parseRequestConfig(inferenceEntityId, taskType, config, parsedModelListener);
229225
}
230226

227+
private void startInferenceEndpoint(
228+
InferenceService service,
229+
TimeValue timeout,
230+
Model model,
231+
ActionListener<PutInferenceModelAction.Response> listener
232+
) {
233+
if (skipValidationAndStart) {
234+
listener.onResponse(new PutInferenceModelAction.Response(model.getConfigurations()));
235+
} else {
236+
service.start(model, timeout, listener.map(started -> new PutInferenceModelAction.Response(model.getConfigurations())));
237+
}
238+
}
239+
231240
private Map<String, Object> requestToMap(PutInferenceModelAction.Request request) throws IOException {
232241
try (
233242
XContentParser parser = XContentHelper.createParser(

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/validation/ElasticsearchInternalServiceModelValidator.java

Lines changed: 70 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,51 +9,91 @@
99

1010
import org.elasticsearch.ElasticsearchStatusException;
1111
import org.elasticsearch.action.ActionListener;
12+
import org.elasticsearch.common.Strings;
1213
import org.elasticsearch.core.TimeValue;
1314
import org.elasticsearch.inference.InferenceService;
15+
import org.elasticsearch.inference.InferenceServiceResults;
1416
import org.elasticsearch.inference.Model;
17+
import org.elasticsearch.inference.TaskType;
1518
import org.elasticsearch.rest.RestStatus;
19+
import org.elasticsearch.xpack.core.inference.results.TextEmbeddingFloatResults;
20+
import org.elasticsearch.xpack.core.inference.results.TextEmbeddingResults;
21+
import org.elasticsearch.xpack.inference.services.elasticsearch.CustomElandEmbeddingModel;
1622

1723
public class ElasticsearchInternalServiceModelValidator implements ModelValidator {
1824

19-
ModelValidator modelValidator;
25+
private final ServiceIntegrationValidator serviceIntegrationValidator;
2026

21-
public ElasticsearchInternalServiceModelValidator(ModelValidator modelValidator) {
22-
this.modelValidator = modelValidator;
27+
public ElasticsearchInternalServiceModelValidator(ServiceIntegrationValidator serviceIntegrationValidator) {
28+
this.serviceIntegrationValidator = serviceIntegrationValidator;
2329
}
2430

2531
@Override
2632
public void validate(InferenceService service, Model model, TimeValue timeout, ActionListener<Model> listener) {
27-
service.start(model, timeout, ActionListener.wrap((modelDeploymentStarted) -> {
28-
if (modelDeploymentStarted) {
29-
try {
30-
modelValidator.validate(service, model, timeout, listener.delegateResponse((l, exception) -> {
31-
stopModelDeployment(service, model, l, exception);
32-
}));
33-
} catch (Exception e) {
34-
stopModelDeployment(service, model, listener, e);
35-
}
36-
} else {
37-
listener.onFailure(
38-
new ElasticsearchStatusException("Could not deploy model for inference endpoint", RestStatus.INTERNAL_SERVER_ERROR)
33+
if (model instanceof CustomElandEmbeddingModel elandModel && elandModel.getTaskType() == TaskType.TEXT_EMBEDDING) {
34+
var temporaryModelWithModelId = new CustomElandEmbeddingModel(
35+
elandModel.getServiceSettings().modelId(),
36+
elandModel.getTaskType(),
37+
elandModel.getConfigurations().getService(),
38+
elandModel.getServiceSettings(),
39+
elandModel.getConfigurations().getChunkingSettings()
40+
);
41+
42+
serviceIntegrationValidator.validate(
43+
service,
44+
temporaryModelWithModelId,
45+
timeout,
46+
listener.delegateFailureAndWrap((delegate, r) -> {
47+
delegate.onResponse(postValidate(service, model, r));
48+
})
49+
);
50+
} else {
51+
listener.onResponse(model);
52+
}
53+
}
54+
55+
private Model postValidate(InferenceService service, Model model, InferenceServiceResults results) {
56+
if (results instanceof TextEmbeddingResults<?> embeddingResults) {
57+
var serviceSettings = model.getServiceSettings();
58+
var dimensions = serviceSettings.dimensions();
59+
int embeddingSize = getEmbeddingSize(embeddingResults);
60+
61+
if (Boolean.TRUE.equals(serviceSettings.dimensionsSetByUser())
62+
&& dimensions != null
63+
&& (dimensions.equals(embeddingSize) == false)) {
64+
throw new ElasticsearchStatusException(
65+
Strings.format(
66+
"The retrieved embeddings size [%s] does not match the size specified in the settings [%s]. "
67+
+ "Please recreate the [%s] configuration with the correct dimensions",
68+
embeddingResults.getFirstEmbeddingSize(),
69+
serviceSettings.dimensions(),
70+
model.getInferenceEntityId()
71+
),
72+
RestStatus.BAD_REQUEST
3973
);
4074
}
41-
}, listener::onFailure));
75+
76+
return service.updateModelWithEmbeddingDetails(model, embeddingSize);
77+
} else {
78+
throw new ElasticsearchStatusException(
79+
"Validation call did not return expected results type."
80+
+ "Expected a result of type ["
81+
+ TextEmbeddingFloatResults.NAME
82+
+ "] got ["
83+
+ (results == null ? "null" : results.getWriteableName())
84+
+ "]",
85+
RestStatus.BAD_REQUEST
86+
);
87+
}
4288
}
4389

44-
private void stopModelDeployment(InferenceService service, Model model, ActionListener<Model> listener, Exception e) {
45-
service.stop(
46-
model,
47-
ActionListener.wrap(
48-
(v) -> listener.onFailure(e),
49-
(ex) -> listener.onFailure(
50-
new ElasticsearchStatusException(
51-
"Model validation failed and model deployment could not be stopped",
52-
RestStatus.INTERNAL_SERVER_ERROR,
53-
ex
54-
)
55-
)
56-
)
57-
);
90+
private int getEmbeddingSize(TextEmbeddingResults<?> embeddingResults) {
91+
int embeddingSize;
92+
try {
93+
embeddingSize = embeddingResults.getFirstEmbeddingSize();
94+
} catch (Exception e) {
95+
throw new ElasticsearchStatusException("Could not determine embedding size", RestStatus.BAD_REQUEST, e);
96+
}
97+
return embeddingSize;
5898
}
5999
}

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/validation/ModelValidatorBuilder.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@
1212

1313
public class ModelValidatorBuilder {
1414
public static ModelValidator buildModelValidator(TaskType taskType, boolean isElasticsearchInternalService) {
15-
var modelValidator = buildModelValidatorForTaskType(taskType);
1615
if (isElasticsearchInternalService) {
17-
return new ElasticsearchInternalServiceModelValidator(modelValidator);
16+
return new ElasticsearchInternalServiceModelValidator(new SimpleServiceIntegrationValidator());
1817
} else {
19-
return modelValidator;
18+
return buildModelValidatorForTaskType(taskType);
2019
}
2120
}
2221

0 commit comments

Comments
 (0)