ONNXRuntime学习笔记(一)
一. 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数据集训练一个分类模型进行部署。确定一下方案:
- 总体目标:训练一个pytorch模型,CIFAR-100数据集测试集acc达到90%;部署后推理效率达到50ms/张, 部署平台为window10+3050Ti+RX5800h.
- 模型选择与训练:用VGG结构+ResNet来构建,尽可能轻量。
- 导出onnx并量化
- 部署:单线程调用ONNXRunTime pythonAPI的demo跑通,单线程调用C++API的demo跑通;进阶完成多线程调用。
ONNXRuntime学习笔记(一)的更多相关文章
- ONNXRuntime学习笔记(四)
接上一篇在Python端的onnx模型验证结果,上一篇在Pytorch和onnxruntime-gpu推理库上分别进行效果效率统计分析,结论要比最初设置的50ms高很多,这一篇我将在C++端写个测试代 ...
- ONNXRuntime学习笔记(二)
继上一篇计划的实践项目,这篇记录我训练模型相关的工作. 首先要确定总体目标:训练一个pytorch模型,CIFAR-100数据集测试集acc达到90%:部署后推理效率达到50ms/张, 部署平台为wi ...
- ONNXRuntime学习笔记(三)
接上一篇完成的pytorch模型训练结果,模型结构为ResNet18+fc,参数量约为11M,最终测试集Acc达到94.83%.接下来有分两个部分:导出onnx和使用onnxruntime推理. 一. ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
随机推荐
- Collection 和 Collections 的区别?
Collection 是一个接口,它是 Set.List 等容器的父接口:Collections 是个一个 工具类,提供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索. 排序.线程安全化等 ...
- django 三件套(render,redirect,HttpResponse)
Django基础必备三件套**: HttpResponse 内部传入一个字符串参数,返回给浏览器. from django.shortcuts import HttpResponse def inde ...
- 定时任务__@Xxl-JOB的使用
概述xxl-job框架 首先我们要知道什么是XXL-JOB? 官方简介:XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源代码并接入多家公司 ...
- 一次关于关系抽取(RE)综述调研的交流心得
本文来自于一次交流的的记录,{}内的为个人体会. 基本概念 实事知识:实体-关系-实体的三元组.比如, 知识图谱:大量实时知识组织在一起,可以构建成知识图谱. 关系抽取:由于文本中蕴含大量事实知识,需 ...
- html简单响应式滚动条置顶
简单响应式滚动条置顶 一般的,让页面出现滚动条的常见方法有: overflow:auto||overflow:scroll 或者overflow-x水平滚动条和overflow-y垂直滚动条 那么现在 ...
- C#设计编写一个控制台应用程序
设计编写一个控制台应用程序,练习类的继承. (1) 编写一个抽象类 People,具有"姓名","年龄"字段,"姓名"属性,Work 方法. ...
- vant弹窗提示
函数调用 Dialog 是一个函数而不是组件,因此可以直接调用,展示对应的提示弹窗 import { Dialog } from 'vant'; Dialog({ message: '提示' }); ...
- Spring原始注解开发-02
使用@Repository.@Service.@Controller注解配置,使其更加清晰属于哪一层,因为我是模拟的web层,所有没有使用@Controller注解,后面结合web开发会使用到 1.创 ...
- VirtualBox使用报错
VirtualBox使用报错 1.启动报错:Failed to instantiate CLSID_VirtualBox... 报错内容: Failed to instantiate CLSID_Vi ...
- JAVA学习2——HelloWorld
Java语言的诞生.版本以及工具:Java的安装开发环境以及环境变量的配置:第一个Java程序--HelloWorld