facebookresearch / facebookresearch/detectron2
Export Faster RCNN model to Onnx
- Dominant language
- Python
- Stars
- 34.7k
- Forks
- 7.9k
- PR merge metrics
- No merged PRs in 30d
Description
## Instructions To Reproduce the Issue:
Trained a custom Faster RCNN model and trying to export to Onnx format using `torch.onnx.export` method.
1. Full runnable code or full changes you made:
```
from detectron2.modeling import build_model
from detectron2.config import get_cfg
import torch
import cv2
cfg = get_cfg()
cfg.merge_from_file("config.yaml")
torch_model = build_model(cfg)
torch_model.train(False)
state_dict = torch.load('model.pth')["model"]
torch_model.load_state_dict(state_dict,strict=False)
torch_model.eval()
image=cv2.imread("uniform.webp")
image=cv2.resize(image,(852,640))
image = torch.as_tensor(image.astype("float32").transpose(2, 0, 1))
inputs = {"image": image}
sample_inputs = [inputs]
torch.onnx.export(torch_model, sample_inputs,"my_model.onnx", do_constant_folding=True, opset_version=11, export_params=True)
```
2. __Full logs__ or other relevant observations:
```
TypeError Traceback (most recent call last)
Input In [11], in ()
----> 1 torch.onnx.export(torch_model, sample_inputs,"my_model.onnx", do_constant_folding=True, opset_version=11,export_params=True)
File /opt/conda/lib/python3.8/site-packages/torch/onnx/__init__.py:275, in export(model, args, f, export_params, verbose, training, input_names, output_names, aten, export_raw_ir, operator_export_type, opset_version, _retain_param_name, do_constant_folding, example_outputs, strip_doc_string, dynamic_axes, keep_initializers_as_inputs, custom_opsets, enable_onnx_checker, use_external_data_format)
38 r"""
39 Export a model into ONNX format. This exporter runs your model
40 once in order to get a trace of its execution to be exported;
(...)
271 than ONNX.
272 """
274 from torch.onnx import utils
--> 275 return utils.export(model, args, f, export_params, verbose, training,
276 input_names, output_names, aten, export_raw_ir,
277 operator_export_type, opset_version, _retain_param_name,
278 do_constant_folding, example_outputs,
279 strip_doc_string, dynamic_axes, keep_initializers_as_inputs,
280 custom_opsets, enable_onnx_checker, use_external_data_format)
File /opt/conda/lib/python3.8/site-packages/torch/onnx/utils.py:88, in export(model, args, f, export_params, verbose, training, input_names, output_names, aten, export_raw_ir, operator_export_type, opset_version, _retain_param_name, do_constant_folding, example_outputs, strip_doc_string, dynamic_axes, keep_initializers_as_inputs, custom_opsets, enable_onnx_checker, use_external_data_format)
86 else:
87 operator_export_type = OperatorExportTypes.ONNX
---> 88 _export(model, args, f, export_params, verbose, training, input_names, output_names,
89 operator_export_type=operator_export_type, opset_version=opset_version,
90 _retain_param_name=_retain_param_name, do_constant_folding=do_constant_folding,
91 example_outputs=example_outputs, strip_doc_string=strip_doc_string,
92 dynamic_axes=dynamic_axes, keep_initializers_as_inputs=keep_initializers_as_inputs,
93 custom_opsets=custom_opsets, enable_onnx_checker=enable_onnx_checker,
94 use_external_data_format=use_external_data_format)
File /opt/conda/lib/python3.8/site-packages/torch/onnx/utils.py:689, in _export(model, args, f, export_params, verbose, training, input_names, output_names, operator_export_type, export_type, example_outputs, opset_version, _retain_param_name, do_constant_folding, strip_doc_string, dynamic_axes, keep_initializers_as_inputs, fixed_batch_size, custom_opsets, add_node_names, enable_onnx_checker, use_external_data_format, onnx_shape_inference)
685 dynamic_axes = {}
686 _validate_dynamic_axes(dynamic_axes, model, input_names, output_names)
688 graph, params_dict, torch_out = \
--> 689 _model_to_graph(model, args, verbose, input_names,
690 output_names, operator_export_type,
691 example_outputs, _retain_param_name,
692 val_do_constant_folding,
693 fixed_batch_size=fixed_batch_size,
694 training=training,
695 dynamic_axes=dynamic_axes)
697 # TODO: Don't allocate a in-memory string for the protobuf
698 defer_weight_export = export_type is not ExportTypes.PROTOBUF_FILE
File /opt/conda/lib/python3.8/site-packages/torch/onnx/utils.py:458, in _model_to_graph(model, args, verbose, input_names, output_names, operator_export_type, example_outputs, _retain_param_name, do_constant_folding, _disable_torch_constant_prop, fixed_batch_size, training, dynamic_axes)
455 if isinstance(example_outputs, (torch.Tensor, int, float, bool)):
456 example_outputs = (example_outputs,)
--> 458 graph, params, torch_out, module = _create_jit_graph(model, args,
459 _retain_param_name)
461 params_dict = _get_named_param_dict(graph, params)
463 graph = _optimize_graph(graph, operator_export_type,
464 _disable_torch_constant_prop=_disable_torch_constant_prop,
465 fixed_batch_size=fixed_batch_size, params_dict=params_dict,
466 dynamic_axes=dynamic_axes, input_names=input_names,
467 module=module)
File /opt/conda/lib/python3.8/site-packages/torch/onnx/utils.py:422, in _create_jit_graph(model, args, _retain_param_name)
420 return graph, params, torch_out, None
421 else:
--> 422 graph, torch_out = _trace_and_get_graph_from_model(model, args)
423 state_dict = _unique_state_dict(model)
424 params = list(state_dict.values())
File /opt/conda/lib/python3.8/site-packages/torch/onnx/utils.py:373, in _trace_and_get_graph_from_model(model, args)
366 def _trace_and_get_graph_from_model(model, args):
367
368 # A basic sanity check: make sure the state_dict keys are the same
369 # before and after running the model. Fail fast!
370 orig_state_dict_keys = _unique_state_dict(model).keys()
372 trace_graph, torch_out, inputs_states = \
--> 373 torch.jit._get_trace_graph(model, args, strict=False, _force_outplace=False, _return_inputs_states=True)
374 warn_on_static_input_change(inputs_states)
376 if orig_state_dict_keys != _unique_state_dict(model).keys():
File /opt/conda/lib/python3.8/site-packages/torch/jit/_trace.py:1160, in _get_trace_graph(f, args, kwargs, strict, _force_outplace, return_inputs, _return_inputs_states)
1158 if not isinstance(args, tuple):
1159 args = (args,)
-> 1160 outs = ONNXTracedModule(f, strict, _force_outplace, return_inputs, _return_inputs_states)(*args, **kwargs)
1161 return outs
File /opt/conda/lib/python3.8/site-packages/torch/nn/modules/module.py:1051, in Module._call_impl(self, *input, **kwargs)
1047 # If we don't have any hooks, we want to skip the rest of the logic in
1048 # this function, and just call forward.
1049 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1050 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1051 return forward_call(*input, **kwargs)
1052 # Do not call functions when jit is used
1053 full_backward_hooks, non_full_backward_hooks = [], []
File /opt/conda/lib/python3.8/site-packages/torch/jit/_trace.py:127, in ONNXTracedModule.forward(self, *args)
124 else:
125 return tuple(out_vars)
--> 127 graph, out = torch._C._create_graph_by_tracing(
128 wrapper,
129 in_vars + module_state,
130 _create_interpreter_name_lookup_fn(),
131 self.strict,
132 self._force_outplace,
133 )
135 if self._return_inputs:
136 return graph, outs[0], ret_inputs[0]
File /opt/conda/lib/python3.8/site-packages/torch/jit/_trace.py:118, in ONNXTracedModule.forward..wrapper(*args)
116 if self._return_inputs_states:
117 inputs_states.append(_unflatten(in_args, in_desc))
--> 118 outs.append(self.inner(*trace_inputs))
119 if self._return_inputs_states:
120 inputs_states[0] = (inputs_states[0], trace_inputs)
File /opt/conda/lib/python3.8/site-packages/torch/nn/modules/module.py:1051, in Module._call_impl(self, *input, **kwargs)
1047 # If we don't have any hooks, we want to skip the rest of the logic in
1048 # this function, and just call forward.
1049 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1050 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1051 return forward_call(*input, **kwargs)
1052 # Do not call functions when jit is used
1053 full_backward_hooks, non_full_backward_hooks = [], []
File /opt/conda/lib/python3.8/site-packages/torch/nn/modules/module.py:1039, in Module._slow_forward(self, *input, **kwargs)
1037 recording_scopes = False
1038 try:
-> 1039 result = self.forward(*input, **kwargs)
1040 finally:
1041 if recording_scopes:
File /opt/conda/lib/python3.8/site-packages/detectron2/modeling/meta_arch/rcnn.py:150, in GeneralizedRCNN.forward(self, batched_inputs)
127 """
128 Args:
129 batched_inputs: a list, batched outputs of :class:`DatasetMapper` .
(...)
147 "pred_boxes", "pred_classes", "scores", "pred_masks", "pred_keypoints"
148 """
149 if not self.training:
--> 150 return self.inference(batched_inputs)
152 images = self.preprocess_image(batched_inputs)
153 if "instances" in batched_inputs[0]:
File /opt/conda/lib/python3.8/site-packages/detectron2/modeling/meta_arch/rcnn.py:203, in GeneralizedRCNN.inference(self, batched_inputs, detected_instances, do_postprocess)
184 """
185 Run inference on the given inputs.
186
(...)
199 Otherwise, a list[Instances] containing raw network outputs.
200 """
201 assert not self.training
--> 203 images = self.preprocess_image(batched_inputs)
204 features = self.backbone(images.tensor)
206 if detected_instances is None:
File /opt/conda/lib/python3.8/site-packages/detectron2/modeling/meta_arch/rcnn.py:227, in GeneralizedRCNN.preprocess_image(self, batched_inputs)
223 def preprocess_image(self, batched_inputs: List[Dict[str, torch.Tensor]]):
224 """
225 Normalize, pad and batch the input images.
226 """
--> 227 images = [self._move_to_current_device(x["image"]) for x in batched_inputs]
228 images = [(x - self.pixel_mean) / self.pixel_std for x in images]
229 images = ImageList.from_tensors(
230 images,
231 self.backbone.size_divisibility,
232 padding_constraints=self.backbone.padding_constraints,
233 )
TypeError: 'NoneType' object is not iterable
```
## Expected behavior:
Model should be exported to Onnx format but somehow `sample_images` passed to `torch.onnx.export` method is received as `None`. If I just do predict like `torch_model(sample_images)`, it works and I get the outputs.
## Environment:
Paste the output of the following command:
```
sys.platform linux
Python 3.8.13 | packaged by conda-forge | (default, Mar 25 2022, 06:04:10) [GCC 10.3.0]
numpy 1.22.4
detectron2 0.6 @/opt/conda/lib/python3.8/site-packages/detectron2
detectron2._C not built correctly: /opt/conda/lib/python3.8/site-packages/detectron2/_C.cpython-38-x86_64-linux-gnu.so: undefined symbol: _ZN2at4_ops6narrow4callERKNS_6TensorElll
Compiler ($CXX) c++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
CUDA compiler Build cuda_11.7.r11.7/compiler.31442593_0
detectron2 arch flags /opt/conda/lib/python3.8/site-packages/detectron2/_C.cpython-38-x86_64-linux-gnu.so
DETECTRON2_ENV_MODULE
PyTorch 1.9.1+cu111 @/opt/conda/lib/python3.8/site-packages/torch
PyTorch debug build False
GPU available Yes
GPU 0 Tesla T4 (arch=7.5)
Driver version 470.141.03
CUDA_HOME /usr/local/cuda
TORCH_CUDA_ARCH_LIST 5.2 6.0 6.1 7.0 7.5 8.0 8.6+PTX
Pillow 9.0.1
torchvision 0.10.1+cu111 @/opt/conda/lib/python3.8/site-packages/torchvision
torchvision arch flags 3.5, 5.0, 6.0, 7.0, 7.5, 8.0, 8.6
fvcore 0.1.5.post20220512
iopath 0.1.9
cv2 3.4.11
```
Contributor guide
Assessment
This issue has not been assessed yet.