• IIANews微官网
    扫描二维码 进入微官网
    IIANews微信
    扫描二维码 关注微信
    移动客户端
  • English
2020OEM机械设计技术研讨会云会议
传感器

深度学习代码生成 | 如何快速将推理模型部署到生产环境中

  2020年05月14日  

  如今,深度学习已在商业领域普及,现实中对训练好的推理模型的应用,已可见于各行各业,但具体应用的开发仍大量依赖一些大公司的框架或产品。他们有些提供云端的接口,也有些提供基于安卓的智能终端上的 apk,换句话说,核心其实并没有掌握在自己手里,想深度定制就难了。

  而能够自行采用 TensorRT、cuDNN 或 CUDA,或者利用 Intel MKL-DNN,又或者针对 ARM 的 Mali GPU 或 Neon 核实现深度学习应用的,与普遍存在的需求相比仍在少数。

  原因可能是下面中的一条或多条:

  缺乏有相关编程经验的工程师
  目标平台不能用 TensorRT,自己基于 cuDNN 或原生 CUDA 写太难了
  用 TensorRT 还能搞定 NVIDIA GPU,ARM 实在无能为力
  找来一套开源代码,BUG 好多,动不动就死了,死了,了
  性能不达标但量化好坑,FP32 的模型转 FP16/INT8 可咋整
  有 Intel Xeon 处理器没 NVIDIA GPU,还得学 MKL-DNN 框架

  【编者注:深度学习不仅训练要用到大量数据和算力,其推理也很耗计算资源,因此在实际应用中必须利用如 MKL-DNN、CUDA、ARM Compute 等在支持张量计算的硬件如 Intel Xeon、NVIDIA GPU 和 ARM Mali 或 Neon 核上实现才能获得满足实际要求的性能】

  那有没有办法又快又稳地在不同目标平台上用 C++ 轻松实现训练好的推理模型呢?

  眼见为实,我们先看一个例子。

  假设我们有一个训练好的 LSTM 模型,存储在 lstmnet.mat 文件中【编者注:它可以是在开源框架中训练后按ONNX标准格式导入MATLAB的,也可以是在MATLAB中训练产生的】,我们写了一个 MATLAB 函数 lstmnet_predict.m 来调用这个模型进行推理,如下:

  function out =lstmnet_predict(in)
  persistent mynet;
  if isempty(mynet)
      mynet =coder.loadDeepLearningNetwork('lstmnet.mat');
  end
  out = predict(mynet,in);

  采用以下脚本【编者注:或者通过 GPU Coder 那个带向导提示的图形化 APP】,即可为上述推理函数产生 C++ 代码。

  % 为代码生成进行配置
  cfg = coder.gpuConfig('mex');
  cfg.TargetLang = 'C++';
  cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
  % 定义目标函数的输入参数
  matrixInput = coder.typeof(double(0),[3 Inf],[falsetrue]);
  % Run the codegen command.
  codegen -configcfglstmnet_predict-args{matrixInput}-report

  自动生成的 C++ 代码看起来是下面这个样子的:

  事实上,通过修改代码生成配置,也就是下面这几行代码,我们就可以为不同的目标平台生成不同的代码了。

  % 为代码生成进行配置
  cfg = coder.gpuConfig('mex');
  cfg.TargetLang = 'C++';
  cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');

  譬如,如果我们要基于 TensorRT 来生成嵌入式 GPU(如Jetson Nano)上跑的代码:

  % 为代码生成进行配置
  cfg = coder.gpuConfig('lib');
  cfg.TargetLang = 'C++';
  cfg.GenCodeOnly = true;
  cfg.Hardware = coder.hardware('NVIDIA Jetson');
  cfg.DeepLearningConfig = coder.DeepLearningConfig('tensorrt');
  cfg.GpuConfig.ComputeCapability = '7.0';
  % cfg.DeepLearningConfig.DataType= 'fp16';
  % 定义目标函数的输入参数
  matrixInput = coder.typeof(double(0),[3 Inf],[falsetrue]);
  % Run the codegen command.
  codegen -configcfglstmnet_predict-args{matrixInput}-report

  这里,我们可以指定硬件平台与兼容版本,甚至通过增加一行 DataType 的配置就可以从默认的 FP32 转而生成 FP16 的推理代码了。
 
  【编者注:转成 INT8 稍微复杂一些,因为那不仅要防止溢出,还必须进行校验校准。以一个图像分类网络如 mobilenet v2 或 resnet-50 为例,如果要产生 INT8 的代码,我们需要准备一个数据集用来在代码生成时进行校验校准,但代码生成时的配置其实也就是 3 行脚本:

  cfg.DeepLearningConfig.DataType ='int8';
  cfg.DeepLearningConfig.DataPath ='calib_dataset';
  cfg.DeepLearningConfig.NumCalibrationBatches = 50;

  另外,最新的MATLAB R2020a有一个Deep Network Quantizer附加功能可以用来简化这一工作。】

  再譬如,如果要针对 ARM Neon 生成 C++ 代码,脚本如下:

  % 为代码生成进行配置
  cfg = coder.config('lib');
  cfg.TargetLang = 'C++';
  cfg.GenCodeOnly = true;
  dlcfg = coder.DeepLearningConfig('arm-compute');
  dlcfg.ArmArchitecture = 'armv7';
  dlcfg.ArmComputeVersion = '19.05';
  cfg.DeepLearningConfig = dlcfg;
  % cfg.Hardware =coder.hardware('Raspberry Pi');
  % 定义目标函数的输入参数
  matrixInput = coder.typeof(double(0),[3 Inf],[falsetrue]);
  % Run the codegen command.
  codegen -configcfglstmnet_predict-args{matrixInput}-report

  这里用到了 ARM Compute 库,我们不仅指定了 ARM 的架构版本,还指定了 Compute 库的版本。

  【编者注:Arm Compute Library 与 MATLAB 的版本最好按帮助文档的提示进行对应,因为那是验证过而且对应优化过的,能保证稳定性和性能最优;另外,由于编译器兼容性的问题,建议参考帮助文档,自行从源代码编译安装 ARM Compute library 到你的嵌入式硬件上。】

  给 ARM Neon 生成的代码看起来是这样子的:

    【编者注#1:显然,仅仅生成 C++ 代码是不够的,推理模型还含有数以百万计的训练好的参数呢,那肯定也是一并生成好了的,而且在生成的代码中会自动完成这些数据文件的加载和参数初始化,您在应用程序中只需要对接口进行调用即可】。

  【编者注#2:有些深度学习推理模型的接口也很复杂,生成后调用起来也要搞清楚很多东西才能玩得转,能不能生成一个主程序给做个参考呀?答案是肯定的,你可以把 MATLAB 里写的前处理和后处理也包含在代码生成中,然后再在代码生成配置中增加这样一行即可:cfg.GenerateExampleMain = 'GenerateCodeAndCompile';】。

  【编者注#3:自动生成的文件这么多,能自动产生 makefile 吗?必须能,不仅可以自动产生 makefile,还可以自动通过调用开发机或者目标机的编译器,以本地编译或交叉编译的方式进行编译,从而产生可执行文件、动态库或静态库】

  MATLAB 都能为深度学习推理模型生成哪些目标平台的代码呢?

  当前 MATLAB R2020a 支持的目标平台包括:

  ●NVIDIA GPU,支持 TensorRT 和 cuDNN,兼容 Windows、Linux 及基于 Linux 的嵌入式 GPU 平台(如 NVIDIA Jetson 系列和 Drive 系列)

  ●ARM Cortex-A 系列,含 Neon 核,支持 ARM Compute Library

  ●ARM Mali GPU,支持 ARM Compute Library

  ●Intel Xeon,AVX/SSE 指令集,支持 Intel MKL-DNN

