From 70d629bf9343ef20ecf836626e61e361f750d018 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Thu, 16 Jul 2026 08:00:52 -0600 Subject: [PATCH] Update OpenVINO model generation (#23733) --- docker/main/Dockerfile | 4 +-- docker/main/build_ov_model.py | 47 +++++++++++++++++++++++++++------ docker/main/requirements-ov.txt | 3 +-- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/docker/main/Dockerfile b/docker/main/Dockerfile index 3ba1772f41..bf17146e30 100644 --- a/docker/main/Dockerfile +++ b/docker/main/Dockerfile @@ -81,10 +81,10 @@ RUN --mount=type=bind,source=docker/main/install_tempio.sh,target=/deps/install_ FROM base_host AS ov-converter ARG DEBIAN_FRONTEND -# Install OpenVino Runtime and Dev library +# Install OpenVINO for model conversion COPY docker/main/requirements-ov.txt /requirements-ov.txt RUN apt-get -qq update \ - && apt-get -qq install -y wget python3 python3-dev python3-distutils gcc pkg-config libhdf5-dev \ + && apt-get -qq install -y wget python3 python3-distutils \ && wget -q https://bootstrap.pypa.io/get-pip.py -O get-pip.py \ && sed -i 's/args.append("setuptools")/args.append("setuptools==77.0.3")/' get-pip.py \ && python3 get-pip.py "pip" \ diff --git a/docker/main/build_ov_model.py b/docker/main/build_ov_model.py index 2888d87a85..9d028159c2 100644 --- a/docker/main/build_ov_model.py +++ b/docker/main/build_ov_model.py @@ -1,11 +1,42 @@ -import openvino as ov -from openvino.tools import mo +"""Convert the default SSDLite MobileNet v2 model to OpenVINO IR. -ov_model = mo.convert_model( +Replaces the legacy openvino-dev Model Optimizer conversion. The TensorFlow +frontend converts the Object Detection API frozen graph natively; the four TF +outputs are then repacked into the single [1, 1, 100, 7] DetectionOutput-style +tensor that Frigate's OpenVINO detector expects, and the input is flipped to +BGR to match the legacy reverse_input_channels behavior. +""" + +import numpy as np +import openvino as ov +from openvino import opset8 as ops +from openvino.preprocess import PrePostProcessor + +model = ov.convert_model( "/models/ssdlite_mobilenet_v2_coco_2018_05_09/frozen_inference_graph.pb", - compress_to_fp16=True, - transformations_config="/usr/local/lib/python3.11/dist-packages/openvino/tools/mo/front/tf/ssd_v2_support.json", - tensorflow_object_detection_api_pipeline_config="/models/ssdlite_mobilenet_v2_coco_2018_05_09/pipeline.config", - reverse_input_channels=True, + input=[("image_tensor:0", [1, 300, 300, 3])], ) -ov.save_model(ov_model, "/models/ssdlite_mobilenet_v2.xml") + +# rows of (image_id, class_id, score, xmin, ymin, xmax, ymax) +boxes = model.output("detection_boxes:0").get_node().input_value(0) +classes = model.output("detection_classes:0").get_node().input_value(0) +scores = model.output("detection_scores:0").get_node().input_value(0) + +# (ymin,xmin,ymax,xmax) -> (xmin,ymin,xmax,ymax) +boxes = ops.gather(boxes, [1, 0, 3, 2], 2) +classes = ops.unsqueeze(classes, 2) +scores = ops.unsqueeze(scores, 2) +image_id = ops.multiply(scores, np.float32(0.0)) + +detections = ops.concat([image_id, classes, scores, boxes], 2) +detections = ops.unsqueeze(detections, 1) +detections.output(0).get_tensor().set_names({"detection_out"}) + +model = ov.Model([detections], model.get_parameters(), "ssdlite_mobilenet_v2") + +ppp = PrePostProcessor(model) +ppp.input().tensor().set_layout(ov.Layout("NHWC")) +ppp.input().preprocess().reverse_channels() +model = ppp.build() + +ov.save_model(model, "/models/ssdlite_mobilenet_v2.xml", compress_to_fp16=True) diff --git a/docker/main/requirements-ov.txt b/docker/main/requirements-ov.txt index 6fd1ca55d9..2df7890dd5 100644 --- a/docker/main/requirements-ov.txt +++ b/docker/main/requirements-ov.txt @@ -1,3 +1,2 @@ numpy -tensorflow -openvino-dev>=2024.0.0 \ No newline at end of file +openvino >= 2026.2.0