一. DL模型落地步骤

一般情况下,一个DL任务落地的流程一般包含训练和部署两大部分,具体细分我认为可以分为以下几个步骤:

  • 1. 明确任务目标:首先要明确我们最终要达到一个什么样的效果,假设我们的DL模型是一个函数y=f(x), 送入一张图片x后,模型需要吐出来一个什么样的y(基于此区分不同任务,如分类、检测或分割),然后这个y是否符合预期应该如何评价(评价指标,如recall或precision),eg.: 我们需要一个模型可以将街景图片中的行人数量统计出来。这个时候我们一般会有几个相对较优的方案可以选择:①基于HOG特征的行人检测方案,该方案是传统数字图像处理中行人检测经典方案,依靠纯数字图像特征提取实现,简单但效果不及DL方案;②深度学习方案,如人脸检测或者直接行人检测。人脸检测显然无法适应遮挡场景,所以直接检测人体更加靠谱。此外,视野中的行人的远近会导致目标尺度范围较大,所以应当确定评价指标是否要区分不同尺度的人或者不考虑尺度小于某一比例的行人。此外还需要考虑我们对漏检(FN)和误检(FP)的容忍度,以选择合适的Recall和Precision预期,或者分别加权来确定加权F-Score如何计算。
  • 2. 模型选择与训练:这部分接上面我们以目标检测模型为例,有很多选择,如Anchor-based或Anchor-Free的等等,近几年的模型多的一批,不再一一列举,总之这个模型喂进去一张图,会输出该图中所有检测到的行人的BBox(当然多类检测还会有预测Label)。在模型构建的过程中,也需要考虑利用一些先验知识加一些定制module或者trick,或者在Loss上做文章,训练后的最终模型效果只看测试集上获得的评价指标结果,另外考虑部署的话,还需要提前考虑到自己模型的计算量,以及加的一些算子是否在部署环境中支持良好。在工作中,如果训练模型的和部署的不是同一个人,这种问题就很容易出现,所以提前沟通很有必要。在得到一个符合预期的pytorch模型后,就可以用troch.onnx.export导出对应的onnx模型,这个模型会记录模型结构(输入输出和Graph)和每个算子的参数信息,是可以单独拿来推理的。
  • 3. 部署前准备:拿到的onnx模型推理效果是否和原始pytorch模型一致是需要再次验证的,因为导出onnx的过程有可能出错。验证可以通过只测试一个样本,然后精确验证输出数据是否和原型一致,以及会不会出现推理库不支持的算子;也可以拿整个测试集用推理库的python接口跑一遍测试效果,但这样会比较麻烦,因为预处理和输出数据后处理以及整个推理流程得再去弄个python实现。此外,为提高效率,通常是需要做量化的(直接用半精度或int8训练就不需要量化了),量化一般都有开源工具可用,思路也比较简单,首先是输入后加转量化后类型的cast,输出前加转单精度的cast,这样能保证我们只给模型float类型的数据即可;另外每个内部算子如果有参数还需要转为指定量化类型。量化后的模型和原始模型的推理效果肯定有差异,比如行人检测有可能漏检一些小目标之类的,我们需要保证精度下降在可接受范围内(一般1%),这里又会用到评价指标。量化成功那么就可以使用推理库运行了。
  • 4. 部署和测试:考虑到效率,量化后的onnx我们一般会用C++推理库部署,像ONNXRuntime也提供了Python接口,但用C++可以方便使用多线程以及C++语言本身的高效性,无论在云端还是在移动端部署C++都是首选。以云端部署为例,我们的C++部署环境会提供一套完整的调用流程,最终会打包为一个SDK提供出去,其内部核心是调用推理库完成DL模型推理,但其前后还需要很多模块配合,如预处理和后处理模型、配置文件解析模块、资源管理模块、输出模块。这些模块一般都会对应有一个各自的Class继承体系,配合配置文件和如工厂模式的设计策略还可以实现一套SDK能实现多种能力。部署完成需要测试效率和效果是否符合预期,还需要考虑多线程调用环境下的稳定性。

小结:以上流程中很多细微的点没有讲到,但大概总结一下要完成以上流程需要具备的一些能力:

  • 初级:能训练开源模型,简单调整模型结构,导出float32的onnx模型,调用开源推理库开发demo进行推理,保证效果不保证效率;
  • 中级:能将开源算法应用到业务场景并针对性对模型结构调整,未开源算法能完成复现,训练过程可控,熟练使用一些结构设计trick和训练trick,导出onnx并能完成量化,能解决或规避算子不支持或支持差的问题,能在现有C++推理框架下开发要部署的模型的相关模块;
  • 高级:我猜啊,首先要能设计模型确定方案,并预判某一模型方案在具体业务上的可行性,提前避免资源浪费;应该不再上手训模型了吧,也不会亲自导模型了吧,因为这些任务相对较独立而且目标很明确,扔给子线程去做最后用的时候同步一下就OK了。部署的框架这块需要明确整体架构,保证接口稳定可靠,因为SDK接口是提供给外部的,不能经常动,接口类亲自设计,实现类code review把关,内部核心推理库也是把关整体架构,kernel实现code review把关。到这个级别深耕的方向大概有两个:要么深入研究算法模型,要么深入研究部署。
  • 再高就是,见识太少,是我无法描述的level了,或许真的宇宙的尽头是编制吧

