查看版本

  1. ./MNNConvert --version

模型转换

参数说明

  1. Usage:
  2. MNNConvert [OPTION...]
  3. -h, --help Convert Other Model Format To MNN Model
  4. -v, --version 显示当前转换器版本
  5. -f, --framework arg 需要进行转换的模型类型, ex: [TF,CAFFE,ONNX,TFLITE,MNN,TORCH, JSON]
  6. --modelFile arg 需要进行转换的模型文件名, ex: *.pb,*caffemodel
  7. --prototxt arg caffe模型结构描述文件, ex: *.prototxt
  8. --MNNModel arg 转换之后保存的MNN模型文件名, ex: *.mnn
  9. --fp16 conv/matmul/LSTMfloat32参数保存为float16
  10. 模型将减小一半,精度基本无损
  11. --benchmarkModel 不保存模型中conv/matmul/BN等层的参数,仅用于benchmark测试
  12. --bizCode arg MNN模型Flag, ex: MNN
  13. --debug 使用debug模型显示更多转换信息
  14. --forTraining 保存训练相关算子,如BN/Dropoutdefault: false
  15. --weightQuantBits arg arg=2~8,此功能仅对conv/matmul/LSTMfloat32权值进行量化,
  16. 仅优化模型大小,加载模型后会解码为float32,量化位宽可选2~8
  17. 运行速度和float32模型一致。8bit时精度基本无损,模型大小减小4
  18. default: 0,即不进行权值量化
  19. --compressionParamsFile arg
  20. 使用MNN模型压缩工具箱生成的模型压缩信息文件
  21. --saveStaticModel 固定输入形状,保存静态模型, default: false
  22. --inputConfigFile arg 保存静态模型所需要的配置文件, ex: ~/config.txt。文件格式为:
  23. input_names = input0,input1
  24. input_dims = 1x3x224x224,1x3x64x64
  25. --JsonFile arg 当-f MNN并指定JsonFile时,可以将MNN模型转换为Json文件
  26. --info 当-f MNN时,打印模型基本信息(输入名、输入形状、输出名、模型版本等)
  27. --testdir arg 测试转换 MNN 之后,MNN推理结果是否与原始模型一致。
  28. arg 为测试数据的文件夹,生成方式参考 "正确性校验" 一节
  29. --thredhold arg 当启用 --testdir 后,设置正确性校验的误差允可范围
  30. 若不设置,默认是 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

  1. ./MNNConvert -f TF --modelFile XXX.pb --MNNModel XXX.mnn --bizCode biz

TensorFlow Lite -> MNN

  1. ./MNNConvert -f TFLITE --modelFile XXX.tflite --MNNModel XXX.mnn --bizCode biz

Caffe -> MNN

  1. ./MNNConvert -f CAFFE --modelFile XXX.caffemodel --prototxt XXX.prototxt --MNNModel XXX.mnn --bizCode biz

ONNX -> MNN

  1. ./MNNConvert -f ONNX --modelFile XXX.onnx --MNNModel XXX.mnn --bizCode biz

TorchScript -> MNN

  1. ./MNNConvert -f TORCH --modelFile XXX.pt --MNNModel XXX.mnn --bizCode biz

注意:TorchScript模型要求使用torch.jit导出的模型,不要直接使用Pytorch的权重文件作为模型转换;导出模型的代码如下:

  1. import torch
  2. # ...
  3. # model is exported model
  4. model.eval()
  5. # trace
  6. model_trace = torch.jit.trace(model, torch.rand(1, 3, 1200, 1200))
  7. model_trace.save('model_trace.pt')
  8. # script
  9. model_script = torch.jit.script(model)
  10. model_script.save('model_script.pt')

对比 Onnx 和 MNN 结果差异的脚本fastTestOnnx.py,需要安装 onnxruntime ,编译好 MNN 的 Converter,在 MNN 的 build 目录下运行

  1. python3 fastTestOnnx.py XXXX.onnx

fastTestOnnx.py

  1. #!/usr/bin/python
  2. import sys
  3. import onnx
  4. import onnxruntime as ort
  5. import numpy as np
  6. modelName = sys.argv[1]
  7. jsonDict = {}
  8. jsonDict['inputs'] = []
  9. jsonDict['outputs'] = []
  10. import os
  11. print(os.popen("mkdir onnx").read())
  12. inputs = {}
  13. ort_session = ort.InferenceSession(modelName)
  14. model = onnx.load(modelName)
  15. for inputVar in ort_session.get_inputs():
  16. inp = {}
  17. inp['name'] = inputVar.name
  18. inp['shape'] = inputVar.shape
  19. inputs[inputVar.name] = np.random.uniform(0.1, 1.2, inputVar.shape).astype(np.float32)
  20. jsonDict['inputs'].append(inp)
  21. print([output.name for output in model.graph.output])
  22. for output in model.graph.output:
  23. jsonDict['outputs'].append(output.name)
  24. import json
  25. jsonString = json.dumps(jsonDict, indent=4)
  26. with open('onnx/input.json', 'w') as f:
  27. f.write(jsonString)
  28. print('inputs:')
  29. for key in inputs:
  30. print(key)
  31. f = open("onnx/" + key + '.txt', 'w')
  32. np.savetxt(f, inputs[key].flatten())
  33. f.close()
  34. outputs = ort_session.run(None, inputs)
  35. print('outputs:')
  36. for i in range(0, len(outputs)):
  37. outputName = model.graph.output[i].name
  38. name = 'onnx/' + outputName + '.txt'
  39. print(name, outputs[i].shape)
  40. f = open(name, 'w')
  41. np.savetxt(f, outputs[i].flatten())
  42. f.close()
  43. print(os.popen("cp " + modelName + " onnx/test.onnx").read())
  44. print(os.popen("./TestConvertResult Onnx onnx").read());

输出结果为 TEST_SUSSESS 即为正确

PyTorch -> MNN

  1. 用PyTorch的 onnx.export 接口转换 ONNX 模型文件(参考:https://pytorch.org/docs/stable/onnx.html)

    1. import torch
    2. import torchvision
    3. dummy_input = torch.randn(10, 3, 224, 224, device='cuda')
    4. model = torchvision.models.alexnet(pretrained=True).cuda()
    5. # Providing input and output names sets the display names for values
    6. # within the model's graph. Setting these does not change the semantics
    7. # of the graph; it is only for readability.
    8. #
    9. # The inputs to the network consist of the flat list of inputs (i.e.
    10. # the values you would pass to the forward() method) followed by the
    11. # flat list of parameters. You can partially specify names, i.e. provide
    12. # a list here shorter than the number of inputs to the model, and we will
    13. # only set that subset of names, starting from the beginning.
    14. input_names = [ "actual_input_1" ] + [ "learned_%d" % i for i in range(16) ]
    15. output_names = [ "output1" ]
    16. torch.onnx.export(model, dummy_input, "alexnet.onnx", verbose=True, input_names=input_names, output_names=output_names)
  2. 将 ONNX 模型文件转成 MNN 模型

    1. ./MNNConvert -f ONNX --modelFile XXX.onnx --MNNModel XXX.mnn --bizCode biz

MNN -> Json

想了解MNN模型的具体结构,输入输出信息时,可以将模型转换为Json文件,并查找相关信息获取。

  1. ./MNNConvert -f MNN --modelFile XXX.mnn --JsonFile XXX.json

Json -> MNN

可以通过将MNN模型转换为Json文件,对Json文件进行编辑修改,然后在转换为MNN模型,达到对模型修改微调的目的。

  1. ./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 ,示例: