程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

windows MNN 的使用流程(Python版)

編輯:Python

MNN的文檔有中文
https://www.yuque.com/mnn/cn/about
除了部分細節, 按照文檔基本沒啥問題,本文部分內容基本也是拆解文檔

目前windows支持的Python版本:3.5、3.6、3.7,用的時候再去這裡確認下吧
https://www.yuque.com/mnn/cn/usage_in_python

1. Python 直接安裝

安裝很簡單,直接pip就好

pip install -U pip -i https://mirror.baidu.com/pypi/simple
pip install -U MNN -i https://mirror.baidu.com/pypi/simple

安裝完畢之後,在命令行輸入

> mnn
mnn toolsets has following command line tools
$mnn
list out mnn commands
$mnnconvert
convert other model to mnn model
$mnnquant
quantize mnn model

這就安裝成功了
mnnconvert 是用來做模型轉化,
mnnquant 量化工具

按理說,安裝完畢之後,命令行會有:

> mnnconvert
Usage:
MNNConvert [OPTION...]
-h, --help Convert Other Model Format To MNN Model
-v, --version show current version
-f, --framework arg model type, ex: [TF,CAFFE,ONNX,TFLITE,MNN]
--modelFile arg tensorflow Pb or caffeModel, ex:
*.pb,*caffemodel
--batch arg if model input's batch is not set, set as the batch size you set --keepInputFormat keep input dimension format or not, default: false --optimizeLevel arg graph optimize option, 0: don't run
optimize(only support for MNN source), 1: use graph
optimize only for every input case is right, 2:
normally right but some case may be wrong,
default 1
--optimizePrefer arg graph optimize option, 0 for normal, 1 for
smalleset, 2 for fastest
--prototxt arg only used for caffe, ex: *.prototxt
--MNNModel arg MNN model, ex: *.mnn
--fp16 save Conv's weight/bias in half_float data type --benchmarkModel Do NOT save big size data, such as Conv's
weight,BN's gamma,beta,mean and variance etc.
Only used to test the cost of the model
--bizCode arg MNN Model Flag, ex: MNN
--debug Enable debugging mode.
--forTraining whether or not to save training ops BN and
Dropout, default: false
--weightQuantBits arg save conv/matmul/LSTM float weights to int8
type, only optimize for model size, 2-8 bits,
default: 0, which means no weight quant
--weightQuantAsymmetric the default weight-quant uses SYMMETRIC quant
method, which is compatible with old MNN
versions. you can try set --weightQuantAsymmetric
to use asymmetric quant method to improve
accuracy of the weight-quant model in some cases,
but asymmetric quant model cannot run on old
MNN versions. You will need to upgrade MNN to
new version to solve this problem. default:
false
--compressionParamsFile arg
The path of the compression parameters that
stores activation, weight scales and zero
points for quantization or information for
sparsity.
--OP print framework supported op
--saveStaticModel save static model with fix shape, default:
false
--targetVersion arg compability for old mnn engine, default: 1.2f
--customOpLibs arg custom op libs ex: libmy_add.so;libmy_sub.so
--authCode arg code for model authentication.
--inputConfigFile arg set input config file for static model, ex:
~/config.txt
--alignDenormalizedValue arg
if 1, converter would align denormalized
float(|x| < 1.18e-38) as zero, because of in
ubuntu/protobuf or android/flatbuf, system
behaviors are different. default: 1, range: {
0, 1}
[10:15:46] @ 192: framework Invalid, use -f CAFFE/MNN/ONNX/TFLITE/TORCH !

如果命令行不能用,可以參考這個:
https://www.yuque.com/mnn/cn/usage_in_python

python(3) -m MNN.tools.mnn
python(3) -m MNN.tools.mnnconvert
python(3) -m MNN.tools.mnnquant

2. 轉化

這裡轉化一下,將onnx轉換為mnn模型

MNNConvert -f ONNX --modelFile output.onnx --MNNModel output.mnn --bizCode biz

加上 --fp 可以轉換為半精度的模型,模型的大小比例近乎縮小一半:

MNNConvert -f ONNX --modelFile output.onnx --MNNModel output16.mnn --bizCode biz --fp

半精度轉換文檔在這裡:
https://www.yuque.com/mnn/cn/qxtz32

3. MNN 權值量化

這個之前沒怎麼用過,直接copy一下官方文檔:

將模型中卷積的float權值量化為int8存儲,推理時反量化還原為float權值進行計算。因此,其推理速度和float模型一致,但是模型大小可以減小到原來的1/4,可以通過模型轉換工具一鍵完成,比較方便。推薦float模型性能夠用,僅需要減少模型大小的場景使用。

使用MNNConvert.exe(c++)或者mnnconvert(python包中自帶)進行轉換,轉換命令行中加上下述選項即可:

--weightQuantBits 8 [--weightQuantAsymmetric](可選)

--weightQuantAsymmetric 選項是指使用非對稱量化方法,精度要比默認的對稱量化精度好一些。

以上是直接用Python 命令行工具轉換的,接下來是,編譯轉換工具的過程:

注意:實驗證明,Python命令行工具mnnconvert 與 編譯的轉換工具MNNConvert.exe 效果相同,當然,可能在後續大版本有些不同

4. 編譯 MNNConvert.exe

編譯前需要 ninja, cmakeVS2017/2019

cmake安裝:
https://blog.csdn.net/HaoZiHuang/article/details/126015717

ninja 安裝:
https://blog.csdn.net/HaoZiHuang/article/details/126083356
ninja 是構建工具,比nmake更快)

