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 中:
gradle
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 上极其强悍的推理引擎