From 2afc646a12ecc7264728019e7a839ed3ec8ede61 Mon Sep 17 00:00:00 2001 From: "Tybulewicz, Tomasz" Date: Mon, 19 Jan 2026 12:40:41 +0100 Subject: [PATCH 1/4] feat: pass missing model_info --- README.md | 29 +++++++++++++++++++++++++++++ src/model_api/models/model.py | 2 +- tests/accuracy/public_scope.json | 18 ++++++++++++++++++ tests/accuracy/test_accuracy.py | 10 +++++++--- 4 files changed, 55 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1ecad6df..3d208c2c 100644 --- a/README.md +++ b/README.md @@ -59,4 +59,33 @@ model = DetectionModel.create_model("~/.cache/omz/public/ssdlite_mobilenet_v2/FP model.save("serialized.xml") ``` +## Usage with generic OpenVINO models + +ModelAPI uses custom field in `rt_info/model_info` section of OpenVINO IR to store metadata required for preprocessing and postprocessing. If you have a generic OpenVINO model without such metadata, you can provide that metadata in `configuration` argument of `create_model()` method: + + +```python +from model_api.models import Model + +# Create a model wrapper from a compatible model generated by OpenVINO Training Extensions +model = Model.create_model( + "model.xml", + configuration={ + "model_type": "segmentation", + "blur_strength": 1, + "labels": ["object"], + "soft_threshold": 0.5, + } +) + +# Run synchronous inference locally +result = model(image) # image is numpy.ndarray + +# Print results in model-specific format +print(f"Inference result: {result}") + +# Save the model with metadata already embedded (passing configuration is not required anymore) +model.save("serialized_with_metadata.xml") +``` + For more details please refer to the [examples](https://github.com/openvinotoolkit/model_api/tree/master/examples) of this project. diff --git a/src/model_api/models/model.py b/src/model_api/models/model.py index 588589c2..a6a8eda0 100644 --- a/src/model_api/models/model.py +++ b/src/model_api/models/model.py @@ -234,7 +234,7 @@ def create_model( ["model_info", "model_type"], ).astype(str) except RuntimeError: - model_type = cls.detect_model_type(inference_adapter) + model_type = configuration.get("model_type", cls.detect_model_type(inference_adapter)) Model = cls.get_model_class(model_type) return Model(inference_adapter, configuration, preload) diff --git a/tests/accuracy/public_scope.json b/tests/accuracy/public_scope.json index 4397ee47..5be791c2 100644 --- a/tests/accuracy/public_scope.json +++ b/tests/accuracy/public_scope.json @@ -35,6 +35,24 @@ } ] }, + { + "name": "otx_models/Lite-hrnet-s_mod2-without-model-info.xml", + "type": "SegmentationModel", + "configuration": { + "blur_strength": 1, + "labels": ["object"], + "model_type": "Segmentation", + "soft_threshold": 0.5 + }, + "test_data": [ + { + "image": "coco128/images/train2017/000000000074.jpg", + "reference": [ + "0: 0.563, 1: 0.437, [426,640,2], [0], [0]; object: 0.520, 26, 0, object: 0.530, 42, 0, object: 0.501, 4, 0, object: 0.507, 27, 0, object: 0.503, 8, 0, object: 0.502, 6, 0, object: 0.505, 18, 0, object: 0.504, 13, 0, object: 0.524, 87, 0, object: 0.521, 89, 0, object: 0.757, 2706, 2, " + ] + } + ] + }, { "name": "otx_models/Lite-hrnet-s_mod2.onnx", "type": "SegmentationModel", diff --git a/tests/accuracy/test_accuracy.py b/tests/accuracy/test_accuracy.py index ea161210..9874376f 100644 --- a/tests/accuracy/test_accuracy.py +++ b/tests/accuracy/test_accuracy.py @@ -78,7 +78,7 @@ def read_config(fname): return json.load(f) -def create_models(model_type, model_path, download_dir, force_onnx_adapter=False, device="CPU"): +def create_models(model_type, model_path, download_dir, force_onnx_adapter=False, device="CPU", configuration=None): if model_path.endswith(".onnx") and force_onnx_adapter: wrapper_type = model_type.get_model_class( load_parameters_from_onnx(onnx.load(model_path))["model_info"]["model_type"], @@ -92,8 +92,11 @@ def create_models(model_type, model_path, download_dir, force_onnx_adapter=False model.load() return [model] + if not configuration: + configuration = {} + models = [ - model_type.create_model(model_path, device=device, download_dir=download_dir), + model_type.create_model(model_path, device=device, download_dir=download_dir, configuration=configuration), ] if model_path.endswith(".xml"): model = create_core().read_model(model_path) @@ -101,7 +104,7 @@ def create_models(model_type, model_path, download_dir, force_onnx_adapter=False wrapper_type = model_type.get_model_class( model.get_rt_info(["model_info", "model_type"]).astype(str), ) - model = wrapper_type(OpenvinoAdapter(create_core(), model_path, device=device)) + model = wrapper_type(OpenvinoAdapter(create_core(), model_path, device=device), configuration=configuration) model.load() models.append(model) return models @@ -287,6 +290,7 @@ def test_image_models(data, device, dump, result, model_data, results_dir): # n data, model_data.get("force_ort", False), device=device, + configuration=model_data.get("configuration", None), ): if "tiler" in model_data: if "extra_model" in model_data: From 7989ea84b6ab34e4f22dd2a4b8431179a8293774 Mon Sep 17 00:00:00 2001 From: Tomasz Tybulewicz Date: Mon, 19 Jan 2026 12:42:42 +0100 Subject: [PATCH 2/4] Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d208c2c..bf6e7344 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ from model_api.models import Model model = Model.create_model( "model.xml", configuration={ - "model_type": "segmentation", + "model_type": "Segmentation", "blur_strength": 1, "labels": ["object"], "soft_threshold": 0.5, From 2c7bd118e4bf0b99f418bf683a3ef3c9733ec514 Mon Sep 17 00:00:00 2001 From: "Tybulewicz, Tomasz" Date: Mon, 19 Jan 2026 13:09:07 +0100 Subject: [PATCH 3/4] Fix code-style --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index bf6e7344..ca52ab3f 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,6 @@ model.save("serialized.xml") ModelAPI uses custom field in `rt_info/model_info` section of OpenVINO IR to store metadata required for preprocessing and postprocessing. If you have a generic OpenVINO model without such metadata, you can provide that metadata in `configuration` argument of `create_model()` method: - ```python from model_api.models import Model From b0b0350b90a19b3be8878d5fc90269dc09d4a4c1 Mon Sep 17 00:00:00 2001 From: Tomasz Tybulewicz Date: Tue, 20 Jan 2026 08:15:21 +0100 Subject: [PATCH 4/4] Update tests/accuracy/test_accuracy.py Co-authored-by: Mariusz Gumowski --- tests/accuracy/test_accuracy.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/accuracy/test_accuracy.py b/tests/accuracy/test_accuracy.py index 9874376f..62063bee 100644 --- a/tests/accuracy/test_accuracy.py +++ b/tests/accuracy/test_accuracy.py @@ -92,8 +92,7 @@ def create_models(model_type, model_path, download_dir, force_onnx_adapter=False model.load() return [model] - if not configuration: - configuration = {} + configuration = configuration or {} models = [ model_type.create_model(model_path, device=device, download_dir=download_dir, configuration=configuration),