标签:MathWorks MATLAB我要反馈
最新视频
洞察先机,后疫情时代中国制造业如何重塑竞争力!   
凯本隆拍了拍你:快来见证「破坏性试验升级版」   
魏德米勒
专题报道
2020年4月16日,由智能网联合国际工业自动化、造车网共同打造的“线上云展”——2020第二届中国智能展览会正式上线。本季展会为期10天,继续围绕“智能领跑,无限未来”的主题打造七大虚拟展厅,以强大的科技核心本源为参展商、投资商与展会观众之间筑建持续畅通的信息桥梁,助力中国制造业新的增长。
企业通讯
自动引导车辆(AGV)的安全解决方案
自动引导车辆(AGV)的安全解决方案

2020年7月16日14:00至16:00,皮尔磁《自动引导车辆(AGV)的安全解决方案》即将开播!

E+H极致创新 兼程并进
E+H极致创新 兼程并进

选择Endress+Hauser作为校准服务伙伴,您可以高效完成仪表校准,轻松进行沟通,简化预算规划。

在线会议

社区

北京赛车Pk10全自动下注q群微信群机器人 2019白菜网送彩金 免费送彩金可提款 2019百家乐18元送彩金 彩金宏辉送彩金 无需充值送彩金的彩票平台 全讯网送彩金 银行卡送彩金 全讯网送彩金 送彩金彩票网