Remove posibility to export to onnx (#17442)

* Remove posibility to export to onnx

* Add OOB pytorch convert_model test
This commit is contained in:
Maxim Vafin
2023-05-17 13:39:35 +02:00
committed by GitHub
parent 43acbf59b6
commit db58355fad
7 changed files with 112 additions and 391 deletions
@@ -49,20 +49,6 @@ Example of using ``example_input``:
* ``list`` or ``tuple`` with tensors (``openvino.runtime.Tensor`` / ``torch.Tensor`` / ``np.ndarray``)
* ``dictionary`` where key is the input name, value is the tensor (``openvino.runtime.Tensor`` / ``torch.Tensor`` / ``np.ndarray``)
If ``use_legacy_frontend`` is set, it enables PyTorch model conversion using a temporary ONNX model.
ONNX opset version can be set using an optional ``onnx_opset_version`` parameter.
If ``onnx_opset_version`` is not set, the default opset from ``torch.onnx.export()`` is used.
Example of PyTorch model conversion using a temporary ONNX model:
.. code-block:: python
import torchvision
model = torchvision.models.resnet50(pretrained=True)
ov_model = convert_model(model, input_shape=[1,3,100,100], use_legacy_frontend=True, onnx_opset_version=13)
Exporting a PyTorch Model to ONNX Format
########################################
+6 -2
View File
@@ -45,9 +45,13 @@ std::vector<ov::frontend::Place::Ptr> InputModel::get_inputs() const {
for (const auto& input_idx : m_model_decoder->inputs()) {
auto place_it = m_name_to_place.find(std::to_string(input_idx));
FRONT_END_GENERAL_CHECK(place_it != m_name_to_place.end(), "Couldn't find Place for input.");
if (input_idx != 0) {
res.push_back(place_it->second);
const auto& names = place_it->second->get_names();
if (input_idx == 0 && std::any_of(names.cbegin(), names.cend(), [](const std::string& n) {
return n.find("self") != std::string::npos;
})) {
continue;
}
res.push_back(place_it->second);
}
return res;
}
@@ -56,7 +56,7 @@ def make_pt_model_two_inputs():
)
def forward(self, x, y):
logits = self.linear_relu_stack(x + y)
logits = self.linear_relu_stack(x * y)
return logits
return NeuralNetwork()
@@ -83,8 +83,8 @@ def make_ref_pt_model_two_inputs(shape, dtype=np.float32):
shape = PartialShape(shape)
param1 = ov.opset8.parameter(shape, name="input_0", dtype=dtype)
param2 = ov.opset8.parameter(shape, name="input_1", dtype=dtype)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
mul = ov.opset8.multiply(param1, param2)
relu = ov.opset8.relu(mul)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
@@ -100,8 +100,8 @@ def create_pytorch_nn_module_case1(tmp_dir):
sample_input2 = torch.zeros(1, 3, 10, 10)
sample_input = sample_input1, sample_input2
return pt_model, ref_model, {'input_shape': [PartialShape([-1, 3, -1, -1]), PartialShape([-1, 3, -1, -1])],
'example_input': sample_input, "use_legacy_frontend": True}
return pt_model, ref_model, {'input': [([-1, 3, -1, -1], np.float32), ([-1, 3, -1, -1], np.float32)],
'example_input': sample_input}
def create_pytorch_nn_module_case2(tmp_dir):
@@ -113,7 +113,8 @@ def create_pytorch_nn_module_case2(tmp_dir):
sample_input = sample_input1, sample_input2
return pt_model, ref_model, {'input_shape': ["[?,3,?,?]", PartialShape([-1, 3, -1, -1])],
'example_input': sample_input, 'onnx_opset_version': 11, "use_legacy_frontend": True}
'input': [np.float32, np.float32],
'example_input': sample_input}
def create_pytorch_nn_module_case3(tmp_dir):
@@ -124,7 +125,9 @@ def create_pytorch_nn_module_case3(tmp_dir):
sample_input2 = torch.zeros(1, 3, 10, 10)
sample_input = tuple([sample_input1, sample_input2])
return pt_model, ref_model, {'input_shape': "[?,3,?,?],[?,3,?,?]", 'example_input': sample_input, "use_legacy_frontend": True}
return pt_model, ref_model, {'input_shape': "[?,3,?,?],[?,3,?,?]",
'input': [np.float32, np.float32],
'example_input': sample_input}
def create_pytorch_nn_module_case4(tmp_dir):
@@ -132,9 +135,10 @@ def create_pytorch_nn_module_case4(tmp_dir):
sample_input = torch.zeros(1, 3, 10, 10)
ref_model = make_ref_pt_model_one_input([1, 3, 10, 10])
ref_model = make_ref_pt_model_one_input(PartialShape.dynamic())
return pt_model, ref_model, {'example_input': sample_input, "use_legacy_frontend": True}
return pt_model, ref_model, {'input': [np.float32],
'example_input': sample_input}
def create_pytorch_nn_module_case5(tmp_dir):
@@ -144,7 +148,7 @@ def create_pytorch_nn_module_case5(tmp_dir):
sample_input = torch.zeros(3, 3, 10, 10)
return pt_model, ref_model, {'example_input': sample_input,
'input_shape': inp_shape, "use_legacy_frontend": True}
'input': (inp_shape, np.float32)}
def create_pytorch_nn_module_case6(tmp_dir):
@@ -152,14 +156,14 @@ def create_pytorch_nn_module_case6(tmp_dir):
shape = PartialShape([1, 3, Dimension(2, -1), Dimension(-1, 10)])
ref_model = make_ref_pt_model_one_input(shape)
return pt_model, ref_model, {'input_shape': shape, "use_legacy_frontend": True}
return pt_model, ref_model, {'input': (shape, np.float32)}
def create_pytorch_nn_module_torch_size(tmp_dir):
pt_model = make_pt_model_one_input()
ref_model = make_ref_pt_model_one_input([1, 3, 2, 10])
return pt_model, ref_model, {'input_shape': torch.Size([1, 3, 2, 10]), "use_legacy_frontend": True}
return pt_model, ref_model, {'input': (torch.Size([1, 3, 2, 10]), np.float32)}
def create_pytorch_nn_module_sample_input_int32(tmp_dir):
@@ -171,7 +175,7 @@ def create_pytorch_nn_module_sample_input_int32(tmp_dir):
ref_model = make_ref_pt_model_one_input(shape, dtype=numpy.int32)
return pt_model, ref_model, {'example_input': sample_input,
'input_shape': shape, "use_legacy_frontend": True}
'input': (shape, np.int32)}
def create_pytorch_nn_module_sample_input_int32_two_inputs(tmp_dir):
@@ -185,105 +189,8 @@ def create_pytorch_nn_module_sample_input_int32_two_inputs(tmp_dir):
[PartialShape([-1, 3, -1, -1]), inp_shapes[1]], dtype=np.int32)
return pt_model, ref_model, {'input_shape': inp_shapes,
'example_input': sample_input, 'onnx_opset_version': 11, "use_legacy_frontend": True}
def create_pytorch_nn_module_compare_convert_paths_case1(tmp_dir):
from openvino.tools.mo import convert_model
pt_model = make_pt_model_one_input()
sample_input = torch.zeros(1, 3, 10, 10, dtype=torch.int32)
onnx_model_path = os.path.join(tmp_dir, 'export.onnx')
torch.onnx.export(pt_model, sample_input,
onnx_model_path, opset_version=16)
ref_model = convert_model(onnx_model_path)
return pt_model, ref_model, {'example_input': sample_input, 'onnx_opset_version': 16, "use_legacy_frontend": True}
def create_pytorch_nn_module_compare_convert_paths_case2(tmp_dir):
from openvino.tools.mo import convert_model
pt_model = make_pt_model_one_input()
sample_input = torch.zeros(1, 3, 10, 10, dtype=torch.int32)
onnx_model_path = os.path.join(tmp_dir, 'export.onnx')
torch.onnx.export(pt_model, sample_input,
onnx_model_path, opset_version=16)
ref_model = convert_model(onnx_model_path)
return pt_model, ref_model, {'example_input': sample_input,
'input_shape': [1, 3, 10, 10],
'onnx_opset_version': 16,
"use_legacy_frontend": True
}
def create_pytorch_nn_module_compare_convert_paths_case3(tmp_dir):
from openvino.tools.mo import convert_model
pt_model = make_pt_model_one_input()
sample_input = torch.zeros(1, 3, 10, 10, dtype=torch.float32)
onnx_model_path = os.path.join(tmp_dir, 'export.onnx')
torch.onnx.export(pt_model, sample_input,
onnx_model_path, opset_version=16)
ref_model = convert_model(onnx_model_path)
return pt_model, ref_model, {'input_shape': [1, 3, 10, 10],
'onnx_opset_version': 16, "use_legacy_frontend": True}
def create_pytorch_nn_module_compare_convert_paths_case4(tmp_dir):
from openvino.tools.mo import convert_model
pt_model = make_pt_model_two_inputs()
sample_input1 = torch.zeros(1, 3, 10, 10, dtype=torch.int32)
sample_input2 = torch.zeros(1, 3, 10, 10, dtype=torch.int32)
sample_input = (sample_input1, sample_input2)
onnx_model_path = os.path.join(tmp_dir, 'export.onnx')
torch.onnx.export(pt_model, sample_input,
onnx_model_path, opset_version=16)
ref_model = convert_model(onnx_model_path)
return pt_model, ref_model, {'example_input': sample_input, 'onnx_opset_version': 16, "use_legacy_frontend": True}
def create_pytorch_nn_module_compare_convert_paths_case5(tmp_dir):
from openvino.tools.mo import convert_model
pt_model = make_pt_model_two_inputs()
sample_input1 = torch.zeros(1, 3, 10, 10, dtype=torch.int32)
sample_input2 = torch.zeros(1, 3, 10, 10, dtype=torch.int32)
sample_input = tuple([sample_input1, sample_input2])
onnx_model_path = os.path.join(tmp_dir, 'export.onnx')
torch.onnx.export(pt_model, sample_input,
onnx_model_path, opset_version=16)
ref_model = convert_model(onnx_model_path)
return pt_model, ref_model, {'example_input': sample_input,
'input_shape': [torch.Size([1, 3, 10, 10]), PartialShape([1, 3, 10, 10])],
'onnx_opset_version': 16, "use_legacy_frontend": True}
def create_pytorch_nn_module_compare_convert_paths_case6(tmp_dir):
from openvino.tools.mo import convert_model
pt_model = make_pt_model_two_inputs()
sample_input1 = torch.zeros(1, 3, 10, 10, dtype=torch.float32)
sample_input2 = torch.zeros(1, 3, 10, 10, dtype=torch.float32)
sample_input = tuple([sample_input1, sample_input2])
onnx_model_path = os.path.join(tmp_dir, 'export.onnx')
torch.onnx.export(pt_model, sample_input,
onnx_model_path, opset_version=16)
ref_model = convert_model(onnx_model_path)
return pt_model, ref_model, {'input_shape': [torch.Size([1, 3, 10, 10]), torch.Size([1, 3, 10, 10])],
'onnx_opset_version': 16, "use_legacy_frontend": True}
'input': [np.int32, np.int32],
'example_input': sample_input}
def create_pytorch_jit_script_module(tmp_dir):
@@ -293,7 +200,7 @@ def create_pytorch_jit_script_module(tmp_dir):
scripted_model = torch.jit.script(net)
model_ref = make_ref_pt_model_two_inputs([1, 3, 5, 5])
return scripted_model, model_ref, {'input_shape': [PartialShape([1, 3, 5, 5]), PartialShape([1, 3, 5, 5])], "use_legacy_frontend": True}
return scripted_model, model_ref, {'input': [([1, 3, 5, 5], np.float32), ([1, 3, 5, 5], np.float32)]}
def create_pytorch_jit_script_function(tmp_dir):
@@ -301,108 +208,13 @@ def create_pytorch_jit_script_function(tmp_dir):
@torch.jit.script
def scripted_fn(x: torch.Tensor, y: torch.Tensor):
return torch.sigmoid(torch.relu(x + y))
return torch.sigmoid(torch.relu(x * y))
inp_shape = PartialShape([Dimension(1, -1), Dimension(-1, 5), 10])
ref_model = make_ref_pt_model_two_inputs(inp_shape)
return scripted_fn, ref_model, {'input_shape': [inp_shape, inp_shape], "use_legacy_frontend": True}
return scripted_fn, ref_model, {'input': [(inp_shape, np.float32), (inp_shape, np.float32)]}
def create_pytorch_nn_module_sample_input_numpy(tmp_dir):
from openvino.tools.mo import convert_model
pt_model = make_pt_model_one_input()
example_inputs = np.array(torch.zeros(1, 3, 10, 10, dtype=torch.int32))
onnx_model_path = os.path.join(tmp_dir, 'export.onnx')
torch.onnx.export(pt_model, torch.zeros(
1, 3, 10, 10, dtype=torch.int32), onnx_model_path, opset_version=16)
ref_model = convert_model(onnx_model_path)
return pt_model, ref_model, {'example_input': example_inputs,
'input_shape': [1, 3, 10, 10],
'onnx_opset_version': 16, "use_legacy_frontend": True}
def create_pytorch_nn_module_sample_input_dict(tmp_dir):
from openvino.tools.mo import convert_model
pt_model = make_pt_model_one_input()
example_inputs = {"x": np.array(
torch.zeros(1, 3, 10, 10, dtype=torch.int32))}
onnx_model_path = os.path.join(tmp_dir, 'export.onnx')
torch.onnx.export(pt_model, torch.zeros(
1, 3, 10, 10, dtype=torch.int32), onnx_model_path, opset_version=16)
ref_model = convert_model(onnx_model_path)
return pt_model, ref_model, {'example_input': example_inputs,
'onnx_opset_version': 16, "use_legacy_frontend": True}
def create_pytorch_nn_module_sample_input_dict_two_inputs(tmp_dir):
from openvino.tools.mo import convert_model
pt_model = make_pt_model_two_inputs()
example_inputs = {"y": np.array(torch.zeros(1, 3, 10, 10, dtype=torch.int32)),
"x": np.array(torch.zeros(1, 3, 10, 10, dtype=torch.int32))}
onnx_model_path = os.path.join(tmp_dir, 'export.onnx')
torch.onnx.export(pt_model, {"y": torch.zeros(1, 3, 10, 10, dtype=torch.int32),
"x": torch.zeros(1, 3, 10, 10, dtype=torch.int32)}, onnx_model_path, opset_version=16)
ref_model = convert_model(onnx_model_path)
return pt_model, ref_model, {'example_input': example_inputs,
'onnx_opset_version': 16, "use_legacy_frontend": True}
def create_pytorch_nn_module_sample_list_of_tensors(tmp_dir):
from openvino.tools.mo import convert_model
pt_model = make_pt_model_one_input()
example_inputs = [torch.zeros(3, 10, 10, dtype=torch.float32)]
onnx_model_path = os.path.join(tmp_dir, 'export.onnx')
torch.onnx.export(pt_model, torch.unsqueeze(
example_inputs[0], 0), onnx_model_path, opset_version=16)
ref_model = convert_model(onnx_model_path)
return pt_model, ref_model, {'example_input': example_inputs,
'onnx_opset_version': 16, "use_legacy_frontend": True}
def create_pytorch_nn_module_sample_input_ov_host_tensor(tmp_dir):
from openvino.tools.mo import convert_model
from openvino.runtime import Tensor
pt_model = make_pt_model_one_input()
sample_input = Tensor(np.zeros([1, 3, 10, 10], dtype=np.int32))
onnx_model_path = os.path.join(tmp_dir, 'export.onnx')
torch.onnx.export(pt_model, torch.zeros(
1, 3, 10, 10, dtype=torch.int32), onnx_model_path, opset_version=16)
ref_model = convert_model(onnx_model_path)
return pt_model, ref_model, {'example_input': sample_input,
'input_shape': [1, 3, 10, 10],
'onnx_opset_version': 16, "use_legacy_frontend": True}
def create_pytorch_nn_module_sample_input_ov_host_tensor_two_inputs(tmp_dir):
from openvino.tools.mo import convert_model
from openvino.runtime import Tensor
pt_model = make_pt_model_two_inputs()
sample_input1 = Tensor(np.zeros([1, 3, 10, 10], dtype=np.int32))
sample_input2 = Tensor(np.zeros([1, 3, 10, 10], dtype=np.int32))
sample_input = sample_input1, sample_input2
onnx_model_path = os.path.join(tmp_dir, 'export.onnx')
torch.onnx.export(pt_model, tuple([torch.zeros(1, 3, 10, 10, dtype=torch.int32),
torch.zeros(1, 3, 10, 10, dtype=torch.int32)]),
onnx_model_path, opset_version=16)
ref_model = convert_model(onnx_model_path)
return pt_model, ref_model, {'example_input': sample_input,
'onnx_opset_version': 16, "use_legacy_frontend": True}
def create_pytorch_nn_module_layout_list(tmp_dir):
from openvino.runtime import Layout
@@ -416,7 +228,7 @@ def create_pytorch_nn_module_layout_list(tmp_dir):
return pt_model, ref_model, {
'input_shape': [shape, shape], 'layout': ['nchw', Layout('nhwc')],
"input": [np.float32, np.float32]
'input': [np.float32, np.float32]
}
@@ -432,7 +244,7 @@ def create_pytorch_nn_module_layout_list_case2(tmp_dir):
return pt_model, ref_model, {
'input_shape': [shape, shape], 'layout': ('nchw', Layout('nhwc')),
"input": [np.float32, np.float32]}
'input': [np.float32, np.float32]}
def create_pytorch_nn_module_mean_list(tmp_dir):
@@ -446,8 +258,8 @@ def create_pytorch_nn_module_mean_list(tmp_dir):
const2 = ov.opset8.constant([[[[-0.0, -0.0, -0.0]]]], dtype=np.float32)
add1 = ov.opset8.add(param1, const1)
add2 = ov.opset8.add(param2, const2)
add3 = ov.opset8.add(add1, add2)
relu = ov.opset8.relu(add3)
mul = ov.opset8.multiply(add1, add2)
relu = ov.opset8.relu(mul)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
@@ -455,7 +267,7 @@ def create_pytorch_nn_module_mean_list(tmp_dir):
return pt_model, ref_model, {
'input_shape': [shape, shape], 'mean_values': [[0, 0, 0], [0, 0, 0]], 'compress_to_fp16': False,
"input": [np.float32, np.float32]}
'input': [np.float32, np.float32]}
def create_pytorch_nn_module_mean_list_default_no_compression(tmp_dir):
@@ -470,17 +282,17 @@ def create_pytorch_nn_module_mean_list_default_no_compression(tmp_dir):
const2 = ov.opset8.constant([[[[-0.0, -0.0, -0.0]]]], dtype=np.float32)
add1 = ov.opset8.add(param1, const1)
add2 = ov.opset8.add(param2, const2)
add3 = ov.opset8.add(add1, add2)
relu = ov.opset8.relu(add3)
mul = ov.opset8.multiply(add1, add2)
relu = ov.opset8.relu(mul)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return pt_model, ref_model, {'input_shape': [shape, shape], 'mean_values': [[0, 0, 0], [0, 0, 0]], "input": [np.float32, np.float32]}
return pt_model, ref_model, {'input_shape': [shape, shape], 'mean_values': [[0, 0, 0], [0, 0, 0]], 'input': [np.float32, np.float32]}
def create_pytorch_nn_module_mean_list_compressin_enabled(tmp_dir):
def create_pytorch_nn_module_mean_list_compression_enabled(tmp_dir):
pt_model = make_pt_model_two_inputs()
shape = [1, 10, 10, 3]
@@ -491,8 +303,8 @@ def create_pytorch_nn_module_mean_list_compressin_enabled(tmp_dir):
const2 = ov.opset8.constant([[[[-0.0, -0.0, -0.0]]]], dtype=np.float32)
add1 = ov.opset8.add(param1, const1)
add2 = ov.opset8.add(param2, const2)
add3 = ov.opset8.add(add1, add2)
relu = ov.opset8.relu(add3)
mul = ov.opset8.multiply(add1, add2)
relu = ov.opset8.relu(mul)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
@@ -500,7 +312,7 @@ def create_pytorch_nn_module_mean_list_compressin_enabled(tmp_dir):
return pt_model, ref_model, {
'input_shape': [shape, shape], 'mean_values': [[0, 0, 0], [0, 0, 0]],
'compress_to_fp16': False, "input": [np.float32, np.float32]}
'compress_to_fp16': False, 'input': [np.float32, np.float32]}
def create_pytorch_nn_module_scale_list(tmp_dir):
@@ -514,14 +326,14 @@ def create_pytorch_nn_module_scale_list(tmp_dir):
const2 = ov.opset8.constant([[[[1, 1, 1]]]], dtype=np.float32)
sub1 = ov.opset8.multiply(param1, const1)
sub2 = ov.opset8.multiply(param2, const2)
add = ov.opset8.add(sub1, sub2)
relu = ov.opset8.relu(add)
mul = ov.opset8.multiply(sub1, sub2)
relu = ov.opset8.relu(mul)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return pt_model, ref_model, {'input_shape': [shape, shape], 'scale_values': [[1, 1, 1], [1, 1, 1]], 'compress_to_fp16': False, "input": [np.float32, np.float32]}
return pt_model, ref_model, {'input_shape': [shape, shape], 'scale_values': [[1, 1, 1], [1, 1, 1]], 'compress_to_fp16': False, 'input': [np.float32, np.float32]}
def create_pytorch_nn_module_scale_list_default_no_compression(tmp_dir):
@@ -536,14 +348,14 @@ def create_pytorch_nn_module_scale_list_default_no_compression(tmp_dir):
const2 = ov.opset8.constant([[[[1, 1, 1]]]], dtype=np.float32)
sub1 = ov.opset8.multiply(param1, const1)
sub2 = ov.opset8.multiply(param2, const2)
add = ov.opset8.add(sub1, sub2)
relu = ov.opset8.relu(add)
mul = ov.opset8.multiply(sub1, sub2)
relu = ov.opset8.relu(mul)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return pt_model, ref_model, {'input_shape': [shape, shape], 'scale_values': [[1, 1, 1], [1, 1, 1]], "input": [np.float32, np.float32]}
return pt_model, ref_model, {'input_shape': [shape, shape], 'scale_values': [[1, 1, 1], [1, 1, 1]], 'input': [np.float32, np.float32]}
def create_pytorch_nn_module_scale_list_compression_enabled(tmp_dir):
@@ -557,16 +369,16 @@ def create_pytorch_nn_module_scale_list_compression_enabled(tmp_dir):
const1_decompressed = ov.opset8.convert(const1, destination_type=np.float32)
const2 = ov.opset8.constant([[[[1, 1, 1]]]], dtype=np.float16)
const2_decompressed = ov.opset8.convert(const2, destination_type=np.float32)
sub1 = ov.opset8.multiply(param1, const1_decompressed)
sub2 = ov.opset8.multiply(param2, const2_decompressed)
add = ov.opset8.add(sub1, sub2)
relu = ov.opset8.relu(add)
mul1 = ov.opset8.multiply(param1, const1_decompressed)
mul2 = ov.opset8.multiply(param2, const2_decompressed)
mul3 = ov.opset8.multiply(mul1, mul2)
relu = ov.opset8.relu(mul3)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return pt_model, ref_model, {'input_shape': [shape, shape], 'scale_values': [[1, 1, 1], [1, 1, 1]], "input": [np.float32, np.float32],
return pt_model, ref_model, {'input_shape': [shape, shape], 'scale_values': [[1, 1, 1], [1, 1, 1]], 'input': [np.float32, np.float32],
'compress_to_fp16': True}
@@ -574,14 +386,14 @@ def create_pytorch_nn_module_shapes_list_static(tmp_dir):
pt_model = make_pt_model_two_inputs()
ref_model = make_ref_pt_model_two_inputs([1, 3, 20, 20])
return pt_model, ref_model, {'input_shape': [[1, 3, 20, 20], [1, 3, 20, 20]], "input": [np.float32, np.float32]}
return pt_model, ref_model, {'input_shape': [[1, 3, 20, 20], [1, 3, 20, 20]], 'input': [np.float32, np.float32]}
def create_pytorch_nn_module_shapes_list_static_via_input(tmp_dir):
pt_model = make_pt_model_two_inputs()
ref_model = make_ref_pt_model_two_inputs([1, 3, 20, 20])
return pt_model, ref_model, {"input": [([1, 3, 20, 20], np.float32), ([1, 3, 20, 20], np.float32)]}
return pt_model, ref_model, {'input': [([1, 3, 20, 20], np.float32), ([1, 3, 20, 20], np.float32)]}
def create_pytorch_nn_module_shapes_list_dynamic(tmp_dir):
@@ -593,13 +405,13 @@ def create_pytorch_nn_module_shapes_list_dynamic(tmp_dir):
inp_shapes[0]), name="x", dtype=np.float32)
param2 = ov.opset8.parameter(PartialShape(
inp_shapes[1]), name="y", dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
mul = ov.opset8.multiply(param1, param2)
relu = ov.opset8.relu(mul)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return pt_model, ref_model, {'input_shape': inp_shapes, "input": [np.float32, np.float32]}
return pt_model, ref_model, {'input_shape': inp_shapes, 'input': [np.float32, np.float32]}
def create_pytorch_nn_module_shapes_list_dynamic_via_input(tmp_dir):
@@ -611,41 +423,41 @@ def create_pytorch_nn_module_shapes_list_dynamic_via_input(tmp_dir):
inp_shapes[0]), name="x", dtype=np.float32)
param2 = ov.opset8.parameter(PartialShape(
inp_shapes[1]), name="y", dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
mul = ov.opset8.multiply(param1, param2)
relu = ov.opset8.relu(mul)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return pt_model, ref_model, {"input": [(inp_shapes[0], np.float32), (inp_shapes[1], np.float32)]}
return pt_model, ref_model, {'input': [(inp_shapes[0], np.float32), (inp_shapes[1], np.float32)]}
def create_pytorch_nn_module_shapes_list_dynamic_single_input(tmp_dir):
pt_model = make_pt_model_one_input()
inp_shapes = [[Dimension(-1), 3, 20, Dimension(20, -1)]]
ref_model = make_ref_pt_model_one_input(inp_shapes[0])
return pt_model, ref_model, {'input_shape': inp_shapes, "input": np.float32}
return pt_model, ref_model, {'input_shape': inp_shapes, 'input': np.float32}
def create_pytorch_nn_module_shapes_list_dynamic_single_input_via_input(tmp_dir):
pt_model = make_pt_model_one_input()
inp_shapes = [Dimension(-1), 3, 20, Dimension(20, -1)]
ref_model = make_ref_pt_model_one_input(inp_shapes)
return pt_model, ref_model, {"input": InputCutInfo(shape=inp_shapes, type=np.float32)}
return pt_model, ref_model, {'input': InputCutInfo(shape=inp_shapes, type=np.float32)}
def create_pytorch_nn_module_shapes_list_static_single_input(tmp_dir):
pt_model = make_pt_model_one_input()
inp_shapes = [[1, 3, 20, 20]]
ref_model = make_ref_pt_model_one_input(inp_shapes[0])
return pt_model, ref_model, {'input_shape': inp_shapes, "input": np.float32}
return pt_model, ref_model, {'input_shape': inp_shapes, 'input': np.float32}
def create_pytorch_nn_module_shapes_list_static_single_input_via_input(tmp_dir):
pt_model = make_pt_model_one_input()
inp_shapes = [1, 3, 20, 20]
ref_model = make_ref_pt_model_one_input(inp_shapes)
return pt_model, ref_model, {"input": (inp_shapes, np.float32)}
return pt_model, ref_model, {'input': (inp_shapes, np.float32)}
def create_pytorch_nn_module_convert_pytorch_frontend1(tmp_dir):
@@ -660,7 +472,7 @@ def create_pytorch_nn_module_convert_pytorch_frontend1(tmp_dir):
ref_model = Model([sigm], parameter_list, "test")
return pt_model, ref_model, {
"example_input": torch.zeros((1, 3, 10, 10)),
"input": [InputCutInfo(shape=[-1, -1, -1, -1], type="f32")]
'input': [InputCutInfo(shape=[-1, -1, -1, -1], type="f32")]
}
@@ -678,7 +490,7 @@ def create_pytorch_nn_module_convert_pytorch_frontend2(tmp_dir):
ref_model.validate_nodes_and_infer_types()
return pt_model, ref_model, {
"example_input": torch.zeros((1, 3, 10, 10), dtype=torch.int32),
"input": [InputCutInfo(shape=[-1, -1, -1, -1], type="i32")]
'input': [InputCutInfo(shape=[-1, -1, -1, -1], type="i32")]
}
@@ -688,15 +500,15 @@ def create_pytorch_nn_module_convert_pytorch_frontend3(tmp_dir):
shape = PartialShape(shape)
param1 = ov.opset10.parameter(shape, dtype=np.float32)
param2 = ov.opset10.parameter(shape, dtype=np.float32)
add = ov.opset10.add(param1, param2)
relu = ov.opset10.relu(add)
mul = ov.opset10.multiply(param1, param2)
relu = ov.opset10.relu(mul)
sigm = ov.opset10.sigmoid(relu)
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return pt_model, ref_model, {
"example_input": [torch.zeros((1, 3, 10, 10)), torch.ones((1, 3, 10, 10))],
"input": [InputCutInfo(shape=[-1, -1, -1, -1], type="f32"), InputCutInfo(shape=[-1, -1, -1, -1], type="f32")]
'input': [InputCutInfo(shape=[-1, -1, -1, -1], type="f32"), InputCutInfo(shape=[-1, -1, -1, -1], type="f32")]
}
@@ -706,15 +518,15 @@ def create_pytorch_nn_module_convert_pytorch_frontend4(tmp_dir):
shape = PartialShape(shape)
param1 = ov.opset10.parameter(shape, dtype=np.float32)
param2 = ov.opset10.parameter(shape, dtype=np.float32)
add = ov.opset10.add(param1, param2)
relu = ov.opset10.relu(add)
mul = ov.opset10.multiply(param1, param2)
relu = ov.opset10.relu(mul)
sigm = ov.opset10.sigmoid(relu)
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return pt_model, ref_model, {
"example_input": {"x": torch.zeros((1, 3, 10, 10), dtype=torch.float32), "y": torch.ones((1, 3, 10, 10), dtype=torch.float32)},
"input": [InputCutInfo(shape=[-1, -1, -1, -1], type="f32"), InputCutInfo(shape=[-1, -1, -1, -1], type="f32")]
'input': [InputCutInfo(shape=[-1, -1, -1, -1], type="f32"), InputCutInfo(shape=[-1, -1, -1, -1], type="f32")]
}
@@ -727,14 +539,14 @@ def create_pytorch_jit_script_module_convert_pytorch_frontend(tmp_dir):
shape = PartialShape(shape)
param1 = ov.opset10.parameter(shape, dtype=np.float32)
param2 = ov.opset10.parameter(shape, dtype=np.float32)
add = ov.opset10.add(param1, param2)
relu = ov.opset10.relu(add)
mul = ov.opset10.multiply(param1, param2)
relu = ov.opset10.relu(mul)
sigm = ov.opset10.sigmoid(relu)
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return scripted_model, ref_model, {
"example_input": {"x": torch.zeros((1, 3, 10, 10)), "y": torch.ones((1, 3, 10, 10))},
"input": [InputCutInfo(shape=[-1, -1, -1, -1], type="f32"), InputCutInfo(shape=[-1, -1, -1, -1], type="f32")]}
'input': [InputCutInfo(shape=[-1, -1, -1, -1], type="f32"), InputCutInfo(shape=[-1, -1, -1, -1], type="f32")]}
def create_pytorch_jit_trace_module_convert_pytorch_frontend(tmp_dir):
@@ -747,15 +559,39 @@ def create_pytorch_jit_trace_module_convert_pytorch_frontend(tmp_dir):
shape = PartialShape(shape)
param1 = ov.opset10.parameter(shape, dtype=np.float32)
param2 = ov.opset10.parameter(shape, dtype=np.float32)
add = ov.opset10.add(param1, param2)
relu = ov.opset10.relu(add)
mul = ov.opset10.multiply(param1, param2)
relu = ov.opset10.relu(mul)
sigm = ov.opset10.sigmoid(relu)
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return scripted_model, ref_model, {"example_input": example_input, "input": [
return scripted_model, ref_model, {"example_input": example_input, 'input': [
InputCutInfo(shape=[-1, -1, -1, -1], type="f32"), InputCutInfo(shape=[-1, -1, -1, -1], type="f32")]}
def create_pytorch_module_convert_pytorch_frontend_oob(tmp_dir):
import torch
import torch.nn.functional as F
class ConvModel(torch.nn.Module):
def __init__(self):
super(ConvModel, self).__init__()
self.weights = torch.rand([1, 3, 3, 3])
def forward(self, x):
return F.conv2d(x, self.weights)
net = ConvModel()
shape = PartialShape([-1, 3, -1, -1])
param1 = ov.opset10.parameter(shape, dtype=np.float32)
weights = ov.opset10.constant(net.weights.numpy(force=True))
conv = ov.opset10.convolution(param1, weights, strides=[1, 1],
pads_begin=[0, 0], pads_end=[0, 0],
dilations=[1, 1])
parameter_list = [param1]
ref_model = Model([conv], parameter_list, "test")
return net, ref_model, {}
class TestMoConvertPyTorch(CommonMOConvertTest):
test_data = [
create_pytorch_nn_module_case1,
@@ -767,24 +603,13 @@ class TestMoConvertPyTorch(CommonMOConvertTest):
create_pytorch_nn_module_torch_size,
create_pytorch_nn_module_sample_input_int32,
create_pytorch_nn_module_sample_input_int32_two_inputs,
create_pytorch_nn_module_compare_convert_paths_case1,
create_pytorch_nn_module_compare_convert_paths_case2,
create_pytorch_nn_module_compare_convert_paths_case4,
create_pytorch_nn_module_compare_convert_paths_case5,
create_pytorch_nn_module_compare_convert_paths_case6,
create_pytorch_nn_module_sample_input_numpy,
create_pytorch_nn_module_sample_input_ov_host_tensor,
create_pytorch_nn_module_sample_input_ov_host_tensor_two_inputs,
create_pytorch_nn_module_sample_input_dict,
create_pytorch_nn_module_sample_input_dict_two_inputs,
create_pytorch_nn_module_sample_list_of_tensors,
create_pytorch_jit_script_module,
create_pytorch_jit_script_function,
create_pytorch_nn_module_layout_list,
create_pytorch_nn_module_layout_list_case2,
create_pytorch_nn_module_mean_list,
create_pytorch_nn_module_mean_list_default_no_compression,
create_pytorch_nn_module_mean_list_compressin_enabled,
create_pytorch_nn_module_mean_list_compression_enabled,
create_pytorch_nn_module_scale_list,
create_pytorch_nn_module_scale_list_default_no_compression,
create_pytorch_nn_module_scale_list_compression_enabled,
@@ -801,7 +626,8 @@ class TestMoConvertPyTorch(CommonMOConvertTest):
create_pytorch_nn_module_convert_pytorch_frontend3,
create_pytorch_nn_module_convert_pytorch_frontend4,
create_pytorch_jit_script_module_convert_pytorch_frontend,
create_pytorch_jit_trace_module_convert_pytorch_frontend
create_pytorch_jit_trace_module_convert_pytorch_frontend,
create_pytorch_module_convert_pytorch_frontend_oob
]
@ pytest.mark.parametrize("create_model", test_data)
@@ -835,17 +661,6 @@ def create_pt_model_with_custom_op():
return MyModel()
class ConvertONNXFallthroughTest(unittest.TestCase):
def test_onnx_fallthrough(self):
from openvino.tools.mo import convert_model
pytorch_model = create_pt_model_with_custom_op()
# Check that ONNX conversion passed, so ONNX frontend raises error message of unsupported op.
with self.assertRaisesRegex(RuntimeError, ".*OpenVINO does not support the following ONNX operations: MyTorchOp.*"):
convert_model(pytorch_model, input_shape=[
1, 2, 3], use_legacy_frontend=True)
class ConvertRaisesExampleInputs(unittest.TestCase):
def test_example_inputs(self):
from openvino.tools.mo import convert_model
-3
View File
@@ -45,7 +45,6 @@ def convert_model(
# PyTorch-specific parameters:
example_input: Any = None,
onnx_opset_version: int = None,
# TensorFlow*-specific parameters
input_model_is_text: bool = None,
@@ -265,8 +264,6 @@ def convert_model(
PyTorch-specific parameters:
:param example_input:
Sample of model input in original framework. For PyTorch it can be torch.Tensor.
:param onnx_opset_version:
Version of ONNX opset that is used for converting from PyTorch to ONNX.
TensorFlow*-specific parameters:
:param input_model_is_text:
+1 -7
View File
@@ -49,7 +49,7 @@ from openvino.tools.mo.utils.telemetry_utils import send_params_info, send_frame
get_tid
from openvino.tools.mo.utils.versions_checker import get_environment_setup # pylint: disable=no-name-in-module
from openvino.tools.mo.moc_frontend.check_config import legacy_extensions_used
from openvino.tools.mo.moc_frontend.pytorch_frontend_utils import get_pytorch_decoder, convert_pytorch_via_onnx
from openvino.tools.mo.moc_frontend.pytorch_frontend_utils import get_pytorch_decoder
from openvino.tools.mo.moc_frontend.shape_utils import parse_input_shapes, get_static_shape
# pylint: disable=no-name-in-module,import-error
@@ -873,12 +873,6 @@ def _convert(cli_parser: argparse.ArgumentParser, framework, args, python_api_us
elif 'example_inputs' in args:
raise AssertionError("'example_inputs' argument is not recognized, maybe you meant to provide 'example_input'?")
if 'use_legacy_frontend' in args and args['use_legacy_frontend']:
# TO DO: remove this path, when pytorch frontend productization is finished, CVS-103726
# prevent invoking legacy mo python onnx frontend for models converted on the fly
args.pop("use_legacy_frontend")
return convert_pytorch_via_onnx(args, example_inputs, cli_parser, framework, _convert)
decoder = get_pytorch_decoder(args['input_model'], parse_input_shapes(args), example_inputs, args.get("input"))
args['input_model'] = decoder
args["framework"] = "pytorch"
@@ -1,27 +1,14 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import logging as log
import numpy as np
from openvino.tools.mo.moc_frontend.shape_utils import get_static_shape, get_dynamic_dims, parse_input_shapes
from openvino.tools.mo.moc_frontend.shape_utils import get_static_shape
from openvino.tools.mo.utils.error import Error
from openvino.runtime import Tensor, Type
from openvino.runtime.utils.types import get_element_type_str
from openvino.tools.mo.utils.cli_parser import input_to_input_cut_info, input_shape_to_input_cut_info
def get_onnx_temp_filename(output_dir):
output_dir = output_dir if output_dir is not None else os.getcwd()
return os.path.normpath(os.path.join(output_dir, "model.onnx"))
def remove_tmp_onnx_model(out_dir):
if not os.environ.get('SAVE_TO_BYTES_IO_ONNX_MODEL'):
tmp_onnx_model = get_onnx_temp_filename(out_dir)
if os.path.exists(tmp_onnx_model):
os.remove(tmp_onnx_model)
def get_pytorch_decoder(model, input_shape, example_inputs, input_info):
try:
@@ -31,7 +18,7 @@ def get_pytorch_decoder(model, input_shape, example_inputs, input_info):
raise e
inputs = prepare_torch_inputs(example_inputs, input_shape, input_info, allow_none=True)
decoder = TorchScriptPythonDecoder(model, example_input=inputs)
return decoder
@@ -48,6 +35,8 @@ def to_torch_tensor(tensor):
else:
raise Error("Unexpected type of example_input. Supported types torch.Tensor, np.array or ov.Tensor. "
"Got {}".format(type(tensor)))
def get_torch_dtype(dtype):
import torch
ov_str_to_torch = {
@@ -56,7 +45,7 @@ def get_torch_dtype(dtype):
"f32": torch.float32,
"f64": torch.float64,
"i8": torch.int8,
"i16":torch.int16,
"i16": torch.int16,
"i32": torch.int32,
"i64": torch.int64,
"u8": torch.uint8,
@@ -74,7 +63,7 @@ def get_torch_dtype(dtype):
if str_dtype is None:
raise Error(f"Unexpected data type '{dtype}' for input")
return str_dtype
raise Error(f"Unexpected data type for input. Supporteed torch.dtype, numpy.dtype, ov.Type and str. Got {type(dtype)}")
raise Error(f"Unexpected data type for input. Supported torch.dtype, numpy.dtype, ov.Type and str. Got {type(dtype)}")
def prepare_torch_inputs(example_inputs, input_shape, input_info=None, allow_none=False):
@@ -118,67 +107,3 @@ def prepare_torch_inputs(example_inputs, input_shape, input_info=None, allow_non
if not allow_none:
raise Error("Please provide input_shape or example_input for converting PyTorch model.")
return inputs
def convert_pytorch_to_onnx(model, input_shape, input_info, opset_version, example_inputs, output_dir):
import io
import torch
input_names = None
inputs = prepare_torch_inputs(example_inputs, input_shape, input_info)
dynamic_dims_dict = {}
if input_shape is not None and input_names is None:
input_names = ["input_{}".format(idx) for idx in range(len(input_shape))]
for shape_idx, shape in enumerate(input_shape):
dynamic_dims = get_dynamic_dims(shape)
if len(dynamic_dims) > 0:
dynamic_dims_dict[input_names[shape_idx]] = dynamic_dims
additional_params = {}
if len(dynamic_dims_dict) > 0:
additional_params.update({'dynamic_axes': dynamic_dims_dict})
if input_names is not None and len(input_names) > 0:
additional_params.update({'input_names': input_names})
if os.environ.get('SAVE_TO_BYTES_IO_ONNX_MODEL'):
model_onnx = io.BytesIO()
else:
model_onnx = get_onnx_temp_filename(output_dir)
if opset_version is not None:
additional_params.update({'opset_version': opset_version})
torch.onnx.export(model,
inputs,
model_onnx,
operator_export_type=torch.onnx.OperatorExportTypes.ONNX_FALLTHROUGH,
**additional_params)
return model_onnx
def convert_pytorch_via_onnx(args, example_inputs, cli_parser, framework, main_convert):
opset_version = None
if 'onnx_opset_version' in args and args['onnx_opset_version'] is not None:
opset_version = args['onnx_opset_version']
out_dir = args['output_dir'] if 'output_dir' in args else None
if os.environ.get('SAVE_TO_BYTES_IO_ONNX_MODEL'):
args['use_legacy_frontend'] = True
# these parameters used only on PyTorch to ONNX conversion,
# remove them before passing model to next step
args['example_input'] = None
args['onnx_opset_version'] = None
try:
model_onnx = convert_pytorch_to_onnx(args['input_model'],
parse_input_shapes(args),
args.get("input"),
opset_version,
example_inputs,
out_dir)
args['input_model'] = model_onnx
ov_model, argv = main_convert(cli_parser, framework, args, True)
except Exception as e:
raise e
finally:
remove_tmp_onnx_model(out_dir)
return ov_model, argv
@@ -2052,7 +2052,7 @@ class TestConvertModelParamsParsing(unittest.TestCase):
'MXNet-specific parameters:': {'input_symbol', 'nd_prefix_name', 'pretrained_model_name', 'save_params_from_nd',
'legacy_mxnet_model', 'enable_ssd_gluoncv'},
'Kaldi-specific parameters:': {'counts', 'remove_output_softmax', 'remove_memory'},
'PyTorch-specific parameters:': {'example_input', 'onnx_opset_version'}
'PyTorch-specific parameters:': {'example_input'}
}
params = get_mo_convert_params()