查看版本
./MNNConvert --version
模型转换
参数说明
Usage:
MNNConvert [OPTION...]
-h, --help Convert Other Model Format To MNN Model
-v, --version 显示当前转换器版本
-f, --framework arg 需要进行转换的模型类型, ex: [TF,CAFFE,ONNX,TFLITE,MNN,TORCH, JSON]
--modelFile arg 需要进行转换的模型文件名, ex: *.pb,*caffemodel
--prototxt arg caffe模型结构描述文件, ex: *.prototxt
--MNNModel arg 转换之后保存的MNN模型文件名, ex: *.mnn
--fp16 将conv/matmul/LSTM的float32参数保存为float16,
模型将减小一半,精度基本无损
--benchmarkModel 不保存模型中conv/matmul/BN等层的参数,仅用于benchmark测试
--bizCode arg MNN模型Flag, ex: MNN
--debug 使用debug模型显示更多转换信息
--forTraining 保存训练相关算子,如BN/Dropout,default: false
--weightQuantBits arg arg=2~8,此功能仅对conv/matmul/LSTM的float32权值进行量化,
仅优化模型大小,加载模型后会解码为float32,量化位宽可选2~8,
运行速度和float32模型一致。8bit时精度基本无损,模型大小减小4倍
default: 0,即不进行权值量化
--compressionParamsFile arg
使用MNN模型压缩工具箱生成的模型压缩信息文件
--saveStaticModel 固定输入形状,保存静态模型, default: false
--inputConfigFile arg 保存静态模型所需要的配置文件, ex: ~/config.txt。文件格式为:
input_names = input0,input1
input_dims = 1x3x224x224,1x3x64x64
--JsonFile arg 当-f MNN并指定JsonFile时,可以将MNN模型转换为Json文件
--info 当-f MNN时,打印模型基本信息(输入名、输入形状、输出名、模型版本等)
--testdir arg 测试转换 MNN 之后,MNN推理结果是否与原始模型一致。
arg 为测试数据的文件夹,生成方式参考 "正确性校验" 一节
--thredhold arg 当启用 --testdir 后,设置正确性校验的误差允可范围
若不设置,默认是 0.01
说明1: 选项benchmarkModel将模型中例如卷积的weight,BN的mean、var等参数移除,减小转换后模型文件大小,在运行时随机初始化参数,以方便测试模型的性能。
说明2: 选项weightQuantBits,使用方式为 —weightQuantBits numBits,numBits可选2~8,此功能仅对conv/matmul/LSTM的float32权值进行量化,仅优化模型大小,加载模型后会解码为float32,量化位宽可选2~8,运行速度和float32模型一致。经内部测试8bit时精度基本无损,模型大小减小4倍。default: 0,即不进行权值量化。
TensorFlow -> MNN
./MNNConvert -f TF --modelFile XXX.pb --MNNModel XXX.mnn --bizCode biz
TensorFlow Lite -> MNN
./MNNConvert -f TFLITE --modelFile XXX.tflite --MNNModel XXX.mnn --bizCode biz
Caffe -> MNN
./MNNConvert -f CAFFE --modelFile XXX.caffemodel --prototxt XXX.prototxt --MNNModel XXX.mnn --bizCode biz
ONNX -> MNN
./MNNConvert -f ONNX --modelFile XXX.onnx --MNNModel XXX.mnn --bizCode biz
TorchScript -> MNN
./MNNConvert -f TORCH --modelFile XXX.pt --MNNModel XXX.mnn --bizCode biz
注意:TorchScript模型要求使用torch.jit导出的模型,不要直接使用Pytorch的权重文件作为模型转换;导出模型的代码如下:
import torch
# ...
# model is exported model
model.eval()
# trace
model_trace = torch.jit.trace(model, torch.rand(1, 3, 1200, 1200))
model_trace.save('model_trace.pt')
# script
model_script = torch.jit.script(model)
model_script.save('model_script.pt')
对比 Onnx 和 MNN 结果差异的脚本fastTestOnnx.py,需要安装 onnxruntime ,编译好 MNN 的 Converter,在 MNN 的 build 目录下运行
python3 fastTestOnnx.py XXXX.onnx
fastTestOnnx.py
#!/usr/bin/python
import sys
import onnx
import onnxruntime as ort
import numpy as np
modelName = sys.argv[1]
jsonDict = {}
jsonDict['inputs'] = []
jsonDict['outputs'] = []
import os
print(os.popen("mkdir onnx").read())
inputs = {}
ort_session = ort.InferenceSession(modelName)
model = onnx.load(modelName)
for inputVar in ort_session.get_inputs():
inp = {}
inp['name'] = inputVar.name
inp['shape'] = inputVar.shape
inputs[inputVar.name] = np.random.uniform(0.1, 1.2, inputVar.shape).astype(np.float32)
jsonDict['inputs'].append(inp)
print([output.name for output in model.graph.output])
for output in model.graph.output:
jsonDict['outputs'].append(output.name)
import json
jsonString = json.dumps(jsonDict, indent=4)
with open('onnx/input.json', 'w') as f:
f.write(jsonString)
print('inputs:')
for key in inputs:
print(key)
f = open("onnx/" + key + '.txt', 'w')
np.savetxt(f, inputs[key].flatten())
f.close()
outputs = ort_session.run(None, inputs)
print('outputs:')
for i in range(0, len(outputs)):
outputName = model.graph.output[i].name
name = 'onnx/' + outputName + '.txt'
print(name, outputs[i].shape)
f = open(name, 'w')
np.savetxt(f, outputs[i].flatten())
f.close()
print(os.popen("cp " + modelName + " onnx/test.onnx").read())
print(os.popen("./TestConvertResult Onnx onnx").read());
输出结果为 TEST_SUSSESS 即为正确
PyTorch -> MNN
用PyTorch的 onnx.export 接口转换 ONNX 模型文件(参考:https://pytorch.org/docs/stable/onnx.html)
import torch
import torchvision
dummy_input = torch.randn(10, 3, 224, 224, device='cuda')
model = torchvision.models.alexnet(pretrained=True).cuda()
# Providing input and output names sets the display names for values
# within the model's graph. Setting these does not change the semantics
# of the graph; it is only for readability.
#
# The inputs to the network consist of the flat list of inputs (i.e.
# the values you would pass to the forward() method) followed by the
# flat list of parameters. You can partially specify names, i.e. provide
# a list here shorter than the number of inputs to the model, and we will
# only set that subset of names, starting from the beginning.
input_names = [ "actual_input_1" ] + [ "learned_%d" % i for i in range(16) ]
output_names = [ "output1" ]
torch.onnx.export(model, dummy_input, "alexnet.onnx", verbose=True, input_names=input_names, output_names=output_names)
将 ONNX 模型文件转成 MNN 模型
./MNNConvert -f ONNX --modelFile XXX.onnx --MNNModel XXX.mnn --bizCode biz
MNN -> Json
想了解MNN模型的具体结构,输入输出信息时,可以将模型转换为Json文件,并查找相关信息获取。
./MNNConvert -f MNN --modelFile XXX.mnn --JsonFile XXX.json
Json -> MNN
可以通过将MNN模型转换为Json文件,对Json文件进行编辑修改,然后在转换为MNN模型,达到对模型修改微调的目的。
./MNNConvert -f JSON --modelFile XXX.json --MNNModel XXX.mnn
正确性校验
为了便于开发者排查问题,对于 PB / Tflite / Onnx ,MNN 提供了正确性校验工具(位于 tools/scripts 目录),以检查 MNN 推理结果是否与 原始模型一致。
相关脚本为:
- fastTestTf.py :适用 pb
- fastTestTflite.py :适用 tflite
- fastTestOnnx.py :适用 onnx
对于由 Torchscript 转换的模型,可以参考 fastTestTorch.py ,自行修改相应的输入构造代码来测试
前置
- 测试 pb / tflite :安装 tensorflow (pip3 install tensorflow)
- 测试 onnx : 安装 onnxruntime (pip3 install onnxruntime)
MNN 模型转换工具编译完成(编译完成产生 TestConvertResult 可执行文件)
使用
使用:在MNN 的 build 目录下(包含 TestConvertResult)运行 python3 fastTestTf.py SRC.pb (Onnx 为 python3 fastTestOnnx.py SRC.onnx ,Tflite 类似),若最终结果为 TEST_SUCCESS 则表示 MNN 的模型转换与运行结果正确
- 由于 MNN 图优化会去除 Identity ,有可能出现 find var error ,这个时候可以打开原始模型文件,找到 identity 之前的一层(假设为 LAYER_NAME )校验,示例:
- python3 fastTestTf.py SRC.pb LAYER_NAME
默认只支持限定数值范围的输入随机生成,如需修改,请自己修改脚本
出错及解决
出现 Test Error 或者 MNN 的 crash 可直接反馈(提 github issue 或者钉钉群反馈)
- 如需自查,fastTestOnnx.py 提供 debug 功能,可方便定位出错的 layer / op ,示例:
- python3 fastTestOnnx.py SRC.onnx DEBUG
模型转换的Python工具
我们提供了预编译的MNNConvert Python工具。https://www.yuque.com/mnn/cn/usage_in_python
- python3 fastTestOnnx.py SRC.onnx DEBUG