安裝VS之後,在編譯過程中,命令行用x64 Native Tools Command Prompt 就好

編譯具體過程參考文檔:
https://www.yuque.com/mnn/cn/cvrt_windows

把 MNN git 下來,然後

cd MNN
mkdir build
cd build
cmake -G "Ninja" -DMNN_BUILD_SHARED_LIBS=OFF -DMNN_BUILD_CONVERTER=ON -DCMAKE_BUILD_TYPE=Release -DMNN_WIN_RUNTIME_MT=ON ..
ninja

之後會在目錄下生成:MNNConvert.exe 該工具就是轉換工具

5. 編譯推理引擎

官方文檔在:
https://www.yuque.com/mnn/cn/build_windows

由於編譯後的引擎在當前版本無法被Python調用,所以如果不用C++,該部分直接跳過不用看

下載GPU Caps Viewer,你可以通過這個工具來查看本機設備的詳細信息(opencl、opengl、vulkan等)

在Github上有個issue:
編譯的引擎如何用Python API調用:https://github.com/alibaba/MNN/issues/2010

官方回復是需要編譯 pymnn, 目前文檔還沒出來,等官方更新吧

同時編譯的時候需要 powershell

同時依舊需要VS的命令行x64 Native Tools Command Prompt

cd /path/to/MNN
powershell # 運行該命令從 cmd 環境進入 powershell 環境,後者功能更強大
./schema/generate.ps1

如果只需要 CPU 後端

# CPU, 64位編譯
.\package_scripts\win\build_lib.ps1 -path MNN-CPU/lib/x64
# CPU, 32位編譯
.\package_scripts\win\build_lib.ps1 -path MNN-CPU/lib/x86

如果需要 opencl 和 vulkan 後端

# CPU+OpenCL+Vulkan, 64位編譯
.\package_scripts\win\build_lib.ps1 -path MNN-CPU-OPENCL/lib/x64 -backends "opencl,vulkan"
# CPU+OpenCL+Vulkan, 32位編譯
.\package_scripts\win\build_lib.ps1 -path MNN-CPU-OPENCL/lib/x86 -backends "opencl,vulkan"

如果僅需要 opencl 後端

# CPU+OpenCL, 64位編譯
.\package_scripts\win\build_lib.ps1 -path MNN-CPU-OPENCL/lib/x64 -backends opencl
# CPU+OpenCL, 32位編譯
.\package_scripts\win\build_lib.ps1 -path MNN-CPU-OPENCL/lib/x86 -backends opencl

如果僅需要 vulkan 後端

# CPU+Vulkan, 64位編譯
.\package_scripts\win\build_lib.ps1 -path MNN-CPU-OPENCL/lib/x64 -backends vulkan
# CPU+Vulkan, 32位編譯
.\package_scripts\win\build_lib.ps1 -path MNN-CPU-OPENCL/lib/x86 -backends vulkan

具體都可以參考這些:
https://www.yuque.com/mnn/cn/build_windows

6. 驗證安裝是否成功

測試圖片shiyuan.jpg

結果圖片:

測試的mnn模型在這裡下載:
https://download.csdn.net/download/HaoZiHuang/86337543

import numpy as np
import MNN
import cv2
import matplotlib.pyplot as plt
def normalize(im,
mean=(0.5, 0.5, 0.5),
std=(0.5, 0.5, 0.5)):
im = im.astype(np.float32, copy=False) / 255.0
im -= mean
im /= std
return im
if __name__ == "__main__":
""" inference PPliteSeg using a specific picture """
img = "shiyuan.jpg"
interpreter = MNN.Interpreter("originalpool/output.mnn") # custompool originalpool
session = interpreter.createSession()
input_tensor = interpreter.getSessionInput(session)
image = cv2.imread(img)
image = cv2.resize(image, (224, 224))
image = normalize(image)
image = image.transpose((2, 0, 1))
image = image.astype(np.float32)
tmp_input = MNN.Tensor((1, 3, 224, 224),
MNN.Halide_Type_Float,
image,
MNN.Tensor_DimensionType_Caffe)
input_tensor.copyFrom(tmp_input)
interpreter.runSession(session)
output_tensor = interpreter.getSessionOutput(session)
tmp_output = MNN.Tensor((1, 2, 224, 224),
MNN.Halide_Type_Float,
np.ones([1, 2, 224, 224]).astype(np.float32),
MNN.Tensor_DimensionType_Caffe)
output_tensor.copyToHostTensor(tmp_output)
res = tmp_output.getNumpyData()[0]
res = res.argmax(axis=0)
plt.imshow(res)
plt.show()

7.1 代碼出現的問題

如果你自己的結果出現全1或者結果不對,可能就是我遇到的問題:

我的mnn模型是onnx模型導出來的,之前出現全1的結果,多次嘗試發現,我的onnx模型輸入是動態的,不是靜態,所以出現這個問題

如果也是這個 onnx -> mnn 的情況,用下邊兒這個腳本看看,是否是動態輸入:

https://blog.csdn.net/HaoZiHuang/article/details/126168132

如果是動態輸入,嘗試將onnx模型修改為靜態輸入試試,如果四 Paddle模型轉onnx模型,在Paddle2onnx工具後加添加 --input_shape_dict "{'x':[1,3,224,224]}"

Paddle2onnx工具命令使用指南在這裡:
https://github.com/PaddlePaddle/Paddle2ONNX#命令行轉換

7.2 結果圖片雜亂無章

本來的結果圖:

結果是醬紫:

可以參考該文章:
https://blog.csdn.net/HaoZiHuang/article/details/126136436


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved