MNN 深度学习推理引擎使用教程
1. MNN 简介
MNN(Mobile Neural Network)是阿里巴巴开源的轻量级深度学习推理引擎,专为移动端和嵌入式设备优化。
主要特点:
- 轻量高效:体积小、速度快、内存占用低
- 跨平台:支持 iOS、Android、Linux、Windows、macOS
- 多后端:CPU、GPU(OpenGL/Vulkan/Metal)、NPU
- 易用性:提供 C++、Java、Python 等多语言接口
- 优化器:内置模型压缩和优化工具
官方资源:
- GitHub:https://github.com/alibaba/MNN
- 文档:https://mnn-docs.readthedocs.io/
- 知乎专栏:https://zhuanlan.zhihu.com/p/455021896
2. 环境准备
2.1 系统要求
- Android:NDK r21 或更高版本
- iOS:Xcode 11 或更高版本
- Linux/Windows/macOS:CMake 3.10+、GCC 4.9+ 或 Clang
2.2 获取源码
bash
git clone https://github.com/alibaba/MNN.git
cd MNN3. Android 平台编译
3.1 配置 NDK 环境
bash
export ANDROID_NDK="/Users/$USER/Library/Android/sdk/ndk/28.0.13004108"
# 或者在 Linux/Windows 上
export ANDROID_NDK="/path/to/android-ndk"3.2 编译 ARMv8 动态库
参考文档:https://mnn-docs.readthedocs.io/en/latest/compile/engine.html
bash
cd MNN/project/android
# 编译 64 位 ARM 架构,启用多种后端
../build_64.sh \
-DMNN_USE_LOGCAT=ON \ # 启用 Android 日志
-DMNN_NNAPI=ON \ # 启用 NNAPI 支持
-DMNN_JNI=ON \ # 启用 JNI 接口
-DMNN_VULKAN=ON \ # 启用 Vulkan GPU 加速
-DMNN_OPENGL=ON # 启用 OpenGL GPU 加速3.3 编译产物
编译完成后,会在 build_64/ 目录生成以下动态库:
text
./libMNN_Express.so # MNN Express 高级 API
./libMNN.so # MNN 核心库
./source/jni/libmnncore.so # JNI 桥接库
./libMNN_GL.so # OpenGL 后端
./libMNN_Vulkan.so # Vulkan 后端3.4 编译 ARMv7 库
如需支持 32 位设备:
bash
../build_32.sh \
-DMNN_USE_LOGCAT=ON \
-DMNN_OPENGL=ON4. Linux/Windows/macOS 编译
4.1 使用 CMake 编译
bash
mkdir build && cd build
# 基础编译
cmake .. \
-DMNN_BUILD_CONVERTER=ON \ # 构建模型转换工具
-DMNN_BUILD_TOOLS=ON # 构建性能测试工具
make -j$(nproc)4.2 启用 GPU 支持
OpenCL(适用于 AMD/NVIDIA GPU):
bash
cmake .. \
-DMNN_OPENCL=ON \
-DMNN_SEP_BUILD=OFF
make -j$(nproc)CUDA(仅 NVIDIA GPU):
bash
cmake .. \
-DMNN_CUDA=ON \
-DMNN_CUDA_PROFILE=ON
make -j$(nproc)4.3 编译 Python 接口
bash
cd pymnn/pip_package
python3 setup.py bdist_wheel
pip install dist/*.whl5. 模型转换
5.1 支持的框架
MNN 支持从以下框架转换模型:
- TensorFlow / TensorFlow Lite
- PyTorch (ONNX)
- Caffe
- ONNX
5.2 转换 ONNX 模型
bash
# 使用 MNNConvert 工具
./MNNConvert \
-f ONNX \
--modelFile model.onnx \
--MNNModel model.mnn \
--bizCode biz5.3 转换 TensorFlow 模型
bash
./MNNConvert \
-f TF \
--modelFile frozen_model.pb \
--MNNModel model.mnn \
--bizCode biz5.4 模型量化
将 FP32 模型量化为 INT8:
bash
./quantized.out \
model.mnn \
model_quant.mnn \
images_folder6. C++ 推理示例
6.1 基础推理代码
cpp
#include <MNN/Interpreter.hpp>
#include <MNN/Tensor.hpp>
#include <iostream>
int main() {
// 1. 创建解释器
std::shared_ptr<MNN::Interpreter> net(
MNN::Interpreter::createFromFile("model.mnn")
);
// 2. 创建会话
MNN::ScheduleConfig config;
config.type = MNN_FORWARD_CPU; // 或 MNN_FORWARD_OPENCL, MNN_FORWARD_VULKAN
config.numThread = 4;
MNN::Session* session = net->createSession(config);
// 3. 获取输入输出张量
MNN::Tensor* input = net->getSessionInput(session, nullptr);
MNN::Tensor* output = net->getSessionOutput(session, nullptr);
// 4. 准备输入数据
auto inputTensor = new MNN::Tensor(input, MNN::Tensor::CAFFE);
float* inputData = inputTensor->host<float>();
// 填充输入数据
for (int i = 0; i < inputTensor->elementSize(); i++) {
inputData[i] = 1.0f;
}
// 5. 复制数据到 MNN
input->copyFromHostTensor(inputTensor);
// 6. 执行推理
net->runSession(session);
// 7. 获取输出
auto outputTensor = new MNN::Tensor(output, MNN::Tensor::CAFFE);
output->copyToHostTensor(outputTensor);
float* outputData = outputTensor->host<float>();
std::cout << "Output: " << outputData[0] << std::endl;
// 8. 清理
delete inputTensor;
delete outputTensor;
return 0;
}6.2 编译和运行
bash
g++ inference.cpp \
-o inference \
-I/path/to/MNN/include \
-L/path/to/MNN/lib \
-lMNN \
-std=c++11
./inference7. Python 推理示例
7.1 安装 MNN Python
bash
pip install MNN7.2 推理代码
python
import MNN
import numpy as np
# 1. 创建解释器
interpreter = MNN.Interpreter("model.mnn")
# 2. 创建会话
session = interpreter.createSession({
'numThread': 4,
'backend': 'CPU' # 或 'OPENCL', 'VULKAN'
})
# 3. 获取输入输出
input_tensor = interpreter.getSessionInput(session)
output_tensor = interpreter.getSessionOutput(session)
# 4. 准备输入数据
tmp_input = MNN.Tensor((1, 3, 224, 224), MNN.Halide_Type_Float,
np.random.randn(1, 3, 224, 224).astype(np.float32),
MNN.Tensor_DimensionType_Caffe)
input_tensor.copyFrom(tmp_input)
# 5. 执行推理
interpreter.runSession(session)
# 6. 获取输出
tmp_output = MNN.Tensor(output_tensor.getShape(),
output_tensor.getDataType(),
np.zeros(output_tensor.getShape()).astype(np.float32),
MNN.Tensor_DimensionType_Caffe)
output_tensor.copyToHostTensor(tmp_output)
# 7. 处理结果
output_data = tmp_output.getNumpyData()
print("Output shape:", output_data.shape)
print("Output:", output_data)8. Android 集成
8.1 添加依赖
在 build.gradle 中:
groovy
android {
defaultConfig {
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
}
dependencies {
implementation 'com.alibaba.android:mnn:2.8.0'
}8.2 Java 推理代码
java
import com.taobao.android.mnn.MNNNetInstance;
import com.taobao.android.mnn.MNNImageProcess;
public class MNNInference {
private MNNNetInstance mNetInstance;
private MNNNetInstance.Session mSession;
public void loadModel(String modelPath) {
// 加载模型
mNetInstance = MNNNetInstance.createFromFile(modelPath);
// 创建会话
MNNNetInstance.Config config = new MNNNetInstance.Config();
config.numThread = 4;
config.forwardType = MNNForwardType.FORWARD_CPU.type;
mSession = mNetInstance.createSession(config);
}
public float[] inference(float[] inputData) {
// 获取输入输出张量
MNNNetInstance.Session.Tensor inputTensor =
mSession.getInput(null);
MNNNetInstance.Session.Tensor outputTensor =
mSession.getOutput(null);
// 设置输入
inputTensor.reshape(new int[]{1, 3, 224, 224});
float[] input = inputTensor.getFloatData();
System.arraycopy(inputData, 0, input, 0, inputData.length);
// 执行推理
mSession.run();
// 获取输出
float[] output = outputTensor.getFloatData();
return output;
}
}9. 性能优化
9.1 选择合适的后端
cpp
// CPU(通用,兼容性好)
config.type = MNN_FORWARD_CPU;
// GPU - OpenCL(适用于大多数 GPU)
config.type = MNN_FORWARD_OPENCL;
// GPU - Vulkan(更现代,性能更好)
config.type = MNN_FORWARD_VULKAN;
// GPU - Metal(iOS/macOS)
config.type = MNN_FORWARD_METAL;9.2 使用模型量化
INT8 量化可以减少模型大小 75%,加速推理 2-4 倍:
bash
./quantized.out original.mnn quantized.mnn calibration_images/9.3 使用 FP16
在支持的设备上使用 FP16 可以提升性能:
cpp
config.type = MNN_FORWARD_OPENCL;
config.precision = MNN_LOW; // 使用 FP1610. 参考资料
- https://github.com/alibaba/MNN - MNN GitHub 仓库
- https://mnn-docs.readthedocs.io/ - MNN 官方文档
- https://www.yuque.com/mnn/en - MNN 语雀文档
- https://zhuanlan.zhihu.com/p/455021896 - MNN:GPU 上极其强悍的推理引擎