Parameter list and descriptions for mo.convert_model() method in docstring (#16459)

* Added convert_model() params docs.

* Added auto-generating of most cli params.

* Added auto-generating of cli params.

* Small correction.

* Removed wrong change.

* Corrected default values.

* Fixed errors, added tests.

* Small correction.

* Corrected params descriptions, moved cli specific params to separate file.

* Moved params specifics to utils/help.py.
This commit is contained in:
Anastasiia Pnevskaia
2023-04-05 14:48:13 +04:00
committed by GitHub
parent 837f5a7d53
commit 4098434233
10 changed files with 752 additions and 559 deletions
@@ -0,0 +1,7 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from openvino.tools.mo import convert_model
if __name__ == "__main__":
convert_model(help=True)
@@ -0,0 +1,39 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import sys
import unittest
from openvino.tools.mo import mo
from openvino.tools.mo.utils.cli_parser import get_mo_convert_params
from pathlib import Path
from common.utils.common_utils import shell
class TestSubprocessMoConvert(unittest.TestCase):
def test_mo_convert(self):
mo_convert_params = get_mo_convert_params()
# Test cli tool help
mo_path = Path(mo.__file__).parent
mo_runner = mo_path.joinpath('main.py').as_posix()
params = [sys.executable, mo_runner, "--help"]
_, mo_output, _ = shell(params)
# We don't expect PyTorch specific parameters to be in help message of the MO tool.
for group in mo_convert_params:
if group == 'Pytorch-specific parameters:':
continue
for param_name in group:
assert param_name in mo_output
# Test Python API help
mo_help_file = os.path.join(os.path.dirname(__file__), "mo_convert_help.py")
params = [sys.executable, mo_help_file]
_, mo_output, _ = shell(params)
for group in mo_convert_params:
for param_name in group:
assert param_name in mo_output
+1
View File
@@ -1036,6 +1036,7 @@ openvino/tools/mo/utils/find_inputs.py
openvino/tools/mo/utils/get_ov_update_message.py
openvino/tools/mo/utils/graph.py
openvino/tools/mo/utils/guess_framework.py
openvino/tools/mo/utils/help.py
openvino/tools/mo/utils/ie_version.py
openvino/tools/mo/utils/import_extensions.py
openvino/tools/mo/utils/ir_engine/__init__.py
+303 -11
View File
@@ -1,9 +1,11 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import pathlib
from collections import namedtuple
from typing import Any
from openvino.frontend import FrontEndManager
from openvino.runtime import PartialShape, Shape, Layout
from openvino.tools.mo.convert_impl import _convert
from openvino.tools.mo.utils.cli_parser import get_all_cli_parser
@@ -13,12 +15,83 @@ InputCutInfo = namedtuple("InputInfo", ["name", "shape", "type", "value"])
LayoutMap = namedtuple("LayoutMap", ["source_layout", "target_layout"])
def convert_model(input_model=None, **args):
def convert_model(
input_model: [str, pathlib.Path, Any] = None,
# Optional parameters
help: bool = False,
framework: [str] = None,
# Framework-agnostic parameters
input: [str, list, tuple, InputCutInfo] = None,
output: [str, list] = None,
input_shape: [str, PartialShape, Shape, list] = None,
batch: int = None,
mean_values: [str, dict, list] = (),
scale_values: [str, dict, list] = (),
scale: [str, float] = None,
reverse_input_channels: bool = False,
source_layout: [str, Layout, dict] = (),
target_layout: [str, Layout, dict] = (),
layout: [str, Layout, LayoutMap, list, dict] = (),
compress_to_fp16: bool = True,
extensions: [str, pathlib.Path, list, Any] = None,
transform: [str, list, tuple] = "",
transformations_config: [str, pathlib.Path] = None,
silent: bool = True,
log_level: str = 'ERROR',
version: bool = None,
progress: bool = False,
stream_output: bool = False,
# PyTorch-specific parameters:
example_input: Any = None,
onnx_opset_version: int = None,
# TensorFlow*-specific parameters
input_model_is_text: bool = None,
input_checkpoint: [str, pathlib.Path] = None,
input_meta_graph: [str, pathlib.Path] = None,
saved_model_dir: [str, pathlib.Path] = None,
saved_model_tags: [str, list] = None,
tensorflow_custom_operations_config_update: [str, pathlib.Path] = None,
tensorflow_object_detection_api_pipeline_config: [str, pathlib.Path] = None,
tensorboard_logdir: [str, pathlib.Path] = None,
tensorflow_custom_layer_libraries: [str, pathlib.Path] = None,
# MXNet-specific parameters:
input_symbol: [str, pathlib.Path] = None,
nd_prefix_name: str = None,
pretrained_model_name: str = None,
save_params_from_nd: bool = None,
legacy_mxnet_model: bool = None,
enable_ssd_gluoncv: bool = False,
# Caffe*-specific parameters:
input_proto: [str, pathlib.Path] = None,
caffe_parser_path: [str, pathlib.Path] = os.path.join(os.path.dirname(__file__), 'front', 'caffe', 'proto'),
k: [str, pathlib.Path] = os.path.join(os.path.dirname(__file__), 'front', 'caffe', 'CustomLayersMapping.xml'),
disable_omitting_optional: bool = False,
enable_flattening_nested_params: bool = False,
# Kaldi-specific parameters:
counts: [str, pathlib.Path] = None,
remove_output_softmax: bool = False,
remove_memory: bool = False,
**args
):
"""
Converts the model from original framework to OpenVino Model.
Args:
input_model:
:param help:
Print available parameters.
:param framework:
Name of the framework used to train the input model.
Framework-agnostic parameters:
:param input_model:
Model object in original framework (PyTorch, Tensorflow) or path to model file.
Tensorflow*: a file with a pre-trained model (binary or text .pb file after freezing).
Caffe*: a model proto file with model weights
@@ -43,17 +116,236 @@ def convert_model(input_model=None, **args):
tf.train.checkpoint
tf.python.training.tracking.base.Trackable for case when it is output from tf.saved_model.load()
Run convert(help=true) to list all available parameters.
:param input:
Input can be set by passing a list of InputCutInfo objects or by a list
of tuples. Each tuple should contain input name and optionally input
type or input shape. Example: input=("op_name", PartialShape([-1,
3, 100, 100]), Type(np.float32)). Alternatively input can be set by
a string or list of strings of the following format. Quoted list of comma-separated
input nodes names with shapes, data types, and values for freezing.
The order of inputs in converted model is the same as order of specified
operation names. The shape and value are specified as comma-separated
lists. The data type of input node is specified in braces and can have
one of the values: f64 (float64), f32 (float32), f16 (float16), i64
(int64), i32 (int32), u8 (uint8), boolean (bool). Data type is optional.
If it's not specified explicitly then there are two options: if input
node is a parameter, data type is taken from the original node dtype,
if input node is not a parameter, data type is set to f32. Example, to set
`input_1` with shape [1,100], and Parameter node `sequence_len` with
scalar input with value `150`, and boolean input `is_training` with
`False` value use the following format: "input_1[1,100],sequence_len->150,is_training->False".
Another example, use the following format to set input port 0 of the node
`node_name1` with the shape [3,4] as an input node and freeze output
port 1 of the node `node_name2` with the value [20,15] of the int32 type
and shape [2]: "0:node_name1[3,4],node_name2:1[2]{i32}->[20,15]".
:param output:
The name of the output operation of the model or list of names. For TensorFlow*,
do not add :0 to this name.The order of outputs in converted model is the
same as order of specified operation names.
:param input_shape:
Input shape(s) that should be fed to an input node(s) of the model. Input
shapes can be defined by passing a list of objects of type PartialShape,
Shape, [Dimension, ...] or [int, ...] or by a string of the following
format. Shape is defined as a comma-separated list of integer numbers
enclosed in parentheses or square brackets, for example [1,3,227,227]
or (1,227,227,3), where the order of dimensions depends on the framework
input layout of the model. For example, [N,C,H,W] is used for ONNX* models
and [N,H,W,C] for TensorFlow* models. The shape can contain undefined
dimensions (? or -1) and should fit the dimensions defined in the input
operation of the graph. Boundaries of undefined dimension can be specified
with ellipsis, for example [1,1..10,128,128]. One boundary can be
undefined, for example [1,..100] or [1,3,1..,1..]. If there are multiple
inputs in the model, --input_shape should contain definition of shape
for each input separated by a comma, for example: [1,3,227,227],[2,4]
for a model with two inputs with 4D and 2D shapes. Alternatively, specify
shapes with the --input option.
:param batch:
Input batch size
:param mean_values:
Mean values to be used for the input image per channel. Mean values can
be set by passing a dictionary, where key is input name and value is mean
value. For example mean_values={'data':[255,255,255],'info':[255,255,255]}.
Or mean values can be set by a string of the following format. Values to
be provided in the (R,G,B) or [R,G,B] format. Can be defined for desired
input of the model, for example: "--mean_values data[255,255,255],info[255,255,255]".
The exact meaning and order of channels depend on how the original model
was trained.
:param scale_values:
Scale values to be used for the input image per channel. Scale values
can be set by passing a dictionary, where key is input name and value is
scale value. For example scale_values={'data':[255,255,255],'info':[255,255,255]}.
Or scale values can be set by a string of the following format. Values
are provided in the (R,G,B) or [R,G,B] format. Can be defined for desired
input of the model, for example: "--scale_values data[255,255,255],info[255,255,255]".
The exact meaning and order of channels depend on how the original model
was trained. If both --mean_values and --scale_values are specified,
the mean is subtracted first and then scale is applied regardless of
the order of options in command line.
:param scale:
All input values coming from original network inputs will be divided
by this value. When a list of inputs is overridden by the --input parameter,
this scale is not applied for any input that does not match with the original
input of the model. If both --mean_values and --scale are specified,
the mean is subtracted first and then scale is applied regardless of
the order of options in command line.
:param reverse_input_channels:
Switch the input channels order from RGB to BGR (or vice versa). Applied
to original inputs of the model if and only if a number of channels equals
3. When --mean_values/--scale_values are also specified, reversing
of channels will be applied to user's input data first, so that numbers
in --mean_values and --scale_values go in the order of channels used
in the original model. In other words, if both options are specified,
then the data flow in the model looks as following: Parameter -> ReverseInputChannels
-> Mean apply-> Scale apply -> the original body of the model.
:param source_layout:
Layout of the input or output of the model in the framework. Layout can
be set by passing a dictionary, where key is input name and value is LayoutMap
object. Or layout can be set by string of the following format. Layout
can be specified in the short form, e.g. nhwc, or in complex form, e.g.
"[n,h,w,c]". Example for many names: "in_name1([n,h,w,c]),in_name2(nc),out_name1(n),out_name2(nc)".
Layout can be partially defined, "?" can be used to specify undefined
layout for one dimension, "..." can be used to specify undefined layout
for multiple dimensions, for example "?c??", "nc...", "n...c", etc.
:param target_layout:
Same as --source_layout, but specifies target layout that will be in
the model after processing by ModelOptimizer.
:param layout:
Combination of --source_layout and --target_layout. Can't be used
with either of them. If model has one input it is sufficient to specify
layout of this input, for example --layout nhwc. To specify layouts
of many tensors, names must be provided, for example: --layout "name1(nchw),name2(nc)".
It is possible to instruct ModelOptimizer to change layout, for example:
--layout "name1(nhwc->nchw),name2(cn->nc)".
Also "*" in long layout form can be used to fuse dimensions, for example "[n,c,...]->[n*c,...]".
:param compress_to_fp16:
If the original model has FP32 weights or biases, they are compressed
to FP16. All intermediate data is kept in original precision. Option
can be specified alone as "--compress_to_fp16", or explicit True/False
values can be set, for example: "--compress_to_fp16=False", or "--compress_to_fp16=True"
:param extensions:
Paths to libraries (.so or .dll) with extensions, comma-separated
list of paths, objects derived from BaseExtension class or lists of
objects. For the legacy MO path (if `--use_legacy_frontend` is used),
a directory or a comma-separated list of directories with extensions
are supported. To disable all extensions including those that are placed
at the default location, pass an empty string.
:param transform:
Apply additional transformations. 'transform' can be set by a list
of tuples, where the first element is transform name and the second element
is transform parameters. For example: [('LowLatency2', {{'use_const_initializer':
False}}), ...]"--transform transformation_name1[args],transformation_name2..."
where [args] is key=value pairs separated by semicolon. Examples:
"--transform LowLatency2" or
"--transform Pruning" or
"--transform LowLatency2[use_const_initializer=False]" or
"--transform "MakeStateful[param_res_names=
{'input_name_1':'output_name_1','input_name_2':'output_name_2'}]""
Available transformations: "LowLatency2", "MakeStateful", "Pruning"
:param transformations_config:
Use the configuration file with transformations description or pass
object derived from BaseExtension class. Transformations file can
be specified as relative path from the current directory, as absolute
path or as relative path from the mo root directory.
:param silent:
Prevent any output messages except those that correspond to log level
equals ERROR, that can be set with the following option: --log_level.
By default, log level is already ERROR.
:param log_level:
Logger level of logging massages from MO.
Expected one of ['CRITICAL', 'ERROR', 'WARN', 'WARNING', 'INFO', 'DEBUG', 'NOTSET'].
:param version:
Version of Model Optimizer
:param progress:
Enable model conversion progress display.
:param stream_output:
Switch model conversion progress display to a multiline mode.
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:
TensorFlow*: treat the input model file as a text protobuf format. If
not specified, the Model Optimizer treats it as a binary file by default.
:param input_checkpoint:
TensorFlow*: variables file to load.
:param input_meta_graph:
Tensorflow*: a file with a meta-graph of the model before freezing
:param saved_model_dir:
TensorFlow*: directory with a model in SavedModel format of TensorFlow
1.x or 2.x version.
:param saved_model_tags:
Group of tag(s) of the MetaGraphDef to load, in string format, separated
by ','. For tag-set contains multiple tags, all tags must be passed in.
:param tensorflow_custom_operations_config_update:
TensorFlow*: update the configuration file with node name patterns
with input/output nodes information.
:param tensorflow_object_detection_api_pipeline_config:
TensorFlow*: path to the pipeline configuration file used to generate
model created with help of Object Detection API.
:param tensorboard_logdir:
TensorFlow*: dump the input graph to a given directory that should be
used with TensorBoard.
:param tensorflow_custom_layer_libraries:
TensorFlow*: comma separated list of shared libraries with TensorFlow*
custom operations implementation.
MXNet-specific parameters:
:param input_symbol:
Symbol file (for example, model-symbol.json) that contains a topology
structure and layer attributes
:param nd_prefix_name:
Prefix name for args.nd and argx.nd files.
:param pretrained_model_name:
Name of a pretrained MXNet model without extension and epoch number.
This model will be merged with args.nd and argx.nd files
:param save_params_from_nd:
Enable saving built parameters file from .nd files
:param legacy_mxnet_model:
Enable MXNet loader to make a model compatible with the latest MXNet
version. Use only if your model was trained with MXNet version lower
than 1.0.0
:param enable_ssd_gluoncv:
Enable pattern matchers replacers for converting gluoncv ssd topologies.
Caffe*-specific parameters:
:param input_proto:
Deploy-ready prototxt file that contains a topology structure and
layer attributes
:param caffe_parser_path:
Path to Python Caffe* parser generated from caffe.proto
:param k:
Path to CustomLayersMapping.xml to register custom layers
:param disable_omitting_optional:
Disable omitting optional attributes to be used for custom layers.
Use this option if you want to transfer all attributes of a custom layer
to IR. Default behavior is to transfer the attributes with default values
and the attributes defined by the user to IR.
:param enable_flattening_nested_params:
Enable flattening optional params to be used for custom layers. Use
this option if you want to transfer attributes of a custom layer to IR
with flattened nested parameters. Default behavior is to transfer
the attributes without flattening nested parameters.
Kaldi-specific parameters:
:param counts:
Path to the counts file
:param remove_output_softmax:
Removes the SoftMax layer that is the output layer
:param remove_memory:
Removes the Memory layer and use additional inputs outputs instead
Returns:
openvino.runtime.Model
"""
args.update({'input_model': input_model})
params = locals()
logger_state = get_logger_state()
cli_parser = get_all_cli_parser(FrontEndManager())
framework = None if 'framework' not in args else args['framework']
ov_model, _ = _convert(cli_parser, framework, args)
del params['args']
params.update(args)
cli_parser = get_all_cli_parser()
ov_model, _ = _convert(cli_parser, framework, params)
restore_logger_state(logger_state)
return ov_model
+35 -25
View File
@@ -31,7 +31,7 @@ from openvino.tools.mo.utils.cli_parser import check_available_transforms, \
get_common_cli_options, get_freeze_placeholder_values, get_kaldi_cli_options, get_layout_values, \
get_mean_scale_dictionary, get_mxnet_cli_options, get_onnx_cli_options, \
get_placeholder_shapes, get_tf_cli_options, parse_transform, parse_tuple_pairs, \
mo_convert_params, get_model_name_from_args, depersonalize
get_model_name_from_args, depersonalize, get_mo_convert_params
from openvino.tools.mo.utils.error import Error
from openvino.tools.mo.utils.find_ie_version import find_ie_version
@@ -131,6 +131,8 @@ def print_argv(argv: argparse.Namespace, is_caffe: bool, is_tf: bool, is_mxnet:
def arguments_post_parsing(argv: argparse.Namespace):
use_legacy_frontend = argv.use_legacy_frontend
use_new_frontend = argv.use_new_frontend
if argv.extensions is None:
argv.extensions = [import_extensions.default_path()]
if use_new_frontend and use_legacy_frontend:
raise Error('Options --use_new_frontend and --use_legacy_frontend must not be used simultaneously '
@@ -608,11 +610,21 @@ def driver(argv: argparse.Namespace, non_default_params: dict):
def args_dict_to_list(cli_parser, **kwargs):
# This method is needed to prepare args from convert_model() for args_parse().
# The method will not be needed when cli_parser checks are moved from cli_parser to a separate pass.
import inspect
from openvino.tools.mo import convert_model
signature = inspect.signature(convert_model)
result = []
for key, value in kwargs.items():
if value is not None and cli_parser.get_default(key) != value:
if value is None:
continue
if key in signature.parameters and signature.parameters[key].default == value:
continue
if cli_parser.get_default(key) == value:
continue
# skip parser checking for non str objects
if not isinstance(value, str):
if not isinstance(value, (str, bool)):
continue
result.append('--{}'.format(key))
if not isinstance(value, bool):
@@ -623,10 +635,17 @@ def args_dict_to_list(cli_parser, **kwargs):
def get_non_default_params(argv, cli_parser):
import numbers
import inspect
from openvino.tools.mo import convert_model
signature = inspect.signature(convert_model)
# make dictionary with parameters which have non-default values to be serialized in IR in rt_info
non_default_params = {}
for arg, arg_value in vars(argv).items():
if arg_value != cli_parser.get_default(arg):
if arg in signature.parameters and arg_value == signature.parameters[arg].default:
continue
if arg_value == cli_parser.get_default(arg):
continue
value = depersonalize(arg_value, arg)
# Skip complex classes in params to prevent
# serializing it to rt_info
@@ -637,7 +656,7 @@ def get_non_default_params(argv, cli_parser):
def params_to_string(**kwargs):
all_params = {}
for key, value in mo_convert_params.items():
for key, value in get_mo_convert_params().items():
all_params.update(value)
for key, value in kwargs.items():
@@ -649,7 +668,7 @@ def params_to_string(**kwargs):
def add_line_breaks(text: str, char_num: int, line_break: str):
words = text.split(" ")
words = text.replace('\n', "\n ").split(" ")
cnt = 0
for i, w in enumerate(words):
cnt += len(w)
@@ -664,26 +683,12 @@ def add_line_breaks(text: str, char_num: int, line_break: str):
def show_mo_convert_help():
mo_convert_params = get_mo_convert_params()
for group_name, group in mo_convert_params.items():
if group_name == "optional":
print("optional arguments:")
elif group_name == "fw_agnostic":
print("Framework-agnostic parameters:")
elif group_name == "tf":
print("TensorFlow*-specific parameters:")
elif group_name == "caffe":
print("Caffe*-specific parameters:")
elif group_name == "mxnet":
print("Mxnet-specific parameters:")
elif group_name == "kaldi":
print("Kaldi-specific parameters:")
elif group_name == "pytorch":
print("Pytorch-specific parameters:")
else:
raise Error("Unknown parameters group {}.".format(group_name))
print(group_name)
for param_name in group:
param_data = group[param_name]
text = param_data.description.format(param_data.possible_types_python_api)
text = param_data.description.replace(" ", '')
text = add_line_breaks(text, 56, "\n\t\t\t")
print(" --{} {}".format(param_name, text))
print()
@@ -708,7 +713,7 @@ def pack_params_to_args_namespace(args: dict, cli_parser: argparse.ArgumentParse
# get list of all available params for convert_model()
all_params = {}
for key, value in mo_convert_params.items():
for key, value in get_mo_convert_params().items():
all_params.update(value)
# check that there are no unknown params provided
@@ -760,7 +765,13 @@ def _convert(cli_parser: argparse.ArgumentParser, framework, args):
argv = pack_params_to_args_namespace(args, cli_parser)
argv.feManager = FrontEndManager()
frameworks = list(set(['tf', 'caffe', 'mxnet', 'kaldi', 'onnx'] + (get_available_front_ends(argv.feManager)
if argv.feManager else [])))
framework = argv.framework if hasattr(argv, 'framework') and argv.framework is not None else framework
if framework is not None:
assert framework in frameworks, "error: argument --framework: invalid choice: '{}'. " \
"Expected one of {}.".format(framework, frameworks)
setattr(argv, 'framework', framework)
# send telemetry with params info
@@ -784,7 +795,6 @@ def _convert(cli_parser: argparse.ArgumentParser, framework, args):
else:
argv.framework = model_framework
argv.feManager = FrontEndManager()
ov_model, legacy_path = driver(argv, {"conversion_parameters": non_default_params})
# add MO meta data to model
+1 -1
View File
@@ -96,4 +96,4 @@ def main(cli_parser: argparse.ArgumentParser, framework=None):
if __name__ == "__main__":
from openvino.tools.mo.utils.cli_parser import get_all_cli_parser
sys.exit(main(get_all_cli_parser(FrontEndManager()), None))
sys.exit(main(get_all_cli_parser(), None))
+1 -1
View File
@@ -10,4 +10,4 @@ from openvino.frontend import FrontEndManager # pylint: disable=no-name-in-modu
if __name__ == "__main__":
from openvino.tools.mo.main import main
sys.exit(main(get_all_cli_parser(FrontEndManager()), 'paddle'))
sys.exit(main(get_all_cli_parser(), 'paddle'))
+148 -505
View File
@@ -13,6 +13,7 @@ from pathlib import Path
from operator import xor
from typing import List, Union
import numbers
import inspect
import numpy as np
from openvino.runtime import Layout, PartialShape, Dimension, Shape, Type
@@ -21,10 +22,10 @@ import openvino
from openvino.tools.mo.front.extractor import split_node_in_port
from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
from openvino.tools.mo.utils import import_extensions
from openvino.tools.mo.utils.error import Error
from openvino.tools.mo.utils.utils import refer_to_faq_msg, get_mo_root_dir
from openvino.tools.mo.utils.version import get_version
from openvino.tools.mo.utils.help import get_convert_model_help_specifics, get_to_string_methods_for_params
def extension_path_to_str_or_extensions_class(extension):
@@ -46,7 +47,7 @@ def transformations_config_to_str(value):
def extensions_to_str_or_extensions_class(extensions):
if extensions is None:
return [import_extensions.default_path()]
return None
extensions_list = []
if isinstance(extensions, str):
extensions_list = extensions.split(',')
@@ -415,300 +416,67 @@ def transform_param_to_str(value):
ParamDescription = namedtuple("ParamData",
["description", "possible_types_command_line", "possible_types_python_api", "to_string"])
mo_convert_params = {
'optional':
{
'help': ParamDescription(
'Print available parameters.', '', '', None),
'framework': ParamDescription(
'Name of the framework used to train the input model.', '', '', None),
},
'fw_agnostic':
{
'input_model': ParamDescription(
'{} Tensorflow*: a file with a pre-trained model ' +
' (binary or text .pb file after freezing).\n' +
' Caffe*: a model proto file with model weights', '',
'Model object in original framework (PyTorch, Tensorflow) or path to model file. \n' +
'Supported object formats of input model:\n PyTorch - torch.nn.Module, torch.jit.ScriptModule, torch.jit.ScriptFunction' +
'TF - tf.compat.v1.GraphDef, tf.compat.v1.wrap_function, tf.compat.v1.session\n ' +
'TF2 / Keras - tf.keras.Model, tf.keras.layers.Layer, tf.function, tf.Module, tf.train.checkpoint, ' +
'tf.python.training.tracking.base.Trackable for case when it is output from tf.saved_model.load().\n' +
'File formats examples:\n',
path_to_str_or_object),
'model_name': ParamDescription(
'Model_name parameter passed to the final create_ir transform. ' +
'This parameter is used to name ' +
'a network in a generated IR and output .xml/.bin files.', '', '', None),
'input_shape': ParamDescription(
'Input shape(s) that should be fed to an input node(s) of the model. {}'
'Shape is defined as a comma-separated list of integer numbers enclosed in '
'parentheses or square brackets, for example [1,3,227,227] or (1,227,227,3), where '
'the order of dimensions depends on the framework input layout of the model. '
'For example, [N,C,H,W] is used for ONNX* models and [N,H,W,C] for TensorFlow* '
'models. The shape can contain undefined dimensions (? or -1) and '
'should fit the dimensions defined in the input '
'operation of the graph. Boundaries of undefined dimension can be specified with '
'ellipsis, for example [1,1..10,128,128]. One boundary can be undefined, for '
'example [1,..100] or [1,3,1..,1..]. If there are multiple inputs in the model, '
'--input_shape should contain definition of shape for each input separated by a '
'comma, for example: [1,3,227,227],[2,4] for a model with two inputs with 4D and 2D '
'shapes. Alternatively, specify shapes with the --input option.', '',
'Input shapes can be defined by passing a list of objects of type '
'PartialShape, Shape, [Dimension, ...] or [int, ...] or by a string '
'of the following format. ', input_shape_to_str),
'scale': ParamDescription(
'All input values coming from original network inputs will be ' +
'divided by this ' +
'value. When a list of inputs is overridden by the --input ' +
'parameter, this scale ' +
'is not applied for any input that does not match with ' +
'the original input of the model. ' +
'If both --mean_values and --scale are specified, ' +
'the mean is subtracted first and then scale is applied ' +
'regardless of the order of options in command line.', '', '', None),
'reverse_input_channels': ParamDescription(
'Switch the input channels order from RGB to BGR (or vice versa). Applied to '
'original inputs of the model if and only if a number of channels equals 3. '
'When --mean_values/--scale_values are also specified, reversing of channels will '
'be applied to user\'s input data first, so that numbers in --mean_values '
'and --scale_values go in the order of channels used in the original model. '
'In other words, if both options are specified, then the data flow in the model '
'looks as following: '
'Parameter -> ReverseInputChannels -> Mean apply-> Scale apply -> the original body of the model.',
'', '', None),
'log_level': ParamDescription(
'Logger level', '', '', None),
'input': ParamDescription(
'{}Quoted list of comma-separated input nodes names with shapes, data types, '
'and values for freezing. The order of inputs in converted model is the same as '
'order of specified operation names. The shape and value are specified as comma-separated '
'lists. The data type of input node is specified in braces and '
'can have one of the values: f64 (float64), f32 (float32), f16 (float16), '
'i64 (int64), i32 (int32), u8 (uint8), boolean (bool). Data type is optional. '
'If it\'s not specified explicitly then there are two options: '
'if input node is a parameter, data type is taken from the original node dtype, '
'if input node is not a parameter, data type is set to f32. '
'Example, to set `input_1` with shape [1,100], and Parameter node `sequence_len` '
'with scalar input with value `150`, and boolean input `is_training` with '
'`False` value use the following format: '
'"input_1[1,100],sequence_len->150,is_training->False". '
'Another example, use the following format to set input port 0 of the node '
'`node_name1` with the shape [3,4] as an input node and freeze output port 1 '
'of the node `node_name2` with the value [20,15] of the int32 type and shape [2]: '
'"0:node_name1[3,4],node_name2:1[2]{{i32}}->[20,15]".', '',
'Input can be set by passing a list of InputCutInfo objects or by a list of tuples. '
'Each tuple should contain input name and optionally input type or input shape. '
'Example: input=("op_name", PartialShape([-1, 3, 100, 100]), Type(np.float32)). '
'Alternatively input can be set by a string or list of strings of the following format. ',
input_to_str),
'output': ParamDescription(
'The name of the output operation of the model or list of names. ' +
'For TensorFlow*, do not add :0 to this name.'
'The order of outputs in converted model is the same as order of '
'specified operation names.', '', '', str_list_to_str),
'mean_values': ParamDescription(
'Mean values to be used for the input image per channel. {}' +
'Values to be provided in the (R,G,B) or [R,G,B] format. ' +
'Can be defined for desired input of the model, for example: ' +
'"--mean_values data[255,255,255],info[255,255,255]". ' +
'The exact meaning and order ' +
'of channels depend on how the original model was trained.', '',
'Mean values can be set by passing a dictionary, '
'where key is input name and value is mean value. '
'For example mean_values={\'data\':[255,255,255],\'info\':[255,255,255]}. '
'Or mean values can be set by a string of the following format. ',
mean_scale_value_to_str),
'scale_values': ParamDescription(
'Scale values to be used for the input image per channel. {}' +
'Values are provided in the (R,G,B) or [R,G,B] format. ' +
'Can be defined for desired input of the model, for example: ' +
'"--scale_values data[255,255,255],info[255,255,255]". ' +
'The exact meaning and order ' +
'of channels depend on how the original model was trained. ' +
'If both --mean_values and --scale_values are specified, ' +
'the mean is subtracted first and then scale is applied ' +
'regardless of the order of options in command line.', '',
'Scale values can be set by passing a dictionary, '
'where key is input name and value is scale value. '
'For example scale_values={\'data\':[255,255,255],\'info\':[255,255,255]}. '
'Or scale values can be set by a string of the following format. ',
mean_scale_value_to_str),
'source_layout': ParamDescription(
'Layout of the input or output of the model in the framework. {}Layout can'
' be specified in the short form, e.g. nhwc, or in complex form, e.g. "[n,h,w,c]".'
' Example for many names: '
'"in_name1([n,h,w,c]),in_name2(nc),out_name1(n),out_name2(nc)". Layout can be '
'partially defined, "?" can be used to specify undefined layout for one dimension, '
'"..." can be used to specify undefined layout for multiple dimensions, for example '
'"?c??", "nc...", "n...c", etc.', '',
'Layout can be set by passing a dictionary, where key is input name and value is '
'LayoutMap object. Or layout can be set by string of the following format. ',
source_target_layout_to_str),
'target_layout': ParamDescription(
'Same as --source_layout, but specifies target layout that will be in the model '
'after processing by ModelOptimizer.', '', '', source_target_layout_to_str),
'layout': ParamDescription(
'Combination of --source_layout and --target_layout. Can\'t be used with either of '
'them. If model has one input it is sufficient to specify layout of this input, for'
' example --layout nhwc. To specify layouts of many tensors, names must be provided,'
' for example: --layout "name1(nchw),name2(nc)". It is possible to instruct '
'ModelOptimizer to change layout, for example: '
'--layout "name1(nhwc->nchw),name2(cn->nc)". Also "*" in long layout form can be'
' used to fuse dimensions, for example "[n,c,...]->[n*c,...]".', '', '', layout_param_to_str),
'compress_to_fp16': ParamDescription(
'If the original model has FP32 weights or biases, they are compressed to FP16. '
'All intermediate data is kept in original precision. Option can be specified alone as "--compress_to_fp16", '
'or explicit True/False values can be set, for example: "--compress_to_fp16=False", or "--compress_to_fp16=True"',
'', '', None),
'transform': ParamDescription(
'Apply additional transformations. {}' +
'"--transform transformation_name1[args],transformation_name2..." ' +
'where [args] is key=value pairs separated by semicolon. ' +
'Examples:' +
' "--transform LowLatency2" or \n' +
' "--transform Pruning" or \n' +
' "--transform LowLatency2[use_const_initializer=False]" or \n' +
' "--transform \"MakeStateful[param_res_names=\n'
'{{\'input_name_1\':\'output_name_1\',\'input_name_2\':\'output_name_2\'}}]\"" ' +
'Available transformations: "LowLatency2", "MakeStateful", "Pruning"', 'Usage: ',
'\'transform\' can be set by a list of tuples, where the first element is '
'transform name and the second element is transform parameters. '
'For example: [(\'LowLatency2\', {{\'use_const_initializer\': False}}), ...]',
transform_param_to_str),
'extensions': ParamDescription(
"{} For the legacy MO path (if `--use_legacy_frontend` is used), "
"a directory or a comma-separated list of directories with extensions are supported. "
"To disable all extensions including those that are placed at the default location, "
"pass an empty string.",
"Paths or a comma-separated list of paths to libraries (.so or .dll) with extensions.",
"Paths to libraries (.so or .dll) with extensions, comma-separated list of paths, "
"objects derived from BaseExtension class or lists of objects.",
extensions_to_str_or_extensions_class),
'batch': ParamDescription(
'Input batch size', '', '', batch_to_int),
'silent': ParamDescription(
'Prevent any output messages except those that correspond to log level equals '
'ERROR, that can be set with the following option: --log_level. '
'By default, log level is already ERROR. ', '', '', None),
'version': ParamDescription(
"Version of Model Optimizer", '', '', None
),
'static_shape': ParamDescription(
'Enables IR generation for fixed input shape (folding `ShapeOf` operations and '
'shape-calculating sub-graphs to `Constant`). Changing model input shape using '
'the OpenVINO Runtime API in runtime may fail for such an IR.', '', '', None),
'progress': ParamDescription(
'Enable model conversion progress display.', '', '', None),
'stream_output': ParamDescription(
'Switch model conversion progress display to a multiline mode.', '', '', None),
'transformations_config': ParamDescription(
'Use the configuration file with transformations '
'description{}. Transformations file can be specified as relative path '
'from the current directory, as absolute path or as a'
'relative path from the mo root directory.', '',
' or pass object derived from BaseExtension class.',
transformations_config_to_str),
'use_new_frontend': ParamDescription(
'Force the usage of new Frontend of Model Optimizer for model conversion into IR. '
'The new Frontend is C++ based and is available for ONNX* and PaddlePaddle* models. '
'Model optimizer uses new Frontend for ONNX* and PaddlePaddle* by default that means '
'`--use_new_frontend` and `--use_legacy_frontend` options are not specified.', '', '', None),
'use_legacy_frontend': ParamDescription(
'Force the usage of legacy Frontend of Model Optimizer for model conversion into IR. '
'The legacy Frontend is Python based and is available for TensorFlow*, ONNX*, MXNet*, '
'Caffe*, and Kaldi* models.', '', '', None),
},
"caffe":
{
'input_proto': ParamDescription(
'Deploy-ready prototxt file that contains a topology structure ' +
'and layer attributes', '', '', path_to_str),
'caffe_parser_path': ParamDescription(
'Path to Python Caffe* parser generated from caffe.proto', '', '',
path_to_str),
'k': ParamDescription(
'Path to CustomLayersMapping.xml to register custom layers', '', '', path_to_str),
'disable_omitting_optional': ParamDescription(
'Disable omitting optional attributes to be used for custom layers. ' +
'Use this option if you want to transfer all attributes of a custom layer to IR. ' +
'Default behavior is to transfer the attributes with default values '
'and the attributes defined by the user to IR.',
'', '', None),
'enable_flattening_nested_params': ParamDescription(
'Enable flattening optional params to be used for custom layers. ' +
'Use this option if you want to transfer attributes of a custom layer to IR with flattened nested parameters. ' +
'Default behavior is to transfer the attributes without flattening nested parameters.', '', '', None),
},
"tf":
{
'input_model_is_text': ParamDescription(
'TensorFlow*: treat the input model file as a text protobuf format. If not specified, ' +
'the Model Optimizer treats it as a binary file by default.', '', '', None),
'input_checkpoint': ParamDescription(
'TensorFlow*: variables file to load.', '', '', path_to_str),
'input_meta_graph': ParamDescription(
'Tensorflow*: a file with a meta-graph of the model before freezing', '', '',
path_to_str),
'saved_model_dir': ParamDescription(
'TensorFlow*: directory with a model in SavedModel format '
'of TensorFlow 1.x or 2.x version.', '', '', path_to_str),
'saved_model_tags': ParamDescription(
"Group of tag(s) of the MetaGraphDef to load, in string format, separated by ','. "
"For tag-set contains multiple tags, all tags must be passed in.", '', '', str_list_to_str),
'tensorflow_custom_operations_config_update': ParamDescription(
'TensorFlow*: update the configuration file with node name patterns with input/output '
'nodes information.', '', '', path_to_str),
'tensorflow_object_detection_api_pipeline_config': ParamDescription(
'TensorFlow*: path to the pipeline configuration file used to generate model created '
'with help of Object Detection API.', '', '', path_to_str),
'tensorboard_logdir': ParamDescription(
'TensorFlow*: dump the input graph to a given directory that should be used with TensorBoard.', '', '',
path_to_str),
'tensorflow_custom_layer_libraries': ParamDescription(
'TensorFlow*: comma separated list of shared libraries with TensorFlow* custom '
'operations implementation.', '', '', path_to_str),
},
"mxnet":
{
'input_symbol': ParamDescription(
'Symbol file (for example, model-symbol.json) that contains a topology structure ' +
'and layer attributes', '', '', path_to_str),
'nd_prefix_name': ParamDescription(
"Prefix name for args.nd and argx.nd files.", '', '', None),
'pretrained_model_name': ParamDescription(
"Name of a pretrained MXNet model without extension and epoch number. "
"This model will be merged with args.nd and argx.nd files",
'', '', None),
'save_params_from_nd': ParamDescription(
"Enable saving built parameters file from .nd files", '', '', None),
'legacy_mxnet_model': ParamDescription(
"Enable MXNet loader to make a model compatible with the latest MXNet version. "
"Use only if your model was trained with MXNet version lower than 1.0.0",
'', '', None),
'enable_ssd_gluoncv': ParamDescription(
"Enable pattern matchers replacers for converting gluoncv ssd topologies.",
'', '', None),
},
"kaldi":
{
'counts': ParamDescription(
"Path to the counts file", '', '', path_to_str),
'remove_output_softmax': ParamDescription(
"Removes the SoftMax layer that is the output layer", '', '', None),
'remove_memory': ParamDescription(
"Removes the Memory layer and use additional inputs outputs instead", '', '',
None),
},
"pytorch":
{
'example_input': ParamDescription('Sample of model input in original framework. '
'For PyTorch it can be torch.Tensor.', '', '', None),
'onnx_opset_version': ParamDescription('Version of ONNX opset that is used for converting from PyTorch to ONNX.',
'', '', None),
}
}
["description", "cli_tool_description", "to_string"])
def get_mo_convert_params():
mo_convert_docs = openvino.tools.mo.convert_model.__doc__
mo_convert_params = {}
group = "Optional parameters:"
mo_convert_params[group] = {}
mo_convert_docs = mo_convert_docs[:mo_convert_docs.find('Returns:')]
while len(mo_convert_docs) > 0:
param_idx1 = mo_convert_docs.find(":param")
if param_idx1 == -1:
break
param_idx2 = mo_convert_docs.find(":", param_idx1+1)
param_name = mo_convert_docs[param_idx1+len(':param '):param_idx2]
param_description_idx = mo_convert_docs.find(":param", param_idx2+1)
param_description = mo_convert_docs[param_idx2+1: param_description_idx]
group_name_idx = param_description.rfind('\n\n')
group_name = ''
if group_name_idx != -1:
group_name = param_description[group_name_idx:].strip()
param_description = param_description[:group_name_idx]
param_description = param_description.strip()
mo_convert_params[group][param_name] = ParamDescription(param_description, "", None)
mo_convert_docs = mo_convert_docs[param_description_idx:]
if group_name != '':
mo_convert_params[group_name] = {}
group = group_name
# TODO: remove this when internal converting of params to string is removed
params_converted_to_string = get_to_string_methods_for_params()
params_with_paths = get_params_with_paths_list()
cli_tool_specific_descriptions = get_convert_model_help_specifics()
for group_name, param_group in mo_convert_params.items():
for param_name, d in param_group.items():
to_str_method = None
if param_name in params_converted_to_string:
to_str_method = params_converted_to_string[param_name]
elif param_name in params_with_paths:
to_str_method = path_to_str
cli_tool_description = None
if param_name in cli_tool_specific_descriptions:
cli_tool_description = cli_tool_specific_descriptions[param_name]
desc = ParamDescription(d.description,
cli_tool_description,
to_str_method)
mo_convert_params[group_name][param_name] = desc
return mo_convert_params
class DeprecatedStoreTrue(argparse.Action):
@@ -945,16 +713,70 @@ def writable_dir(path: str):
raise Error('The directory "{}" is not writable'.format(cur_path))
def add_args_by_description(args_group, params_description):
signature = inspect.signature(openvino.tools.mo.convert_model)
filepath_args = get_params_with_paths_list()
cli_tool_specific_descriptions = get_convert_model_help_specifics()
for param_name, param_description in params_description.items():
if param_name == 'help':
continue
cli_param_name = "--"+param_name
if cli_param_name not in args_group._option_string_actions:
# Get parameter specifics
param_specifics = cli_tool_specific_descriptions[param_name] if param_name in \
cli_tool_specific_descriptions else {}
help_text = param_specifics['description'] if 'description' in param_specifics \
else param_description.description
action = param_specifics['action'] if 'action' in param_specifics else None
param_type = param_specifics['type'] if 'type' in param_specifics else None
param_alias = param_specifics['aliases'] if 'aliases' in param_specifics else {}
param_version = param_specifics['version'] if 'version' in param_specifics else None
param_choices = param_specifics['choices'] if 'choices' in param_specifics else None
# Bool params common setting
if signature.parameters[param_name].annotation == bool and param_name != 'version':
args_group.add_argument(
cli_param_name, *param_alias,
type=check_bool if param_type is None else param_type,
nargs="?",
const=True,
help=help_text,
default=signature.parameters[param_name].default)
# File paths common setting
elif param_name in filepath_args:
action = action if action is not None else CanonicalizePathCheckExistenceAction
args_group.add_argument(
cli_param_name, *param_alias,
type=str if param_type is None else param_type,
action=action,
help=help_text,
default=signature.parameters[param_name].default)
# Other params
else:
additional_params = {}
if param_version is not None:
additional_params['version'] = param_version
if param_type is not None:
additional_params['type'] = param_type
if param_choices is not None:
additional_params['choices'] = param_choices
args_group.add_argument(
cli_param_name, *param_alias,
help=help_text,
default=signature.parameters[param_name].default,
action=action,
**additional_params
)
def get_common_cli_parser(parser: argparse.ArgumentParser = None):
if not parser:
parser = argparse.ArgumentParser()
common_group = parser.add_argument_group('Framework-agnostic parameters')
mo_convert_params_common = mo_convert_params['fw_agnostic']
# Common parameters
common_group.add_argument('--input_model', '-w', '-m',
help=mo_convert_params_common['input_model'].description,
action=CanonicalizePathCheckExistenceAction,
type=readable_file_or_dir)
mo_convert_params = get_mo_convert_params()
mo_convert_params_common = mo_convert_params['Framework-agnostic parameters:']
# Command line tool specific params
common_group.add_argument('--model_name', '-n',
help='Model_name parameter passed to the final create_ir transform. ' +
'This parameter is used to name ' +
@@ -965,90 +787,8 @@ def get_common_cli_parser(parser: argparse.ArgumentParser = None):
default=get_absolute_path('.'),
action=CanonicalizePathAction,
type=writable_dir)
common_group.add_argument('--input_shape',
help=mo_convert_params_common['input_shape'].description.format(
mo_convert_params_common['input_shape'].possible_types_command_line))
common_group.add_argument('--scale', '-s',
type=float,
help='All input values coming from original network inputs will be ' +
'divided by this ' +
'value. When a list of inputs is overridden by the --input ' +
'parameter, this scale ' +
'is not applied for any input that does not match with ' +
'the original input of the model.' +
'If both --mean_values and --scale are specified, ' +
'the mean is subtracted first and then scale is applied ' +
'regardless of the order of options in command line.')
common_group.add_argument('--reverse_input_channels',
help='Switch the input channels order from RGB to BGR (or vice versa). Applied to '
'original inputs of the model if and only if a number of channels equals 3. '
'When --mean_values/--scale_values are also specified, reversing of channels will '
'be applied to user\'s input data first, so that numbers in --mean_values '
'and --scale_values go in the order of channels used in the original model. '
'In other words, if both options are specified, then the data flow in the model '
'looks as following: Parameter -> ReverseInputChannels -> Mean apply-> Scale apply -> the original body of the model.',
action='store_true')
common_group.add_argument('--log_level',
help='Logger level',
choices=['CRITICAL', 'ERROR', 'WARN', 'WARNING', 'INFO',
'DEBUG', 'NOTSET'],
default='ERROR')
common_group.add_argument('--input',
help=mo_convert_params_common['input'].description.format(
mo_convert_params_common['input'].possible_types_command_line))
common_group.add_argument('--output',
help=mo_convert_params_common['output'].description.format(
mo_convert_params_common['output'].possible_types_command_line))
common_group.add_argument('--mean_values', '-ms',
help=mo_convert_params_common['mean_values'].description.format(
mo_convert_params_common['mean_values'].possible_types_command_line),
default=())
common_group.add_argument('--scale_values',
help=mo_convert_params_common['scale_values'].description.format(
mo_convert_params_common['scale_values'].possible_types_command_line),
default=())
common_group.add_argument('--source_layout',
help=mo_convert_params_common['source_layout'].description.format(
mo_convert_params_common['source_layout'].possible_types_command_line),
default=())
common_group.add_argument('--target_layout',
help=mo_convert_params_common['target_layout'].description.format(
mo_convert_params_common['target_layout'].possible_types_command_line),
default=())
common_group.add_argument('--layout',
help=mo_convert_params_common['layout'].description.format(
mo_convert_params_common['layout'].possible_types_command_line),
default=())
common_group.add_argument('--compress_to_fp16',
help=mo_convert_params_common['compress_to_fp16'].description,
type=check_bool,
nargs="?",
const=True,
default=True)
common_group.add_argument('--transform',
help=mo_convert_params_common['transform'].description.format(
mo_convert_params_common['transform'].possible_types_command_line),
default="")
# we use CanonicalizeDirCheckExistenceAction instead of readable_dirs to handle empty strings
common_group.add_argument("--extensions",
help=mo_convert_params_common['extensions'].description.format(
mo_convert_params_common['extensions'].possible_types_command_line),
default=[import_extensions.default_path()],
action=CanonicalizeExtensionsPathCheckExistenceAction,
type=readable_dirs_or_files_or_empty)
common_group.add_argument("--batch", "-b",
type=check_positive,
default=None,
help=mo_convert_params_common['batch'].description)
common_group.add_argument("--version",
action='version',
version='Version of Model Optimizer is: {}'.format(get_version()),
help=mo_convert_params_common['version'].description)
common_group.add_argument('--silent',
help=mo_convert_params_common['silent'].description,
type=check_bool,
default=True)
# Deprecated params
common_group.add_argument('--freeze_placeholder_with_value',
help='Replaces input layer with constant node with '
'provided value, for example: "node_name->True". '
@@ -1056,24 +796,22 @@ def get_common_cli_parser(parser: argparse.ArgumentParser = None):
'Use --input option to specify a value for freezing.',
default=None)
common_group.add_argument('--static_shape',
help=mo_convert_params_common['static_shape'].description,
help='Enables IR generation for fixed input shape (folding `ShapeOf` operations and '
'shape-calculating sub-graphs to `Constant`). Changing model input shape using '
'the OpenVINO Runtime API in runtime may fail for such an IR.',
action='store_true', default=False)
common_group.add_argument('--progress',
help=mo_convert_params_common['progress'].description,
action='store_true', default=False)
common_group.add_argument('--stream_output',
help=mo_convert_params_common['stream_output'].description,
action='store_true', default=False)
common_group.add_argument('--transformations_config',
help=mo_convert_params_common['transformations_config'].description.format(
mo_convert_params_common['transformations_config'].possible_types_command_line),
action=CanonicalizeTransformationPathCheckExistenceAction)
common_group.add_argument("--use_new_frontend",
help=mo_convert_params_common['use_new_frontend'].description,
help='Force the usage of new Frontend of Model Optimizer for model conversion into IR. '
'The new Frontend is C++ based and is available for ONNX* and PaddlePaddle* models. '
'Model optimizer uses new Frontend for ONNX* and PaddlePaddle* by default that means '
'`--use_new_frontend` and `--use_legacy_frontend` options are not specified.',
action='store_true', default=False)
common_group.add_argument("--use_legacy_frontend",
help=mo_convert_params_common['use_legacy_frontend'].description,
help='Force the usage of legacy Frontend of Model Optimizer for model conversion into IR. '
'The legacy Frontend is Python based and is available for TensorFlow*, ONNX*, MXNet*, '
'Caffe*, and Kaldi* models.',
action='store_true', default=False)
add_args_by_description(common_group, mo_convert_params_common)
return parser
@@ -1181,32 +919,8 @@ def get_caffe_cli_parser(parser: argparse.ArgumentParser = None):
get_common_cli_parser(parser=parser)
caffe_group = parser.add_argument_group('Caffe*-specific parameters')
mo_convert_params_caffe = mo_convert_params['caffe']
caffe_group.add_argument('--input_proto', '-d',
help=mo_convert_params_caffe['input_proto'].description,
type=str,
action=CanonicalizePathCheckExistenceAction)
caffe_group.add_argument('--caffe_parser_path',
help=mo_convert_params_caffe['caffe_parser_path'].description,
type=str,
default=os.path.join(os.path.dirname(__file__), os.pardir, 'front', 'caffe', 'proto'),
action=CanonicalizePathCheckExistenceAction)
caffe_group.add_argument('-k',
help=mo_convert_params_caffe['k'].description,
type=str,
default=os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'extensions',
'front', 'caffe',
'CustomLayersMapping.xml'),
action=CanonicalizePathCheckExistenceAction)
caffe_group.add_argument('--disable_omitting_optional',
help=mo_convert_params_caffe['disable_omitting_optional'].description,
action='store_true',
default=False)
caffe_group.add_argument('--enable_flattening_nested_params',
help=mo_convert_params_caffe['enable_flattening_nested_params'].description,
action='store_true',
default=False)
mo_convert_params_caffe = get_mo_convert_params()['Caffe*-specific parameters:']
add_args_by_description(caffe_group, mo_convert_params_caffe)
return parser
@@ -1221,39 +935,10 @@ def get_tf_cli_parser(parser: argparse.ArgumentParser = None):
if not parser:
parser = argparse.ArgumentParser(usage='%(prog)s [options]')
get_common_cli_parser(parser=parser)
mo_convert_params_tf = mo_convert_params['tf']
mo_convert_params_tf = get_mo_convert_params()['TensorFlow*-specific parameters:']
tf_group = parser.add_argument_group('TensorFlow*-specific parameters')
tf_group.add_argument('--input_model_is_text',
help=mo_convert_params_tf['input_model_is_text'].description,
action='store_true')
tf_group.add_argument('--input_checkpoint', type=str, default=None,
help=mo_convert_params_tf['input_checkpoint'].description,
action=CanonicalizePathCheckExistenceAction)
tf_group.add_argument('--input_meta_graph',
help=mo_convert_params_tf['input_meta_graph'].description,
action=CanonicalizePathCheckExistenceAction,
type=readable_file)
tf_group.add_argument('--saved_model_dir', default=None,
help=mo_convert_params_tf['saved_model_dir'].description,
action=CanonicalizePathCheckExistenceAction,
type=readable_dirs)
tf_group.add_argument('--saved_model_tags', type=str, default=None,
help=mo_convert_params_tf['saved_model_tags'].description)
tf_group.add_argument('--tensorflow_custom_operations_config_update',
help=mo_convert_params_tf['tensorflow_custom_operations_config_update'].description,
action=CanonicalizePathCheckExistenceAction)
tf_group.add_argument('--tensorflow_object_detection_api_pipeline_config',
help=mo_convert_params_tf['tensorflow_object_detection_api_pipeline_config'].description,
action=CanonicalizePathCheckExistenceAction)
tf_group.add_argument('--tensorboard_logdir',
help=mo_convert_params_tf['tensorboard_logdir'].description,
default=None,
action=CanonicalizePathCheckExistenceAction)
tf_group.add_argument('--tensorflow_custom_layer_libraries',
help=mo_convert_params_tf['tensorflow_custom_layer_libraries'].description,
default=None,
action=CanonicalizePathCheckExistenceAction)
add_args_by_description(tf_group, mo_convert_params_tf)
return parser
@@ -1269,29 +954,9 @@ def get_mxnet_cli_parser(parser: argparse.ArgumentParser = None):
parser = argparse.ArgumentParser(usage='%(prog)s [options]')
get_common_cli_parser(parser=parser)
mx_group = parser.add_argument_group('Mxnet-specific parameters')
mo_convert_params_mxnet = mo_convert_params['mxnet']
mx_group.add_argument('--input_symbol',
help=mo_convert_params_mxnet['input_symbol'].description,
type=str,
action=CanonicalizePathCheckExistenceAction)
mx_group.add_argument("--nd_prefix_name",
help=mo_convert_params_mxnet['nd_prefix_name'].description,
default=None)
mx_group.add_argument("--pretrained_model_name",
help=mo_convert_params_mxnet['pretrained_model_name'].description,
default=None)
mx_group.add_argument("--save_params_from_nd",
action='store_true',
help=mo_convert_params_mxnet['save_params_from_nd'].description)
mx_group.add_argument("--legacy_mxnet_model",
action='store_true',
help=mo_convert_params_mxnet['legacy_mxnet_model'].description)
mx_group.add_argument("--enable_ssd_gluoncv",
action='store_true',
help=mo_convert_params_mxnet['enable_ssd_gluoncv'].description,
default=False)
mx_group = parser.add_argument_group('MXNet-specific parameters')
mo_convert_params_mxnet = get_mo_convert_params()['MXNet-specific parameters:']
add_args_by_description(mx_group, mo_convert_params_mxnet)
return parser
@@ -1309,22 +974,8 @@ def get_kaldi_cli_parser(parser: argparse.ArgumentParser = None):
get_common_cli_parser(parser=parser)
kaldi_group = parser.add_argument_group('Kaldi-specific parameters')
mo_convert_params_kaldi = mo_convert_params['kaldi']
kaldi_group.add_argument("--counts",
help=mo_convert_params_kaldi['counts'].description,
default=None,
action=CanonicalizePathCheckExistenceIfNeededAction)
kaldi_group.add_argument("--remove_output_softmax",
help=mo_convert_params_kaldi['remove_output_softmax'].description,
action='store_true',
default=False)
kaldi_group.add_argument("--remove_memory",
help=mo_convert_params_kaldi['remove_memory'].description,
action='store_true',
default=False)
mo_convert_params_kaldi = get_mo_convert_params()['Kaldi-specific parameters:']
add_args_by_description(kaldi_group, mo_convert_params_kaldi)
return parser
@@ -1343,7 +994,7 @@ def get_onnx_cli_parser(parser: argparse.ArgumentParser = None):
return parser
def get_all_cli_parser(frontEndManager=None):
def get_all_cli_parser():
"""
Specifies cli arguments for Model Optimizer
@@ -1352,17 +1003,10 @@ def get_all_cli_parser(frontEndManager=None):
ArgumentParser instance
"""
parser = argparse.ArgumentParser(usage='%(prog)s [options]')
frameworks = list(set(['tf', 'caffe', 'mxnet', 'kaldi', 'onnx'] +
(get_available_front_ends(frontEndManager) if frontEndManager else [])))
parser.add_argument('--framework',
help='Name of the framework used to train the input model.',
type=str,
choices=frameworks)
mo_convert_params_optional = get_mo_convert_params()['Optional parameters:']
add_args_by_description(parser, mo_convert_params_optional)
get_common_cli_parser(parser=parser)
get_tf_cli_parser(parser=parser)
get_caffe_cli_parser(parser=parser)
get_mxnet_cli_parser(parser=parser)
@@ -2264,7 +1908,6 @@ def depersonalize(value: str, key: str):
dir_keys = [
'output_dir', 'extensions', 'saved_model_dir', 'tensorboard_logdir', 'caffe_parser_path'
]
if isinstance(value, list):
updated_value = []
for elem in value:
+164
View File
@@ -0,0 +1,164 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
def get_convert_model_help_specifics():
from openvino.tools.mo.utils.cli_parser import CanonicalizeTransformationPathCheckExistenceAction, \
CanonicalizePathCheckExistenceAction, CanonicalizeExtensionsPathCheckExistenceAction, \
CanonicalizePathCheckExistenceIfNeededAction, readable_file_or_dir, readable_dirs_or_files_or_empty, \
check_positive
from openvino.tools.mo.utils.version import get_version
return {
'input_model':
{'description':
'Tensorflow*: a file with a pre-trained model '
'(binary or text .pb file after freezing). '
'Caffe*: a model proto file with model weights.', 'action': CanonicalizePathCheckExistenceAction,
'type': readable_file_or_dir,
'aliases': {'-w', '-m'}},
'input_shape':
{'description':
'Input shape(s) that should be fed to an input node(s) '
'of the model. Shape is defined as a comma-separated '
'list of integer numbers enclosed in parentheses or '
'square brackets, for example [1,3,227,227] or '
'(1,227,227,3), where the order of dimensions depends '
'on the framework input layout of the model. For '
'example, [N,C,H,W] is used for ONNX* models and '
'[N,H,W,C] for TensorFlow* models. The shape can '
'contain undefined dimensions (? or -1) and should fit '
'the dimensions defined in the input operation of the '
'graph. Boundaries of undefined dimension can be '
'specified with ellipsis, for example '
'[1,1..10,128,128]. One boundary can be undefined, for '
'example [1,..100] or [1,3,1..,1..]. If there are '
'multiple inputs in the model, --input_shape should '
'contain definition of shape for each input separated '
'by a comma, for example: [1,3,227,227],[2,4] for a '
'model with two inputs with 4D and 2D shapes. '
'Alternatively, specify shapes with the --input option.'},
'input':
{'description':
'Quoted list of comma-separated input nodes names with '
'shapes, data types, and values for freezing. The order '
'of inputs in converted model is the same as order of '
'specified operation names. The shape and value are '
'specified as comma-separated lists. The data type of '
'input node is specified in braces and can have one of '
'the values: f64 (float64), f32 (float32), f16 '
'(float16), i64 (int64), i32 (int32), u8 (uint8), '
'boolean (bool). Data type is optional. If it\'s not '
'specified explicitly then there are two options: if '
'input node is a parameter, data type is taken from the '
'original node dtype, if input node is not a parameter, '
'data type is set to f32. Example, to set `input_1` '
'with shape [1,100], and Parameter node `sequence_len` '
'with scalar input with value `150`, and boolean input '
'`is_training` with `False` value use the following '
'format: \n '
'\"input_1[1,100],sequence_len->150,is_training->False\". '
'Another example, use the following format to set input '
'port 0 of the node `node_name1` with the shape [3,4] '
'as an input node and freeze output port 1 of the node '
'\"node_name2\" with the value [20,15] of the int32 type '
'and shape [2]: \n '
'\"0:node_name1[3,4],node_name2:1[2]{i32}->[20,15]\".'},
'mean_values':
{'description':
'Mean values to be used for the input image per '
'channel. Values to be provided in the (R,G,B) or '
'[R,G,B] format. Can be defined for desired input of '
'the model, for example: "--mean_values '
'data[255,255,255],info[255,255,255]". The exact '
'meaning and order of channels depend on how the '
'original model was trained.'},
'scale_values':
{'description':
'Scale values to be used for the input image per '
'channel. Values are provided in the (R,G,B) or [R,G,B] '
'format. Can be defined for desired input of the model, '
'for example: "--scale_values '
'data[255,255,255],info[255,255,255]". The exact '
'meaning and order of channels depend on how the '
'original model was trained. If both --mean_values and '
'--scale_values are specified, the mean is subtracted '
'first and then scale is applied regardless of the '
'order of options in command line.'},
'source_layout':
{'description':
'Layout of the input or output of the model in the '
'framework. Layout can be specified in the short form, '
'e.g. nhwc, or in complex form, e.g. \"[n,h,w,c]\". '
'Example for many names: \"in_name1([n,h,w,c]),in_name2('
'nc),out_name1(n),out_name2(nc)\". Layout can be '
'partially defined, \"?\" can be used to specify '
'undefined layout for one dimension, \"...\" can be used '
'to specify undefined layout for multiple dimensions, '
'for example \"?c??\", \"nc...\", \"n...c\", etc.'},
'transform':
{'description':
'Apply additional transformations. Usage: \"--transform '
'transformation_name1[args],transformation_name2...\" '
'where [args] is key=value pairs separated by '
'semicolon. Examples: \"--transform LowLatency2\" or \"--'
'transform Pruning" or "--transform '
'LowLatency2[use_const_initializer=False]" or "--'
'transform "MakeStateful[param_res_names= {\'input_name_1\':'
'\'output_name_1\',\'input_name_2\':\'output_name_2\'}]\" \n'
'Available transformations: "LowLatency2", "MakeStateful", "Pruning"'},
'extensions':
{'description':
'Paths or a comma-separated list of paths to libraries '
'(.so or .dll) with extensions. For the legacy MO path '
'(if `--use_legacy_frontend` is used), a directory or a '
'comma-separated list of directories with extensions '
'are supported. To disable all extensions including '
'those that are placed at the default location, pass an empty string.',
'action': CanonicalizeExtensionsPathCheckExistenceAction,
'type': readable_dirs_or_files_or_empty},
'transformations_config':
{'description':
'Use the configuration file with transformations '
'description. Transformations file can be specified as '
'relative path from the current directory, as absolute '
'path or as arelative path from the mo root directory.',
'action': CanonicalizeTransformationPathCheckExistenceAction},
'counts':
{'action': CanonicalizePathCheckExistenceIfNeededAction},
'version':
{'action': 'version',
'version': 'Version of Model Optimizer is: {}'.format(get_version())},
'scale':
{'type': float,
'aliases': {'-s'}},
'batch':
{'type': check_positive,
'aliases': {'-b'}},
'input_proto':
{'aliases': {'-d'}},
'log_level':
{'choices': ['CRITICAL', 'ERROR', 'WARN', 'WARNING', 'INFO', 'DEBUG', 'NOTSET']}
}
# TODO: remove this when internal converting of params to string is removed
def get_to_string_methods_for_params():
from openvino.tools.mo.utils.cli_parser import path_to_str_or_object, input_shape_to_str, str_list_to_str, \
mean_scale_value_to_str, source_target_layout_to_str, layout_param_to_str, transform_param_to_str, \
extensions_to_str_or_extensions_class, batch_to_int, transformations_config_to_str, input_to_str
return {
'input_model': path_to_str_or_object,
'input_shape': input_shape_to_str,
'input': input_to_str,
'output': str_list_to_str,
'mean_values': mean_scale_value_to_str,
'scale_values': mean_scale_value_to_str,
'source_layout': source_target_layout_to_str,
'target_layout': source_target_layout_to_str,
'layout': layout_param_to_str,
'transform': transform_param_to_str,
'extensions': extensions_to_str_or_extensions_class,
'batch': batch_to_int,
'transformations_config': transformations_config_to_str,
'saved_model_tags': str_list_to_str
}
@@ -4,7 +4,6 @@
import argparse
import numpy
import os
import pathlib
import shutil
import sys
import tempfile
@@ -16,13 +15,13 @@ import numpy as np
from openvino.tools.mo.utils.cli_parser import get_placeholder_shapes, get_tuple_values, get_mean_scale_dictionary, \
get_model_name, \
parse_tuple_pairs, check_positive, writable_dir, readable_dirs, \
readable_file, get_freeze_placeholder_values, parse_transform, check_available_transforms, get_layout_values, get_data_type_from_input_value, get_all_cli_parser
readable_file, get_freeze_placeholder_values, parse_transform, check_available_transforms, get_layout_values, get_all_cli_parser, \
get_mo_convert_params
from openvino.tools.mo.convert_impl import pack_params_to_args_namespace
from openvino.tools.mo.convert import InputCutInfo, LayoutMap
from openvino.tools.mo.utils.error import Error
from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
from openvino.runtime import PartialShape, Dimension, Layout
from openvino.frontend import FrontEndManager
class TestingMeanScaleGetter(UnitTestWithMockedTelemetry):
@@ -1978,7 +1977,7 @@ class TestPackParamsToArgsNamespace(unittest.TestCase):
'layout': {"a": LayoutMap("nchw","nhwc"), "b": "nc"},
'transform': ('LowLatency2', {'use_const_initializer': False})}
cli_parser = get_all_cli_parser(FrontEndManager())
cli_parser = get_all_cli_parser()
argv = pack_params_to_args_namespace(args, cli_parser)
assert argv.input_model == args['input_model']
@@ -2001,7 +2000,7 @@ class TestPackParamsToArgsNamespace(unittest.TestCase):
def test_not_existing_dir(self):
args = {"input_model": "abc"}
cli_parser = get_all_cli_parser(FrontEndManager())
cli_parser = get_all_cli_parser()
with self.assertRaisesRegex(Error, "The \"abc\" is not existing file or directory"):
pack_params_to_args_namespace(args, cli_parser)
@@ -2009,7 +2008,45 @@ class TestPackParamsToArgsNamespace(unittest.TestCase):
def test_unknown_params(self):
args = {"input_model": os.path.dirname(__file__),
"a": "b"}
cli_parser = get_all_cli_parser(FrontEndManager())
cli_parser = get_all_cli_parser()
with self.assertRaisesRegex(Error, "Unrecognized argument: a"):
pack_params_to_args_namespace(args, cli_parser)
class TestConvertModelParamsParsing(unittest.TestCase):
def test_mo_convert_params_parsing(self):
ref_params = {
'Optional parameters:': {'help', 'framework'},
'Framework-agnostic parameters:': {'input_model', 'input_shape', 'scale', 'reverse_input_channels',
'log_level', 'input', 'output', 'mean_values', 'scale_values', 'source_layout',
'target_layout', 'layout', 'compress_to_fp16', 'transform', 'extensions',
'batch', 'silent', 'version', 'progress', 'stream_output',
'transformations_config'},
'Caffe*-specific parameters:': {'input_proto', 'caffe_parser_path', 'k', 'disable_omitting_optional',
'enable_flattening_nested_params'},
'TensorFlow*-specific parameters:': {'input_model_is_text', 'input_checkpoint', 'input_meta_graph',
'saved_model_dir', 'saved_model_tags',
'tensorflow_custom_operations_config_update',
'tensorflow_object_detection_api_pipeline_config',
'tensorboard_logdir', 'tensorflow_custom_layer_libraries'},
'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'}
}
params = get_mo_convert_params()
for group_name in ref_params:
assert group_name in params
assert params[group_name].keys() == ref_params[group_name]
cli_parser = get_all_cli_parser()
for group_name, params in ref_params.items():
for param_name in params:
param_name = '--' + param_name
if group_name == 'PyTorch-specific parameters:':
assert param_name not in cli_parser._option_string_actions
else:
assert param_name in cli_parser._option_string_actions