facebookresearch / facebookresearch/detectron2
detectron2 to OpenVINO IR
- Dominant language
- Python
- Stars
- 34.7k
- Forks
- 7.9k
- PR merge metrics
- No merged PRs in 30d
Description
## Instructions To Reproduce the 🐛 Bug:
1. Full runnable code or full changes you made:
```
import warnings, cv2
from pathlib import Path, PurePosixPath
from IPython.display import Markdown, display
from openvino.runtime import Core
# Some basic setup:
# Setup detectron2 logger
from detectron2.utils.logger import setup_logger
setup_logger()
# import some common libraries
import numpy as np
import os, json, cv2, random, pymediainfo, sys, time, torch, detectron2
# import some common detectron2 utilities
from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2.utils.visualizer import Visualizer, ColorMode
from detectron2.data import MetadataCatalog, DatasetCatalog
from detectron2.modeling import build_model
import matplotlib.pyplot as plt
from tqdm import tqdm
from detectron2.export import dump_torchscript_IR, torchscript
from detectron2.modeling import build_model
from detectron2.checkpoint import DetectionCheckpointer
import onnx
import onnxruntime as rt
import detectron2.data.transforms as T
import pickle
def mask_image(im, outputs):
v = Visualizer(im[:, :, ::-1], MetadataCatalog.get(cfg.DATASETS.TRAIN[0]), scale=1)
out = v.draw_instance_predictions(outputs["instances"].to("cpu"))
return out.get_image()[:, :, ::-1]
IMAGE_HEIGHT = 800
IMAGE_WIDTH = 800
DIRECTORY_NAME = "models"
image_filename = "data/test.jpg"
image = cv2.imread(image_filename)
image = cv2.resize(image, (IMAGE_WIDTH, IMAGE_HEIGHT))
d = {"file_name": image_filename, "height": IMAGE_HEIGHT, "width": IMAGE_WIDTH}
cfg = get_cfg()
cfg.MODEL.DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'
# add project-specific config (e.g., TensorMask) here if you're not running a model in detectron2's core library
path = PurePosixPath("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
cfg.merge_from_file(model_zoo.get_config_file(path))
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5 # set threshold for this model
# Find a model from detectron2's model zoo. You can use the https://dl.fbaipublicfiles... url as well
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(str(path))
# predictor = DefaultPredictor(cfg)
# Build model and prepare input
model = build_model(cfg)
model.eval()
# checkpointer = DetectionCheckpointer(model)
# checkpointer.load(cfg.MODEL.WEIGHTS)
# aug = T.ResizeShortestEdge([cfg.INPUT.MIN_SIZE_TEST, cfg.INPUT.MIN_SIZE_TEST], cfg.INPUT.MAX_SIZE_TEST)
# height, width = image.shape[:2]
# image = aug.get_transform(image).apply_image(image)
# image = torch.as_tensor(image.astype("float32").transpose(2, 0, 1))
# inputs = {"image": image, "height": height, "width": width}
BASE_MODEL_NAME = DIRECTORY_NAME + "/" + "mask_rcnn_R_50_FPN_3x"
weights_path = Path(BASE_MODEL_NAME + ".pt")
# Paths where ONNX and OpenVINO IR models will be stored.
onnx_path = weights_path.with_suffix('.onnx')
if not onnx_path.parent.exists():
onnx_path.parent.mkdir()
ir_path = onnx_path.with_suffix(".xml")
print("Downloading the {} model (if it has not been downloaded already)...".format(BASE_MODEL_NAME.split("/")[1]))
# load pkl file
with open("models/model_final_f10217.pkl", 'rb') as f:
weights = pickle.load(f)
# create model object
# model = torch.load("models/mask_rcnn_R_50_FPN_3x.pt", map_location='cpu')
# read state dict, use map_location argument to avoid a situation where weights are saved in cuda (which may not be unavailable on the system)
state_dict = torch.load(weights_path, map_location='cpu')
# load state dict to model
model.load_state_dict(state_dict)
# switch model from training to inference mode
model.eval()
print("Loaded PyTorch {} model".format(BASE_MODEL_NAME.split("/")[1]))
with warnings.catch_warnings():
warnings.filterwarnings("ignore")
if not onnx_path.exists():
dummy_input = torch.randn(1, 3, IMAGE_HEIGHT, IMAGE_WIDTH)
torch.onnx.export(
model,
dummy_input,
onnx_path,
)
print(f"ONNX model exported to {onnx_path}.")
else:
print(f"ONNX model {onnx_path} already exists.")
# Construct the command for Model Optimizer.
mo_command = f"""mo
--input_model "{onnx_path}"
--compress_to_fp16
--output_dir "{ir_path.parent}"
"""
mo_command = " ".join(mo_command.split())
print("Model Optimizer command to convert the ONNX model to OpenVINO:")
display(Markdown(f"`{mo_command}`"))
if not ir_path.exists():
print("Exporting ONNX model to IR... This may take a few minutes.")
mo_result = %sx $mo_command
print("\n".join(mo_result))
else:
print(f"IR model {ir_path} already exists.")
# Load the network to OpenVINO Runtime.
ie = Core()
model_onnx = ie.read_model(model=onnx_path)
compiled_model_onnx = ie.compile_model(model=model_onnx, device_name="CPU")
output_layer_onnx = compiled_model_onnx.output(0)
# Run inference on the input image.
res_onnx = compiled_model_onnx([image])[output_layer_onnx]
# Convert the network result to a segmentation map and display the result.
result_mask_onnx = predictor(image)
cv2.imshow(mask_image(image, result_mask_onnx))
# Load the network in OpenVINO Runtime.
ie = Core()
model_ir = ie.read_model(model=ir_path)
compiled_model_ir = ie.compile_model(model=model_ir, device_name="CPU")
# Get input and output layers.
output_layer_ir = compiled_model_ir.output(0)
# Run inference on the input image.
res_ir = compiled_model_ir([image])[output_layer_ir]
result_mask_ir = predictor(image)
cv2.imshow(mask_image(image, result_mask_ir))
model.eval()
with torch.no_grad():
result_torch = model(image)
result_mask_torch = predictor(image)
cv2.imshow(mask_image(image, result_mask_torch))
num_images = 100
with torch.no_grad():
start = time.perf_counter()
for _ in range(num_images):
model(image)
end = time.perf_counter()
time_torch = end - start
print(
f"PyTorch model on CPU: {time_torch/num_images:.3f} seconds per image, "
f"FPS: {num_images/time_torch:.2f}"
)
start = time.perf_counter()
for _ in range(num_images):
compiled_model_onnx([image])
end = time.perf_counter()
time_onnx = end - start
print(
f"ONNX model in OpenVINO Runtime/CPU: {time_onnx/num_images:.3f} "
f"seconds per image, FPS: {num_images/time_onnx:.2f}"
)
start = time.perf_counter()
for _ in range(num_images):
compiled_model_ir([image])
end = time.perf_counter()
time_ir = end - start
print(
f"OpenVINO IR model in OpenVINO Runtime/CPU: {time_ir/num_images:.3f} "
f"seconds per image, FPS: {num_images/time_ir:.2f}"
)
if "GPU" in ie.available_devices:
compiled_model_onnx_gpu = ie.compile_model(model=model_onnx, device_name="GPU")
start = time.perf_counter()
for _ in range(num_images):
compiled_model_onnx_gpu([image])
end = time.perf_counter()
time_onnx_gpu = end - start
print(
f"ONNX model in OpenVINO/GPU: {time_onnx_gpu/num_images:.3f} "
f"seconds per image, FPS: {num_images/time_onnx_gpu:.2f}"
)
compiled_model_ir_gpu = ie.compile_model(model=model_ir, device_name="GPU")
start = time.perf_counter()
for _ in range(num_images):
compiled_model_ir_gpu([image])
end = time.perf_counter()
time_ir_gpu = end - start
print(
f"IR model in OpenVINO/GPU: {time_ir_gpu/num_images:.3f} "
f"seconds per image, FPS: {num_images/time_ir_gpu:.2f}"
)
```
```
Output exceeds the [size limit](command:workbench.action.openSettings?%5B%22notebook.output.textLineLimit%22%5D). Open the full output data [in a text editor](command:workbench.action.openLargeOutput?5227386a-8f4b-486c-9da5-4ba88143cda2)
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
Cell In[3], line 96
94 if not onnx_path.exists():
95 dummy_input = torch.randn(1, 3, IMAGE_HEIGHT, IMAGE_WIDTH)
---> 96 torch.onnx.export(
97 model,
98 dummy_input,
99 onnx_path,
100 )
101 print(f"ONNX model exported to {onnx_path}.")
102 else:
File [~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\torch\onnx\utils.py:504](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/Lazhar%20Bouacha/OneDrive%20-%20CHAMP%27S/PhD/~/AppData/Local/Packages/PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0/LocalCache/local-packages/Python310/site-packages/torch/onnx/utils.py:504), in export(model, args, f, export_params, verbose, training, input_names, output_names, operator_export_type, opset_version, do_constant_folding, dynamic_axes, keep_initializers_as_inputs, custom_opsets, export_modules_as_functions)
186 @_beartype.beartype
187 def export(
188 model: Union[torch.nn.Module, torch.jit.ScriptModule, torch.jit.ScriptFunction],
(...)
204 export_modules_as_functions: Union[bool, Collection[Type[torch.nn.Module]]] = False,
205 ) -> None:
206 r"""Exports a model into ONNX format.
207
208 If ``model`` is not a :class:`torch.jit.ScriptModule` nor a
(...)
501 All errors are subclasses of :class:`errors.OnnxExporterError`.
502 """
--> 504 _export(
505 model,
506 args,
507 f,
508 export_params,
509 verbose,
510 training,
511 input_names,
512 output_names,
513 operator_export_type=operator_export_type,
514 opset_version=opset_version,
515 do_constant_folding=do_constant_folding,
516 dynamic_axes=dynamic_axes,
517 keep_initializers_as_inputs=keep_initializers_as_inputs,
518 custom_opsets=custom_opsets,
519 export_modules_as_functions=export_modules_as_functions,
520 )
File [~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\torch\onnx\utils.py:1529](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/Lazhar%20Bouacha/OneDrive%20-%20CHAMP%27S/PhD/~/AppData/Local/Packages/PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0/LocalCache/local-packages/Python310/site-packages/torch/onnx/utils.py:1529), in _export(model, args, f, export_params, verbose, training, input_names, output_names, operator_export_type, export_type, opset_version, do_constant_folding, dynamic_axes, keep_initializers_as_inputs, fixed_batch_size, custom_opsets, add_node_names, onnx_shape_inference, export_modules_as_functions)
1526 dynamic_axes = {}
1527 _validate_dynamic_axes(dynamic_axes, model, input_names, output_names)
-> 1529 graph, params_dict, torch_out = _model_to_graph(
1530 model,
1531 args,
1532 verbose,
1533 input_names,
1534 output_names,
1535 operator_export_type,
1536 val_do_constant_folding,
1537 fixed_batch_size=fixed_batch_size,
1538 training=training,
1539 dynamic_axes=dynamic_axes,
1540 )
1542 # TODO: Don't allocate a in-memory string for the protobuf
1543 defer_weight_export = (
1544 export_type is not _exporter_states.ExportTypes.PROTOBUF_FILE
1545 )
File [~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\torch\onnx\utils.py:1111](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/Lazhar%20Bouacha/OneDrive%20-%20CHAMP%27S/PhD/~/AppData/Local/Packages/PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0/LocalCache/local-packages/Python310/site-packages/torch/onnx/utils.py:1111), in _model_to_graph(model, args, verbose, input_names, output_names, operator_export_type, do_constant_folding, _disable_torch_constant_prop, fixed_batch_size, training, dynamic_axes)
1108 args = (args,)
1110 model = _pre_trace_quant_model(model, args)
-> 1111 graph, params, torch_out, module = _create_jit_graph(model, args)
1112 params_dict = _get_named_param_dict(graph, params)
1114 try:
File [~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\torch\onnx\utils.py:987](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/Lazhar%20Bouacha/OneDrive%20-%20CHAMP%27S/PhD/~/AppData/Local/Packages/PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0/LocalCache/local-packages/Python310/site-packages/torch/onnx/utils.py:987), in _create_jit_graph(model, args)
982 graph = _C._propagate_and_assign_input_shapes(
983 graph, flattened_args, param_count_list, False, False
984 )
985 return graph, params, torch_out, None
--> 987 graph, torch_out = _trace_and_get_graph_from_model(model, args)
988 _C._jit_pass_onnx_lint(graph)
989 state_dict = torch.jit._unique_state_dict(model)
File [~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\torch\onnx\utils.py:891](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/Lazhar%20Bouacha/OneDrive%20-%20CHAMP%27S/PhD/~/AppData/Local/Packages/PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0/LocalCache/local-packages/Python310/site-packages/torch/onnx/utils.py:891), in _trace_and_get_graph_from_model(model, args)
889 prev_autocast_cache_enabled = torch.is_autocast_cache_enabled()
890 torch.set_autocast_cache_enabled(False)
--> 891 trace_graph, torch_out, inputs_states = torch.jit._get_trace_graph(
892 model,
893 args,
894 strict=False,
895 _force_outplace=False,
896 _return_inputs_states=True,
897 )
898 torch.set_autocast_cache_enabled(prev_autocast_cache_enabled)
900 warn_on_static_input_change(inputs_states)
File [~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\torch\jit\_trace.py:1184](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/Lazhar%20Bouacha/OneDrive%20-%20CHAMP%27S/PhD/~/AppData/Local/Packages/PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0/LocalCache/local-packages/Python310/site-packages/torch/jit/_trace.py:1184), in _get_trace_graph(f, args, kwargs, strict, _force_outplace, return_inputs, _return_inputs_states)
1182 if not isinstance(args, tuple):
...
231 self.backbone.size_divisibility,
232 padding_constraints=self.backbone.padding_constraints,
233 )
IndexError: too many indices for tensor of dimension 3
```
## Expected behavior:
I would like to export detectron2 model to OpenVINO because I have Intel Iris Xe graphics and NCS 2. Is it possible to do it with ONNX ?
## Environment:
```
No CUDA runtime is found, using CUDA_HOME='C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.1'
------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
sys.platform win32
Python 3.10.10 (tags/v3.10.10:aad5f6a, Feb 7 2023, 17:20:36) [MSC v.1929 64 bit (AMD64)]
numpy 1.24.2
detectron2 0.6 @C:\Users\Lazhar Bouacha\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\detectron2
Compiler MSVC 193532215
CUDA compiler not available
DETECTRON2_ENV_MODULE
PyTorch 1.13.1+cpu @C:\Users\Lazhar Bouacha\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\torch
PyTorch debug build False
torch._C._GLIBCXX_USE_CXX11_ABI False
GPU available No: torch.cuda.is_available() == False
Pillow 9.4.0
torchvision 0.14.1+cpu @C:\Users\Lazhar Bouacha\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\torchvision
fvcore 0.1.5.post20221221
iopath 0.1.9
cv2 4.7.0
------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PyTorch built with:
- C++ Version: 199711
- MSVC 192829337
- Intel(R) Math Kernel Library Version 2020.0.2 Product Build 20200624 for Intel(R) 64 architecture applications
- Intel(R) MKL-DNN v2.6.0 (Git Hash 52b5f107dd9cf10910aaa19cb47f3abf9b349815)
- OpenMP 2019
- LAPACK is enabled (usually provided by MKL)
- CPU capability usage: AVX2
- Build settings: BLAS_INFO=mkl, BUILD_TYPE=Release, CXX_COMPILER=C:/actions-runner/_work/pytorch/pytorch/builder/windows/tmp_bin/sccache-cl.exe, CXX_FLAGS=/DWIN32 /D_WINDOWS /GR /EHsc /w /bigobj -DUSE_PTHREADPOOL -openmp:experimental -IC:/actions-runner/_work/pytorch/pytorch/builder/windows/mkl/include -DNDEBUG -DUSE_KINETO -DLIBKINETO_NOCUPTI -DUSE_FBGEMM -DUSE_XNNPACK -DSYMBOLICATE_MOBILE_DEBUG_HANDLE -DEDGE_PROFILER_USE_KINETO, LAPACK_INFO=mkl, PERF_WITH_AVX=1, PERF_WITH_AVX2=1, PERF_WITH_AVX512=1, TORCH_VERSION=1.13.1, USE_CUDA=0, USE_CUDNN=OFF, USE_EXCEPTION_PTR=1, USE_GFLAGS=OFF, USE_GLOG=OFF, USE_MKL=ON, USE_MKLDNN=ON, USE_MPI=OFF, USE_NCCL=OFF, USE_NNPACK=OFF, USE_OPENMP=ON, USE_ROCM=OFF,
```
Contributor guide
Assessment
This issue has not been assessed yet.