MindConverter is a migration tool to transform the model scripts and weights from PyTorch, TensorFlow or ONNX to MindSpore. Users can migrate their PyTorch, TensorFlow or ONNX models to MindSpore rapidly with minor changes according to the conversion report.
MindConverter is a submodule in MindInsight. Please follow the Guide here to install MindInsight.
For users using MindConverter, in addition to install the TensorFlow that can satisfy the model loading, inference and training requirements, users also need to install the following third party package (tf2onnx is not required for users that convert ONNX model definition file to MindSpore):
onnx>=1.8.0
tf2onnx>=1.7.1
onnxruntime>=1.5.2
onnxoptimizer>=0.1.2
For some models, if the onnx or tf2onnx error message appears during the conversion process, please try to upgrade the onnx, tf2onnx or onnxoptimizer in the environment to the latest version.
MindConverter currently only provides command-line interface. Here is the manual page.
usage: mindconverter [-h] [--version] [--in_file IN_FILE]
[--model_file MODEL_FILE] [--shape SHAPE [SHAPE ...]]
[--input_nodes INPUT_NODES [INPUT_NODES ...]]
[--output_nodes OUTPUT_NODES [OUTPUT_NODES ...]]
[--output OUTPUT] [--report REPORT]
optional arguments:
-h, --help show this help message and exit
--version show program version number and exit
--in_file IN_FILE Specify path for script file to use AST schema to do
script conversation.
--model_file MODEL_FILE
Tensorflow(.pb) or ONNX(.onnx) model file path is
expected to do script generation based on graph
schema. When `--in_file` and `--model_file` are both
provided, use AST schema as default.
--shape SHAPE [SHAPE ...]
Expected input tensor shape of `--model_file`. It is
required when use graph based schema. Both order and
number should be consistent with `--input_nodes`.
Given that (1,128) and (1,512) are shapes of input_1
and input_2 separately. Usage: --shape 1,128 1,512
--input_nodes INPUT_NODES [INPUT_NODES ...]
Input node(s) name of `--model_file`. It is required
when use graph based schema. Both order and number
should be consistent with `--shape`. Given that both
input_1 and input_2 are inputs of model. Usage:
--input_nodes input_1 input_2
--output_nodes OUTPUT_NODES [OUTPUT_NODES ...]
Output node(s) name of `--model_file`. It is required
when use graph based schema. Given that both output_1
and output_2 are outputs of model. Usage:
--output_nodes output_1 output_2
--output OUTPUT Optional, specify path for converted script file
directory. Default output directory is `output` folder
in the current working directory.
--report REPORT Optional, specify report directory. Default is
converted script directory.
Abstract Syntax Tree (AST) based conversion: Use the argument --in_file will enable the AST mode.
The AST mode will be enabled, if both
--in_fileand--model_fileare specified.
--output and --report is optional. MindConverter creates an output folder under the current working directory, and outputs generated scripts to it.
While computational graph based conversion is required, it is recommended to use ONNX file after converting PyTorch model scripts to ONNX file, and the tutorial is PyTorch instruction.
MindConverter provides computational graph based conversion for TensorFlow: Transformation will be done given --model_file, --shape, --input_nodes and --output_nodes.
AST mode is not supported for TensorFlow, only computational graph based mode is available.
If both output and report are not set, mindConverter creates an output folder under the current working directory, and outputs generated scripts, converted checkpoint file, weight map file and conversion reports to it.
MindConverter provides computational graph based conversion for ONNX: Transformation will be done given --model_file, --shape, --input_nodes and --output_nodes.
AST mode is not supported for ONNX, only computational graph based mode is available.
If both output and report are not set, mindConverter creates an output folder under the current working directory, and outputs generated scripts, converted checkpoint file, weight map file and conversion reports to it.
MindConverter provides two modes for different migration demands.
The AST mode is recommended for the first demand (AST mode is only supported for PyTorch). It parses and analyzes PyTorch scripts, then replace them with the MindSpore AST to generate codes. Theoretically, The AST mode supports any model script. However, the conversion may differ due to the coding style of original scripts.
For the second demand, the Graph mode is recommended. As the computational graph is a standard descriptive language, it is not affected by user's coding style. This mode may have more operators converted as long as these operators are supported by MindConverter.
Some typical image classification networks have been tested for the Graph mode. Note that:
- The Dropout operator will be lost after conversion because the inference mode is used to load the ONNX or TensorFlow model. Manually re-implement is necessary.
- The Graph-based mode will be continuously developed and optimized with further updates.
Assume the PyTorch script is located at /home/user/model.py, and outputs the transformed MindSpore script to /home/user/output, with the conversion report to /home/user/output/report. Use the following command:
mindconverter --in_file /home/user/model.py \
--output /home/user/output \
--report /home/user/output/report
In the conversion report, non-transformed code is listed as follows:
line <row>:<col> [UnConvert] 'operator' didn't convert. ...
For non-transformed operators, the original code keeps. Please manually migrate them. Click here for more information about operator mapping.
Here is an example of the conversion report:
[Start Convert]
[Insert] 'import mindspore.ops.operations as P' is inserted to the converted file.
line 1:0: [Convert] 'import torch' is converted to 'import mindspore'.
...
line 157:23: [UnConvert] 'nn.AdaptiveAvgPool2d' didn't convert. Maybe could convert to mindspore.ops.operations.ReduceMean.
...
[Convert Over]
For non-transformed operators, suggestions are provided in the report. For instance, MindConverter suggests that replace torch.nn.AdaptiveAvgPool2d with mindspore.ops.operations.ReduceMean.
To use TensorFlow model script migration, users need to export TensorFlow model to Pb format first, and obtain the model input node and output node name. For exporting pb model, please refer to TensorFlow Pb model exporting.
Suppose the input node name is input_1:0, output node name is predictions/Softmax:0, the input shape of model is 1,224,224,3 and the original TensorFlow model is at /home/user/xxx/frozen_model.pb. Output the transformed MindSpore script and MindSpore checkpoint file to /home/user/output, with the conversion report and weight map file to /home/user/output/report. Use the following command:
mindconverter --model_file /home/user/xxx/frozen_model.pb --shape 1,224,224,3 \
--input_nodes input_1:0 \
--output_nodes predictions/Softmax:0 \
--output /home/user/output \
--report /home/user/output/report
After executed, MindSpore script, MindSpore checkpoint file, weight map file and report file can be found in corresponding directory.
Since the graph based scheme is a generative method, the original TensorFlow script is not referenced in the conversion process. Therefore, the code line and column numbers involved in the generated conversion report refer to the generated script.
In addition, input and output Tensor shape of unconverted operators shows explicitly (input_shape and output_shape) as comments in converted scripts to help further manual modifications. Here is an example of the Reshape operator (Not supported in current version):
class Classifier(nn.Cell):
def __init__(self):
super(Classifier, self).__init__()
...
self.reshape = onnx.Reshape(input_shape=(1, 1280, 1, 1),
output_shape=(1, 1280))
...
def construct(self, x):
...
# Suppose input of `reshape` is x.
reshape_output = self.reshape(x)
...
It is convenient to replace the operators according to the input_shape and output_shape parameters. The replacement is like this:
from mindspore.ops import operations as P
...
class Classifier(nn.Cell):
def __init__(self):
super(Classifier, self).__init__()
...
self.reshape = P.Reshape(input_shape=(1, 1280, 1, 1),
output_shape=(1, 1280))
...
def construct(self, x):
...
# Suppose input of `reshape` is x.
reshape_output = self.reshape(x, (1, 1280))
...
--outputand--reportare optional. MindConverter creates anoutputfolder under the current working directory, and outputs generated scripts, MindSpore checkpoint file, weight map file and conversion reports to it.
Here is an example of the weight map:
{
"resnet50": [
{
"converted_weight": {
"name": "conv2d_0.weight",
"shape": [
64,
3,
7,
7
],
"data_type": "Float32"
},
"source_weight": {
"name": "conv1.weight",
"shape": [
64,
3,
7,
7
],
"data_type": "float32"
}
}
]
}
Weight information in MindSpore (converted_weight) and that in source framework(source_weight) are saved in weight map separately.
To use ONNX model file migration, user needs to obtain the model input node and output node name from ONNX model. To get input node and output node name, Netron is recommended.
Suppose the model is saved to /home/user/xxx/model.onnx, corresponding input node name is input_1:0, output node name is predictions/Softmax:0, the input shape of model is 1,3,224,224, the following command can be used to generate the script:
mindconverter --model_file /home/user/xxx/model.onnx --shape 1,3,224,224 \
--input_nodes input_1:0 \
--output_nodes predictions/Softmax:0 \
--output /home/user/output \
--report /home/user/output/report
After executed, MindSpore script, MindSpore checkpoint file, weight map file and report file can be found in corresponding directory.
Since the graph based scheme is a generative method, the original ONNX model is not referenced in the conversion process. Therefore, the code line and column numbers involved in the generated conversion report refer to the generated script.
In addition, for operators that are not converted successfully, the input and output shape of tensor of the node will be identified in the code by input_shape and output_shape. For example, please refer to the example in TensorFlow Model Scripts Conversion section.
--shape while using graph based scheme, as a result, it is required that inputs shape used to retrain or inference in MindSpore are the same as that used to convert using MindConverter. If inputs shape has changed, rerunning MindConverter with new --shape or fixing shape related parameters in old script manually is necessary.Classes and functions that can't be converted:
.shape, .ndim and .dtype member of torch.Tensor.torch.nn.AdaptiveXXXPoolXd and torch.nn.functional.adaptive_XXX_poolXd().torch.nn.functional.Dropout.torch.unsqueeze() and torch.Tensor.unsqueeze().torch.chunk() and torch.Tensor.chunk().Subclassing from the subclasses of nn.Module
e.g. (code snip from torchvision.models.mobilenet)
from torch import nn
class ConvBNReLU(nn.Sequential):
def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1):
padding = (kernel_size - 1) // 2
super(ConvBNReLU, self).__init__(
nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False),
nn.BatchNorm2d(out_planes),
nn.ReLU6(inplace=True)
)
Q1. terminate called after throwing an instance of 'std::system_error', what(): Resource temporarily unavailable, Aborted (core dumped):
Answer: This problem is caused by TsorFlow. First step of conversion process is loading TensorFlow model into memory using TensorFlow module, and TensorFlow starts to apply for needed resource. When required resource is unavailable, such as exceeding max process number of Linux system limit, etc., TensorFlow will raise an error from its C/C++ layer. For more detail, please refer to TensorFlow official repository. There are some known issue for reference only:
TF ISSUE 14885, TF ISSUE 37449
Q2. Can MindConverter run on ARM platform?
Answer: MindConverter supports both x86 and ARM platform. Please ensure all required dependencies and environments installed in the ARM platform.
Q3. Why does the conversion process take a lot of time (more than 10 minutes), but the model is not so large?
Answer: When converting, MindConverter needs to use protobuf to deserialize the model file. Please make sure that the protobuf installed in Python environment is implemented by C++ backend. The validation method is as follows. If the output is "python", you need to install Python protobuf implemented by C++ (download the protobuf source code, enter the "python" subdirectory in the source code, and use
python setup.py install --cpp_implementationto install). If the output is "cpp" and the conversion process still takes a long time, please add environment variableexport PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cppbefore conversion.
from google.protobuf.internal import api_implementation
print(api_implementation.Type())
Q4. While converting .pb file to MindSpore script, what may be the cause of error code 1000001 with ensuring model_file, shape, iput_nodes and output_nodes set right and third party requirements installed correctly?
Answer: Make sure that the TensorFlow version to generate .pb file is no higher than that to convert .pb file, avoiding the conflict which caused by using low version TensorFlow to parse .pb file generated by high version one.
Q5. What should I do to deal with Exception [ERROR] MINDCONVERTER: [BaseConverterError] code: 0000000, msg: {python_home}/lib/libgomp.so.1: cannot allocate memory in static TLS block?
Answer: In most cases, the problem is caused by environment variable exported incorrectly. Please set
export LD_PRELOAD={python_home}/lib/libgomp.so.1.0.0, then try to rerun MindConverter.
If build model with Keras API, user can refer to this tutorial.
Error code defined in MindConverter, please refer to LINK.