二. 一个小项目

ONNXRuntime是微软出品的机器学习推理库,目前两大深度学习训练框架Pytorch和Tensorflow训练后的模型都可以导出为onnx格式,可以直接用ONNXruntime推理。打算用CIFAR-100数据集训练一个分类模型进行部署。确定一下方案:

  1. 总体目标:训练一个pytorch模型,CIFAR-100数据集测试集acc达到90%;部署后推理效率达到50ms/张, 部署平台为window10+3050Ti+RX5800h.
  2. 模型选择与训练:用VGG结构+ResNet来构建,尽可能轻量。
  3. 导出onnx并量化
  4. 部署:单线程调用ONNXRunTime pythonAPI的demo跑通,单线程调用C++API的demo跑通;进阶完成多线程调用。

ONNXRuntime学习笔记(一)的更多相关文章

  1. ONNXRuntime学习笔记(四)

    接上一篇在Python端的onnx模型验证结果,上一篇在Pytorch和onnxruntime-gpu推理库上分别进行效果效率统计分析,结论要比最初设置的50ms高很多,这一篇我将在C++端写个测试代 ...

  2. ONNXRuntime学习笔记(二)

    继上一篇计划的实践项目,这篇记录我训练模型相关的工作. 首先要确定总体目标:训练一个pytorch模型,CIFAR-100数据集测试集acc达到90%:部署后推理效率达到50ms/张, 部署平台为wi ...

  3. ONNXRuntime学习笔记(三)

    接上一篇完成的pytorch模型训练结果,模型结构为ResNet18+fc,参数量约为11M,最终测试集Acc达到94.83%.接下来有分两个部分:导出onnx和使用onnxruntime推理. 一. ...

  4. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  5. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  6. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  7. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  8. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  9. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

随机推荐

  1. mac phpStrom 卸载

    cd ~/Library/Logs/cd ~/Library/Application\ Supportcd ~/Library/Preferences/cd ~/Library/Caches/

  2. mysql行锁、表锁。乐观锁,悲观锁

    锁定用于确保事务完整性和数据库一致性. 锁定可以防止用户读取其他用户正在更改的数据,并防止多个用户同时更改相同的数据. 如果不使用锁定,数据库中的数据可能在逻辑上变得不正确,而针对这些数据进行查询可能 ...

  3. PowerDesigner生成MySQL脚本,表和字段进行转义

    打开Power Designer数据库建模工具,软件基本信息如下 如果PowerDesigner内置的(table_option)表物理操作没有,请看以下步骤 打开 Edit Current DBMS ...

  4. remote debug 的详细配置

    一.remote debug 的简单介绍 何为远程debug,项目写完后就需要进入到测试环节,将代码打包发布到测试环境(服务器)上.这时候测试人员测试出一个缺陷(bug).由于代码已经发布到测试环境, ...

  5. Mybatis入门程序(二)

    1.实现需求 添加用户 更新用户 删除用户 2.添加用户 (1)映射文件User.xml(Mapper)中,配置添加用户的Statement <!-- 添加用户: parameterType:指 ...

  6. js技术之分割split()

    案例:把所有单词以空格为分割并将首字母转为大写 <!DOCTYPE html><html lang="en"><head> <meta c ...

  7. i2c总线编码

    i2c总线编码 发送启动信号S 在同步时钟线SCL 为高电平时,数据线出现的由高到低的下降沿. 启动信号子程序STA 1 /************************************** ...

  8. (stm32f103学习总结)—stm32 PMW输出实验

    一.PWM简介 PWM是 Pulse Width Modulation 的缩写,中文意思就是脉冲宽度调 制,简称脉宽调制.它是利用微处理器的数字输出来对模拟电路进行控 制的一种非常有效的技术,其控制简 ...

  9. C#编写一个简易的文件管理器

    编写一个简易的文件管理器,通过本次实验,练习 TreeView.ListView 和SplitContainer 控件的使用,同时熟悉 C#文件系统的操作方法以及 File 类和 Directory类 ...

  10. webpack的安装 以及 问题 以及 作用

    参考链接: https://blog.csdn.net/Rnger/article/details/81086938     https://blog.csdn.net/qq_38111015/art ...