ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

MNN 示例工程实战指南:C++ 推理、Python 训练到移动端部署的完整 Demo 路线

MNN 示例工程实战指南:C++ 推理、Python 训练到移动端部署的完整 Demo 路线 MNN 示例工程实战指南C 推理、Python 训练到移动端部署的完整 Demo 路线【免费下载链接】MNNMNN: A blazing-fast, lightweight inference engine battle-tested by Alibaba, powering high-performance on-device LLMs and Edge AI.项目地址: https://gitcode.com/GitHub_Trending/mn/MNNMNN 仓库内置了一组覆盖“模型转换 → 推理 → 移动端集成”全流程的官方示例工程分别位于 demo/exec、pymnn/examples 与 project/android、project/ios 目录下。本文以官方文档中的示例工程为主线逐一讲解姿态检测、图像分割、图像识别、Python Session/表达式推理、模型微调以及 Android/iOS 工程的编译运行方法并结合各 Demo 源码剖析其中的前处理、Session 配置与后处理实现细节帮助读者快速上手 MNN 的典型应用开发。C 推理 Demo编译生成 Demo 可执行文件按照 从源码编译 的说明使用仓库顶层的 CMakeLists.txt 打开MNN_BUILD_DEMO选项即可编译出全部 Demo 程序。Linux/macOS 下操作如下来源demo/exec/README.mdcd path/to/MNN mkdir build cd build cmake -DMNN_BUILD_DEMOON .. make -j8Windows 下则使用 NMake 生成器cd path/to/MNN mkdir build cd build cmake -G NMake Makefiles -DCMAKE_BUILD_TYPERelease -DMNN_BUILD_DEMOON .. nmake从 demo/exec/CMakeLists.txt 的源码可以看到Demo 目录注册了十余个可执行目标包括multiPose.out、segment.out、pictureRecognition.out、pictureRecognition_module.out、multithread_imgrecog.out、transformerDemo.out、nluDemo.out等每个目标统一链接${MNN_DEPS}依赖库。本文聚焦其中三个经典示例。三个 Demo 的推理代码都遵循同一个 Interpreter-Session 骨架Interpreter::createFromFile(modelPath)加载.mnn模型配置ScheduleConfig后端类型、线程数等后createSessionresizeTensorresizeSession设定输入形状通过ImageProcess完成缩放、通道转换与归一化把图像数据直接写入输入 TensorrunSession执行推理再按输出 Tensor 的名字或顺序取结果。其中第 4 步正是文档反复强调模型转换时要加--keepInputFormat0的原因使用 Interpreter-Session 接口时把输入由 NHWC 转换为 NC4HW4 布局后ImageProcess的convert可以直接把像素数据按目标布局写进设备内存省去一次显式布局转换。该参数的完整语义可参考 模型转换工具文档其“说明 2”专门指出如果使用 Interpreter-Session C 接口开发可以考虑转换时使用--keepInputFormat0。姿态检测MultiPose代码位置demo/exec/multiPose.cpp步骤下载 posenet 项目中的原始 TensorFlow 模型model-mobilenet_v1_075.pbfrozen model使用 模型转换工具 转换为 MNN 模型转换时加上参数--keepInputFormat0【把输入由 NHWC 转换为 NC4HW4 布局】例如./MNNConvert -f TF --modelFile model-mobilenet_v1_075.pb --MNNModel model.mnn --bizCode biz --keepInputFormat0执行姿态检测./multiPose.out model.mnn input.png pose.png效果示例输入图与检测结果关键点被红色圆点标出。从源码结构看该 Demo 的关键实现细节包括网络配置ScheduleConfig指定MNN_FORWARD_CPU且numThread 4若模型输入是动态 batch则调用resizeTensor(input, {1, 3, targetHeight, targetWidth})将其固定为 513×513 附近、宽高均为 16 的倍数加 1 的形状MODEL_IMAGE_SIZE 513、OUTPUT_STRIDE 16。前处理ImageProcess配置mean {127.5, 127.5, 127.5}、normal {2/255, 2/255, 2/255}即把像素从[0, 255]归一化到[-1, 1]sourceFormat CV::RGBA、destFormat CV::RGB配合一个 postScale 矩阵完成原图到模型输入尺寸的缩放。后处理posenet 模型的四个输出节点分别为heatmap、offset_2OFFSET_NODE_NAME、displacement_fwd_2、displacement_bwd_2。decodeMultiPose先在热力图上做半径为LOCAL_MAXIMUM_RADIUS的局部极大值过滤阈值SCORE_THRESHOLD 0.5再按NMS_RADIUS 20做非极大值抑制通过正向/反向位移场沿PoseChain骨架边遍历把单个人体的 17 个关键点串起来单个人体综合得分低于MIN_POSE_SCORE 0.25时丢弃最多输出MAX_POSE_DETECTIONS 10个人体。结果绘制drawPose对得分超阈值的每个关键点画半径为 3 的圆最终用stb_image_write输出 PNG。这些常数都以宏形式定义在文件头部若要针对自己的 pose 模型调整检测灵敏度直接修改对应宏即可。图像实例分割Segment代码位置demo/exec/segment.cpp步骤下载 deeplabv3 分割模型deeplabv3_257_mv_gpu.tfliteTensorFlow 官方提供的 DeepLabv3 MobileNet 分割模型使用 模型转换工具 转换为 MNN 模型转换时加上参数--keepInputFormat0【把输入由 NHWC 转换为 NC4HW4 布局】./MNNConvert -f TFLITE --modelFile deeplabv3_257_mv_gpu.tflite --MNNModel model.mnn --bizCode biz --keepInputFormat0执行分割./segment.out model.mnn input.png result.png效果示例result.png是一张二值掩膜图人体区域为白色255其余为黑色0。从源码看这个 Demo 展示了 Interpreter 接口与 Express表达式接口混用的典型写法推理部分使用默认的ScheduleConfig后端自动选择创建 Session并同样通过ImageProcess做前处理mean 127.5、normal 1/127.5sourceFormat RGBA、destFormat RGB、filterType BILINEAR后处理则绕开了手写循环先Variable::create(Expr::create(outputTensor))把设备上的输出 Tensor 包装成 VARP再依次_Convert(output, NHWC)→_Reshape(output, {-1, channel})→_TopKV2(output, 1)取每个像素概率最高的一类随后用_Select(_Equal(index, 15), 255, 0)判断“是否为 person 类类别索引 15”最后_Castuint8_t得到掩膜并写出 PNG。源码中还附了一行注释给出的更快写法_Equal(index, 15) * 255可直接替代_Select对性能敏感时可以参考。仓库内置的 demo/model 目录里也提供了 MobileNet 与 SqueezeNet 对应的测试图片如 testcat.jpg没有素材时可直接拿来跑通流程。图像识别PictureRecognition代码位置demo/exec/pictureRecognition.cpp准备 mobilenet 模型并转换为 MNN 格式Caffe 权重转换命令可参考 Android Demo README 中 MobileNet_v2 的示例。程序参数含义第一个参数MNN 模型地址第二个参数图像地址追加的参数更多待识别图像地址源码中shape[0] argc - 2即按传入图像数自动设置 batch。示例./pictureRecognition.out moiblenet.mnn Test.jpg输出Cant Find type4 backend, use 0 instead For Image: TestMe.jpg 386, 0.419250 101, 0.345093 385, 0.214722 347, 0.012001 346, 0.002010 348, 0.001876 294, 0.001247 349, 0.000761 354, 0.000443 345, 0.000441第一行表示识别出可能性最大的类别编号在相应的synset_words.txt中查找对应的类别如demo/model/MobileNet/synset_words.txt。源码层面这个 Demo 有三个值得注意的写法net-setCacheFile(.cachefile)与net-setSessionMode(Interpreter::Session_Backend_Auto)开启执行配置缓存与后端自动调优并setSessionHint(Interpreter::MAX_TUNING_NUMBER, 5)限制调优尝试次数首次运行“Cant Find type4 backend, use 0 instead”这类提示表示请求的某后端不可用、自动回退到 CPU后端枚举定义见 include/MNN/MNNForwardType.h通过getSessionInfo打印MEMORY显存/内存占用 MB、FLOPS浮点运算量与BACKENDS实际使用的后端类型三类 Session 信息方便快速评估模型规模与调度结果前处理使用mean {103.94, 116.78, 123.68}、normal 0.017、destFormat BGR的 Caffe 风格归一化多张图像逐张ImageProcess::convert写入同一个 batch 输入 Tensor 的不同 offset最后统一copyFromHostTensor并一次runSession完成批量推理。Python Demo以下示例默认已通过pip install MNN或从源码安装 Python 包资源文件mobilenet_v1.mnn与 ImageNet 验证图ILSVRC2012_val_00049999.JPEG以压缩包形式在官方文档中提供解压后即可按如下方式运行。Session 图片分类代码位置pymnn/examples/MNNEngineDemo/包含三个文件mobilenet_demo.py使用 Session 进行图片分类示例mobilenet_demo_2.py使用 Runtime 创建 Session 进行图片分类示例gpu_session_demo.py使用 Session 的 GPUOpenCL后端进行图片分类示例。示例输出$ unzip mobilenet_demo.zip $ python mobilenet_demo.py mobilenet_demo/mobilenet_v1.mnn mobilenet_demo/ILSVRC2012_val_00049999.JPEG Load Cache file error. expect 983 output belong to class: 983 $ python mobilenet_demo_2.py mobilenet_demo/mobilenet_v1.mnn mobilenet_demo/ILSVRC2012_val_00049999.JPEG Load Cache file error. MNN use low precision capsule object NULL at 0x7fdd0185a270 (True,) MNN use low precision memory_info: 22.382057MB flops_info: 568.792175M backend_info: 13 expect 983 output belong to class: 983 $ python gpu_session_demo.py mobilenet_demo/mobilenet_v1.mnn mobilenet_demo/ILSVRC2012_val_00049999.JPEG Testing gpu model calling method Load Cache file error. MNN use high precision Cant Find type3 backend, use 0 instead Cant Find type3 backend, use 0 instead Run on backendtype: 13 expect 983 output belong to class: 983三个脚本的差异恰好对应三种 Session 创建方式mobilenet_demo.py最简路径——MNN.Interpreter(model)后直接createSession()传入{precision: low}配置mobilenet_demo_2.py先MNN.Interpreter.createRuntime(config)显式创建 Runtime再createSession(config, runtimeinfo)并演示用getSessionInfo(session, 0/1/2)分别读取内存占用MB、FLOPS 与后端类型三类信息便于在 Python 侧做调度诊断gpu_session_demo.pyconfig[backend] OPENCL、config[precision] high指定 GPU 后端net.setSessionMode(9)对应Session_Backend_Auto后台调优setSessionHint(0, 20)设置调优次数上限运行结束后updateCacheFile落盘缓存。输出中的 “Cant Find type3 backend, use 0 instead” 表示当前环境缺少 OpenCL 后端而回退 CPU属于正常的降级提示而非错误。三个脚本的前处理逻辑一致cv2 读图BGR→ 翻转为 RGB →cv2.resize到 224×224 → 减均值{103.94, 116.78, 123.68}乘0.017→transpose成 NCHW 的float32numpy 数组再用MNN.Tensor(..., MNN.Tensor_DimensionType_Caffe)包装后copyFrom到输入 Tensor输出则通过copyToHostTensor拷回 host 侧避免 NC4HW4 布局带来的读取歧义np.argmax取最大类别该验证图的标准类别是 983。表达式图片分类代码位置pymnn/examples/MNNExpr/其中 mobilenet_demo.py 使用 MNN-Express表达式接口$ python mobilenet_demo.py mobilenet_demo/mobilenet_v1.mnn mobilenet_demo/ILSVRC2012_val_00049999.JPEG expect 983 output belong to class: 983与 Session 写法相比表达式路径更简洁MNN.nn.load_module_from_file(model, [input], [MobilenetV1/Predictions/Reshape_1])按输入/输出 Tensor 名加载模型MNN.expr.placeholder([1,224,224,3], MNN.expr.NHWC)创建 NHWC 输入MNN.expr.convert完成 NC4HW4 转换后net.forward([input_var])一步得到输出。同目录下还有 gpu_express_demo.py、gpu_io_interface.py 与 mnn_numpy_cv_demo.py可分别参考 GPU 表达式调用、GPU 输入输出接口与 numpy/CV 互操作写法。模型训练代码位置pymnn/examples/MNNTrain/。官方文档记载的测试代码包含mnist使用 mnist 数据训练模型并测试准确率mobilenet_finetune使用 MobileNetV2 在自己的数据集上 finetune 一个图像分类器module_save演示模型权值的存储和加载quantization_aware_training训练量化Quantization Aware Training示例。当前仓库中该目录实际包含 mnisttrain_mnist.py、dataset.py、mobilenet_finetunemobilenet_transfer.py、finetune_dataset.py、module_savetest_save.py、grad_test.py与 simplegrad_loss.py、solve_equation.py等梯度/自动微分小例四类子目录文档提到的quantization_aware_training在现有目录中未直接对应运行训练类示例时以仓库内实际脚本为准。mnist 示例无需下载资源用法如下$ pip install mnist $ python train_mnist.py train loss: 2.3346531 train loss: 0.28027835 train loss: 0.26191226 train loss: 0.09180952 train loss: 0.14287554 train loss: 0.14296289 train loss: 0.060721636 train loss: 0.037558462 train loss: 0.11289845 train loss: 0.04905951 Epoch cost: 47.505 s. Save to 0.mnist.mnn test acc: 96.25 %训练完成后直接保存为0.mnist.mnn说明 MNN 的训练产物本身就是可部署的 MNN 模型文件。mobilenet_finetune 示例需要自行解压model.zip、train_dataset.zip、test_dataset.zip三组资源然后运行$ unzip model.zip train_dataset.zip test_dataset.zip $ python mobilenet_transfer.py --model_file mobilenet_v2_tfpb_train_public.mnn --train_image_folder train_images --train_txt train.txt --test_image_folder test_images --test_txt test.txt --num_classes 1000需要说明的是文档在该示例下标注了 “当前版本不支持 FixModule无法执行该示例”运行时报AttributeError: module MNN.nn has no attribute FixModule因此在缺少MNN.nn.FixModule接口的版本中应把它当作 API 参考而非可跑通的脚本。module_save 演示了模型权值的存储和加载$ python test_save.py 0.0004 10Android Demo代码位置project/android/demo详细步骤见 project/android/demo/README.md。环境准备安装Android Studio与NDK模型下载与转换先编译MNNConvert已编译可跳过cd MNN mkdir build cd build cmake -DMNN_BUILD_CONVERTERON .. make -j8然后下载模型可以直接执行sh ../tools/script/get_model.sh脚本位于 tools/script会自动完成模型下载与转换也可以按 README 手动转换例如 MobileNet_v2Caffe 格式./MNNConvert -f CAFFE --modelFile mobilenet_v2.caffemodel --prototxt mobilenet_v2_deploy.prototxt --MNNModel mobilenet_v2.caffe.mnn mv mobilenet_v2.caffe.mnn ../resource/model/MobileNet/v2/README 中还给出了 SqueezeNet_v1.1 与 DeepLab_v3TFLite两组同样格式的转换命令编译运行使用 Android Studio 打开demo目录在local.properties中指定sdk.dir与ndk.dir即可编译执行。效果示例iOS Demo模型下载与转换首先编译如果已编译可以跳过MNNConvertcd MNN mkdir build cd build cmake -DMNN_BUILD_CONVERTERON .. make -j8然后下载并转换模型切到编译了 MNNConvert 的目录如上为 build 目录执行sh ../tools/script/get_model.sh该脚本会下载 MobileNet、SqueezeNet 等示例模型并调用MNNConvert转成.mnn文件。工程编译代码位置project/ios。使用 Xcode 打开project/ios/MNN.xcodeprojtarget选择demo即可编译运行。效果示例社区贡献示例官方文档同时欢迎开发者提交自己的 MNN 示例项目可通过仓库 issue 渠道提交审核通过后展示在文档中。社区围绕 MNN 沉淀的示例方向包括MobileNet/YOLOv8 等分类检测模型部署、Stable Diffusion 文生图、ChatGLM 等 LLM 推理、嵌入式设备部署、车道线检测、人脸检测/识别/跟踪、视频抠图、SuperGlue 关键点匹配、OCR、语音合成与虚拟角色面捕系统等。这些项目的具体用法需要参考各自代码仓库。小结示例工程的参考价值示例入口学到的核心能力multiPosedemo/exec/multiPose.cppNC4HW4 输入布局、ImageProcess 前处理、多输出 Tensor 的后处理解码segmentdemo/exec/segment.cppSession 推理 Express 表达式后处理Convert/Reshape/TopKV2/SelectpictureRecognitiondemo/exec/pictureRecognition.cpp缓存文件、后端自动调优、SessionInfo 诊断、batch 推理Python Session 三例pymnn/examples/MNNEngineDemo/三种 Session 创建方式、OpenCL 后端配置、Tensor host 拷贝Python Expresspymnn/examples/MNNExpr/mobilenet_demo.pyModule 加载、placeholder/convert 的 NHWC-NC4HW4 转换MNNTrainpymnn/examples/MNNTrain/训练-保存-部署一体化、微调与梯度接口Android / iOSproject/android/demo、project/iosMNNConvert 编译、模型脚本化下载转换、原生工程集成以上示例覆盖了从桌面命令行到移动端的典型链路先按 docs/tools/convert.md 用MNNConvert准备模型推理类 C 接口建议加--keepInputFormat0再对照相应 Demo 的“加载 → resize → 前处理 → 推理 → 后处理”骨架替换为自己的模型输入输出即可快速搭建应用原型。【免费下载链接】MNNMNN: A blazing-fast, lightweight inference engine battle-tested by Alibaba, powering high-performance on-device LLMs and Edge AI.项目地址: https://gitcode.com/GitHub_Trending/mn/MNN创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表