MNN是一个轻量级的深度神经网络推理引擎,在端侧加载深度神经网络模型进行推理预测。目前,MNN已经在阿里巴巴的手机淘宝、手机天猫、优酷等20多个App中使用,覆盖直播、短视频、搜索推荐、商品图像搜索、互动营销、权益发放、安全风控等场景。此外,IoT等场景下也有若干应用。

整体特点

轻量性
• 针对端侧设备特点深度定制和裁剪,无任何依赖,可以方便地部署到移动设备和各种嵌入式设备中。
• 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间并行运行。

安装

git clone https://github.com/alibaba/MNN

推理框架编译(Linux / macOS)

环境要求

• cmake(建议使用3.10或以上版本)、
• protobuf(使用3.0或以上版本)
• gcc(使用4.9或以上版本)

编译选项

使用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)加速

具体步骤

cd /path/to/MNN
./schema/generate.sh
./tools/script/get_model.sh # 可选,模型仅demo工程需要
mkdir build && cd build && cmake .. && make -j8

编译完成后MNN/build目录下出现MNN的动态库(libMNN.so)。

推理框架Android编译

环境要求

• cmake(建议使用3.10或以上版本)、
• protobuf(使用3.0或以上版本)
• gcc(使用4.9或以上版本)

编译选项

使用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)加速

具体步骤

在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
./tools/script/get_model.sh(可选,模型仅demo工程需要)。注意get_model.sh需要事先编译好模型转换工具。
cd project/android
编译armv7动态库:mkdir build_32 && cd build_32 && ../build_32.sh
编译armv8动态库:mkdir build_64 && cd build_64 && ../build_64.sh

转换工具Linux / macOS编译

cd MNN/
./schema/generate.sh
mkdir build
cd build
cmake .. -DMNN_BUILD_CONVERTER=true && make -j4

编译产物包含模型转换工具MNNConvert和模型输出工具MNNDump2Json.out