深度学习移动端部署方案 --- MNN端侧推理引擎
-
MNN简介及应用场景 一个轻量级的深度学习端侧推理引擎,核心解决深度神经网络模型在端侧推理运行问题,涵盖深度神经网络模型的优化、转换和推理。 MNN为提供面向不同业务算法场景,不同训练框架,不同部署环境的简单、高效、安全的端侧推理引擎 MNN 。能够抹平 Android 和 iOS 的差异,碎片设备之间的差异,不同训练框架的差异,实现快速的在端侧部署运行,并且能够根据业务模型进行 OP 灵活添加和 CPU/GPU 等异构设备深入性能优化。 深度学习模型应用流程: 模型训练---->模型导出----->模型转换------>在线部署----->在线推理预测 MNN主要用来解决模型转换, 在线部署和推理这几个阶段(虽然MNN也在逐步提供模型训练一站式方案) Pytorch应用示例 模型离线训练 导出模型 MNN不直接支持Pytorch(直接支持的框架:TensorFlow,Caffe),但支持ONNX标准格式与MNN交流,Pytorch里使用torch.onnx.export接口导出ONNX格式的模型文件 def save_model(m, loss, base_name, all_model=False): save_path = r/home/hc/trainned_weight_params model_name = str(type(m)) name = %s/%s_epoch%d_loss%.4f.pth % (save_path, base_name, epoch_num, loss) name_onnx = name + .onnx print(>>>save model:, model_name, name) if all_model: torch.save(m, name) else: torch.save(m.state_dict(), name) # create the right input shape m_input_data = torch.randn(1, 4) # switch pytorch model to onnx model torch.onnx.export(m, m_input_data, name_onnx, verbose=True) 模型转换 使用MNN提供的onnx模型转换工具就可以转换成MNN可以解析的模型文件 官方文档: https://github.com/alibaba/MNN/blob/master/tools/converter/README.md ./MNNConvert --framework ONNX --modelFile pfld-lite.onnx --MNNModel pfld-lite.mnn --bizCode MNN 模型部署 使用MNN API加载模型和相关配置,然后设置输入和输出 示例代码(4输入3输出): // load model and set config (work thread num and platform auto ALSnet = MNN::Interpreter::createFromFile((const char*)model_path); MNN::ScheduleConfig netConfig; netConfig.type = MNN_FORWARD_CPU; netConfig.numThread = 4; // set model precison MNN::BackendConfig backendConfig; backendConfig.precision = MNN::BackendConfig::Precision_High; netConfig.backendConfig = &backendConfig; auto session = ALSnet->createSession(netConfig); auto inputTensor = ALSnet->getSessionInput(session, NULL); auto net_input_data = inputTensor->host<float>(); // get input data net_input_data[0] = block_r[round] / (pixel_cnt / 4); net_input_data[1] = block_g[round] / (pixel_cnt / 4); net_input_data[2] = block_b[round] / (pixel_cnt / 4); // run session { ALSnet->runSession(session); } // get output data auto outputTensor = ALSnet->getSessionOutput(session, NULL); predDiff[round].r = outputTensor->host<float>()[0]; predDiff[round].g = outputTensor->host<float>()[1]; predDiff[round].b = outputTensor->host<float>()[2];
上一篇:
通过多线程提高代码的执行效率例子