Skip to content

Commit

Permalink
[8.6][ML Inference] Add ML inference failure handler (elastic#142488)
Browse files Browse the repository at this point in the history
* Add ML Inference failure handler
  • Loading branch information
demjened authored and WafaaNasr committed Oct 14, 2022
1 parent a6a04e4 commit a4c3115
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ export const generateMlInferencePipelineBody = ({
},
model_id: model.model_id,
target_field: `ml.inference.${destinationField}`,
on_failure: [
{
append: {
field: '_source._ingest.inference_errors',
value: [
{
pipeline: pipelineName,
message: `Processor 'inference' in pipeline '${pipelineName}' failed with message '{{ _ingest.on_failure_message }}'`,
timestamp: '{{{ _ingest.timestamp }}}',
},
],
},
},
],
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { merge } from 'lodash';

import { ElasticsearchClient } from '@kbn/core/server';

Expand Down Expand Up @@ -41,14 +42,63 @@ describe('createIndexPipelineDefinitions util function', () => {
describe('formatMlPipelineBody util function', () => {
const pipelineName = 'ml-inference-my-ml-proc';
const modelId = 'my-model-id';
let modelInputField = 'my-model-input-field';
const modelInputField = 'my-model-input-field';
const modelType = 'pytorch';
const inferenceConfigKey = 'my-model-type';
const modelTypes = ['pytorch', 'my-model-type'];
const modelVersion = 3;
const sourceField = 'my-source-field';
const destField = 'my-dest-field';

const expectedResult = {
description: '',
processors: [
{
remove: {
field: `ml.inference.${destField}`,
ignore_missing: true,
},
},
{
inference: {
field_map: {
[sourceField]: modelInputField,
},
model_id: modelId,
target_field: `ml.inference.${destField}`,
on_failure: [
{
append: {
field: '_source._ingest.inference_errors',
value: [
{
pipeline: pipelineName,
message: `Processor 'inference' in pipeline '${pipelineName}' failed with message '{{ _ingest.on_failure_message }}'`,
timestamp: '{{{ _ingest.timestamp }}}',
},
],
},
},
],
},
},
{
append: {
field: '_source._ingest.processors',
value: [
{
model_version: modelVersion,
pipeline: pipelineName,
processed_timestamp: '{{{ _ingest.timestamp }}}',
types: modelTypes,
},
],
},
},
],
version: 1,
};

const mockClient = {
ml: {
getTrainedModels: jest.fn(),
Expand All @@ -60,41 +110,6 @@ describe('formatMlPipelineBody util function', () => {
});

it('should return the pipeline body', async () => {
const expectedResult = {
description: '',
processors: [
{
remove: {
field: `ml.inference.${destField}`,
ignore_missing: true,
},
},
{
inference: {
field_map: {
[sourceField]: modelInputField,
},
model_id: modelId,
target_field: `ml.inference.${destField}`,
},
},
{
append: {
field: '_source._ingest.processors',
value: [
{
model_version: modelVersion,
pipeline: pipelineName,
processed_timestamp: '{{{ _ingest.timestamp }}}',
types: modelTypes,
},
],
},
},
],
version: 1,
};

const mockResponse = {
count: 1,
trained_model_configs: [
Expand Down Expand Up @@ -136,41 +151,19 @@ describe('formatMlPipelineBody util function', () => {
});

it('should insert a placeholder if model has no input fields', async () => {
modelInputField = 'MODEL_INPUT_FIELD';
const expectedResult = {
description: '',
const expectedResultWithNoInputField = merge({}, expectedResult, {
processors: [
{
remove: {
field: `ml.inference.${destField}`,
ignore_missing: true,
},
},
{}, // append - we'll leave it untouched
{
inference: {
field_map: {
[sourceField]: modelInputField,
[sourceField]: 'MODEL_INPUT_FIELD',
},
model_id: modelId,
target_field: `ml.inference.${destField}`,
},
},
{
append: {
field: '_source._ingest.processors',
value: [
{
model_version: modelVersion,
pipeline: pipelineName,
processed_timestamp: '{{{ _ingest.timestamp }}}',
types: modelTypes,
},
],
},
},
],
version: 1,
};
});

const mockResponse = {
count: 1,
trained_model_configs: [
Expand All @@ -193,7 +186,7 @@ describe('formatMlPipelineBody util function', () => {
destField,
mockClient as unknown as ElasticsearchClient
);
expect(actualResult).toEqual(expectedResult);
expect(actualResult).toEqual(expectedResultWithNoInputField);
expect(mockClient.ml.getTrainedModels).toHaveBeenCalledTimes(1);
});
});

0 comments on commit a4c3115

Please sign in to comment.