一、MNN介绍
轻量级高性能推理引擎
MNN 是一个轻量级的深度神经网络推理引擎,在端侧加载深度神经网络模型进行推理预测。目前,MNN已经在阿里巴巴的手机淘宝、手机天猫、优酷等20多个App中使用,覆盖直播、短视频、搜索推荐、商品图像搜索、互动营销、权益发放、安全风控等场景。此外,IoT等场景下也有若干应用。
1.MNN整体特点
轻量性
- 针对端侧设备特点深度定制和裁剪,无任何依赖,可以方便地部署到移动设备和各种嵌入式设备中。
- iOS平台:armv7+arm64静态库大小5MB左右,链接生成可执行文件增加大小620KB左右,metallib文件600KB左右。
- Android平台:so大小500KB左右,OpenCL库300KB左右,Vulkan库300KB左右。
通用性
- 支持Tensorflow、Caffe、ONNX等主流模型文件格式,支持CNN、RNN、GAN等常用网络。
- 支持 149 个TensorflowOp、47 个CaffeOp、74 个 ONNX Op;各计算设备支持的MNN Op数:CPU 110个,Metal 55个,OpenCL 29个,Vulkan 31个。
- 支持iOS 8.0+、Android 4.3+和具有POSIX接口的嵌入式设备。
- 支持异构设备混合计算,目前支持CPU和GPU,可以动态导入GPU Op插件,替代CPU Op的实现。
高性能
- 不依赖任何第三方计算库,依靠大量手写汇编实现核心运算,充分发挥ARM CPU的算力。
- iOS设备上可以开启GPU加速(Metal),常用模型上快于苹果原生的CoreML。
- Android上提供了OpenCL、Vulkan、OpenGL三套方案,尽可能多地满足设备需求,针对主流GPU(Adreno和Mali)做了深度调优。
- 卷积、转置卷积算法高效稳定,对于任意形状的卷积均能高效运行,广泛运用了 Winograd 卷积算法,对3x3 -> 7x7之类的对称卷积有高效的实现。
- 针对ARM v8.2的新架构额外作了优化,新设备可利用半精度计算的特性进一步提速。
易用性
- 有高效的图像处理模块,覆盖常见的形变、转换等需求,一般情况下,无需额外引入libyuv或opencv库处理图像。
- 支持回调机制,可以在网络运行中插入回调,提取数据或者控制运行走向。
- 支持只运行网络中的一部分,或者指定CPU和GPU间并行运行。
2.MNN架构设计
MNN可以分为Converter和Interpreter两部分。
Converter
Converter由Frontends和Graph Optimize构成。前者负责支持不同的训练框架,MNN当前支持Tensorflow(Lite)、Caffe和ONNX(PyTorch/MXNet的模型可先转为ONNX模型再转到MNN);后者通过算子融合、算子替代、布局调整等方式优化图。
Interpreter
Interpreter由Engine和Backends构成。前者负责模型的加载、计算图的调度;后者包含各计算设备下的内存分配、Op实现。在Engine和Backends中,MNN应用了多种优化方案,包括在卷积和反卷积中应用Winograd算法、在矩阵乘法中应用Strassen算法、低精度计算、Neon优化、手写汇编、多线程优化、内存复用、异构计算等。
3.MNN License
Apache 2.0
二、MNN安装
MNN 工作台下载地址(Win+Mac版本)
https://www.mnn.zone/m/0.3/#download-mnn-workstation
Windows版MNN安装
1.开启MNN工作台安装程序
下载好的压缩包进行解压,双击安装程序“MNNWorkbench Setup 1.3.6”即可
2.耐心等待
稍微是有点慢的,需要耐心等待一下
3.安装完毕
安装好之后,会直接弹出“MNNWorkbench工作台窗口”
Mac OS版MNN安装
Mac OS版MNN环境要求
MNN 工作台目前仅支持 MacOS 10.13 及以上的用户,可以通过 Mac 上顶部菜单的关于本机来确认您的设备是否符合使用 MNN 工作台的要求。
注意:MacOS 10.13.x 系列的用户有可能会在使用过程中,遇到部分功能不兼容的情况。
怎么查看Mac 操作系统版本?
点击系统菜单,点击“关于本机”即可查看Mac 操作系统版本
开启MNN工作台安装程序
双击下载好的DMG安装程序,把“MNNWorkbench”程序文件夹拖到“Applications”文件夹就安装完毕了。
Mac OS版MNN安装安全设置
如果弹出如下图所示的安全提示,请前往 系统偏好设置 - 安全性隐私 - 通用 里面允许打开 MNN 工作台。
三、MNN编译
1.MNN推理框架Android编译
MNN编译环境要求
- cmake(建议使用3.10或以上版本)
- protobuf(使用3.0或以上版本)
- gcc(使用4.9或以上版本)
MNN编译选项
使用cmake编译时,可以修改CMakeLists.txt中的选项:
- MNN_DEBUG
默认关闭,关闭时,不保留符号,开启优化。 - MNN_USE_THREAD_POOL
默认开启,使用 MNN 内部的无锁线程池实现多线程优化。关闭后,视MNN_OPENMP开关选择OpenMP或关闭多线程优化。
注:MNN 的无锁线程池最多允许两个实例同时使用,即最多供两个模型同时推理使用。参考代码 source/backend/cpu/ThreadPool.cpp 中 MNN_THREAD_POOL_MAX_TASKS 宏的定义。 - MNN_OPENMP
默认开启,在 MNN_USE_THREAD_POOL 关闭时生效,依赖OpenMP实现多线程优化。关闭后,禁用OpenMP。 - MNN_OPENCL
默认关闭,开启后,编译OpenCL部分,可以通过指定MNN_FORWARD_OPENCL利用GPU进行推理。 - MNN_OPENGL
默认关闭,开启后,编译OpenGL部分,可以通过指定MNN_FORWARD_OPENGL利用GPU进行推理。
需要android-21及以上,亦即脚本中指定 -DANDROID_NATIVE_API_LEVEL=android-21 - MNN_VULKAN
默认关闭,开启后,编译Vulkan部分,可以通过指定MNN_FORWARD_VULKAN利用GPU进行推理。 - MNN_ARM82
默认关闭,开启后,编译Arm8.2部分,用Arm8.2+扩展指令集实现半精度浮点计算(fp16)和int8(sdot)加速
使用Arm82+扩展指令的方法如下:
// 创建session需要的配置
MNN::ScheduleConfig config;
// 选择Backend
config.type = MNN_FORWARD_CPU;
// 线程数
config.numThread = 2;
// 配置相应的Backend
BackendConfig backendConfig;
// Option 1: 如需运行浮点模型以运用FP16的加速,选择低精度Precision_Low
backendConfig.precision = BackendConfig::Precision_Low;
config.backendConfig = &backendConfig;
// Option 2: 如需运行量化模型以运用INT8 SDOT加速,选择普通精度(默认值)
backendConfig.precision = BackendConfig::Precision_Normal;
config.backendConfig = &backendConfig;
具体步骤
- 在https://developer.android.com/ndk/downloads/下载安装NDK,建议使用最新稳定版本
- 在 .bashrc 或者 .bash_profile 中设置 NDK 环境变量,例如:export ANDROID_NDK=/Users/username/path/to/android-ndk-r14b
- cd /path/to/MNN
- ./schema/generate.sh (可选,更改 schema 文件后需要重新生成)
- ./tools/script/get_model.sh(可选,模型仅demo工程需要)。注意get_model.sh需要事先编译好模型转换工具。
- cd project/android
- 编译动态库,可选择命令行方式或者 Android Studio 方式
- 命令行方式,适用 linux / mac 系统
- 编译armv7动态库:mkdir build_32 && cd build_32 && …/build_32.sh
- 编译armv8动态库:mkdir build_64 && cd build_64 && …/build_64.sh
- Android Studio 方式,全平台适用
- 用 Android Studio 打开 project/android/demo ,编译 apk
- 用 zip 解压编译好的 apk ,lib 目录下包含 mnn 的 so
2.推理框架iOS编译
MNN编译环境要求
protobuf(使用3.0或以上版本)
具体步骤
- cd /path/to/MNN
- ./schema/generate.sh
- ./tools/script/get_model.sh(可选,模型仅demo工程需要)。注意get_model.sh需要事先编译好模型转换工具。
- 在macOS下,用Xcode打开project/ios/MNN.xcodeproj,点击编译即可
如果需要使用Metal后端,需要将mnn.metallib拷贝至应用的main bundle目录下,可以参考Playground应用Build Phases中的Run Script。
3.推理框架Linux / macOS编译
MNN编译环境要求
- cmake(建议使用3.10或以上版本)
- protobuf(使用3.0或以上版本)
- gcc(使用4.9或以上版本)
MNN编译选项
使用cmake编译时,可以修改CMakeLists.txt中的选项:
- MNN_DEBUG
默认关闭,关闭时,不保留符号,开启优化。 - MNN_OPENMP
默认开启,关闭后,禁用openmp多线程优化。 - MNN_OPENCL
默认关闭,开启后,编译OpenCL部分,可以通过指定MNN_FORWARD_OPENCL利用GPU进行推理。 - MNN_OPENGL
默认关闭,开启后,编译OpenGL部分,可以通过指定MNN_FORWARD_OPENGL利用GPU进行推理。 - MNN_VULKAN
默认关闭,开启后,编译Vulkan部分,可以通过指定MNN_FORWARD_VULKAN利用GPU进行推理。 - MNN_METAL
默认关闭,开启后,编译Metal部分,可以通过指定MNN_FORWARD_METAL利用GPU进行推理,仅限iOS或macOS上开启。 - MNN_ARM82
默认关闭,开启后,编译Arm8.2部分,用Arm8.2+扩展指令集实现半精度浮点计算(fp16)和int8(sdot)加速
使用Arm82+扩展指令的方法如下:
// 创建session需要的配置
MNN::ScheduleConfig config;
// 选择Backend
config.type = MNN_FORWARD_CPU;
// 线程数
config.numThread = 2;
// 配置相应的Backend
BackendConfig backendConfig;
// 选择低精度
backendConfig.precision = BackendConfig::Precision_Low;
config.backendConfig = &backendConfig;
MNN编译具体步骤
准备工作
(可选,修改 MNN Schema 后需要)
cd /path/to/MNN
./schema/generate.sh
./tools/script/get_model.sh # 可选,模型仅demo工程需要
本地编译
mkdir build && cd build && cmake .. && make -j8
编译完成后本地出现MNN的动态库。
交叉编译
由于交叉编译的目标设备及厂商提供的编译环境类型众多,本文恕无法提供手把手教学。 以下是大致流程,请按照具体场景做相应修改。
交叉编译大致上分为以下两个步骤,即获取交叉编译器以及配置CMake进行交叉编译。
获取交叉编译工具链
以Linaro工具链为例。首先从 https://releases.linaro.org/components/toolchain/binaries/latest-7/ 网页中按照宿主机以及交叉编译目标设备来选择合适的工具链。这里我们以 arm-linux-gnueabi
为例,点击网页上的链接,进入 https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabi/ 页面。 按照宿主机类型(这里以X64 Linux为例)选择下载链接, 文件名形如 gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabi.tar.xz
下载后解压到任意目录。
配置交叉编译CMake
Toolchain 法
对于常用的交叉编译配置,工具链提供方或网络上可能已经有现成的CMake Toolchain。 这种情况下使用如下命令即可:
mkdir build
cd build
cmake 其他CMake参数 /MNN/源码/路径 -DCMAKE_TOOLCHAIN_FILE=CMake/Toolchain/文件/路径
注意部分这类CMake Toolchain中会写死你的交叉编译工具链路径,您可能需要手动编辑这些CMake Toolchain文件进行修改
手动配置法
mkdir build && cd build
cmake .. \
-DCMAKE_SYSTEM_NAME=宿主系统,例如Linux \
-DCMAKE_SYSTEM_VERSION=1 \
-DCMAKE_SYSTEM_PROCESSOR=交叉编译目标处理器的信息。例如arm或aarch64 \
-DCMAKE_C_COMPILER=交叉编译器中C编译器的路径 \
-DCMAKE_CXX_COMPILER=交叉编译器中C++编译器的路径
例子
还是以Linaro ARM64为例:
下载aarch64交叉编译工具链
mkdir -p linaro/aarch64
cd linaro/aarch64
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabi/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabi.tar.xz
tar xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabi.tar.xz
构建、编译
export cross_compile_toolchain=linaro/aarch64
mkdir build && cd build
cmake .. \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_SYSTEM_VERSION=1 \
-DCMAKE_SYSTEM_PROCESSOR=aarch64 \
-DCMAKE_C_COMPILER=$cross_compile_toolchain/bin/aarch64-linux-gnu-gcc \
-DCMAKE_CXX_COMPILER=$cross_compile_toolchain/bin/aarch64-linux-gnu-g++
make -j4
Ubuntu
- 安装opencl sdk(可选)
sudo apt install ocl-icd-opencl-dev
- 编译构建
mkdir build && cd build
cmake ..
make -j8
注:部分linux系统会出现执行不到openclbackend,需要手动dlopen mnn_opencl.so。
4.推理框架Windows编译
MNN主库
MNN编译环境要求
- Microsoft Visual Studio (>=2017)
- cmake(>=3.13)
- powershell
- Ninja (构建工具,比nmake更快)
MNN编译具体步骤
- 64位编译:在设置中找到vcvars64.bat(适用于 VS 2017 的 x64 本机工具命令提示)并单击,打开VS编译x64架构程序的虚拟环境
- 32位编译:在设置中找到vcvarsamd64_x86.bat(VS 2017的 x64_x86 交叉工具命令提示符)并单击,打开VS交叉编译x86架构程序的虚拟环境
cd /path/to/MNN
powershell # 运行该命令从cmd环境进入powershell环境,后者功能更强大
./schema/generate.ps1
# 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
# 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"
MNN opencl支持
环境要求
- (可选)下载GPU Caps Viewer,你可以通过这个工具来查看本机设备的详细信息(opencl、opengl、vulkan等)
驱动和sdk准备
- SDK
https://github.com/GPUOpen-LibrariesAndSDKs/OCL-SDK/releases 将opencl sdk目录的路径加到AMDAPPSDKROOT环境变量 - AMD Radeon
https://www.amd.com/zh-hans/support - NVIDIA
https://developer.nvidia.com/opencl - 其他待补充
编译MNN 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
MNN vulkan支持
驱动和sdk准备
- Vulkan SDK
下载链接:https://vulkan.lunarg.com/ ,安装完毕后,将Vulkan SDK路径加入VULKAN_SDK环境变量,以备cmake查找 - 驱动
AMD Radeon:https://community.amd.com/community/gaming/blog/2016/02/16/radeon-gpus-are-ready-for-the-vulkan-graphics-api ,其中列举了驱动下载位置和支持列表
编译MNN 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
四、MNN官方资源
MNN官网
https://www.mnn.zone/
MNN官方github
https://github.com/alibaba/MNN
MNN 工作台下载地址
https://www.mnn.zone/m/0.3/#download-mnn-workstation
👨💻博主Python老吕说:如果您觉得本文有帮助,辛苦您🙏帮忙点赞、收藏、评论,您的举手之劳将对我提供了无限的写作动力!🤞
🔥精品付费专栏:(暂时免费,尽快订阅、收藏哦)🔥
《跟老吕学Python编程》
《跟老吕学Python编程·附录资料》
🌐前端:
《跟老吕学HTML》
《XHTML》
《CSS》
《JavaScript》
《Vue》
💻后端:
《跟老吕学C语言》
《C++》
《Java》
《R》
《Ruby》
《PHP》
《Go》
《C#》
《Swift》
《Python》
💾数据库:
《跟老吕学Oracle语言》
《MYSQL》
《SQL》
《PostgreSQL》
《MongoDB》