YOLOv8的TensorRT 的量化及部署

一、原理篇

一)、YOLOv8的整体架构

二)、TensoRT INT8量化原理

2.1 TensorRT 是什么?

NVIDIA TensorRT 的核心是一个C++库,可促进对NVIDIA图形处理单元(GPU)的高性能推理。它指在与TensorFlow、pytorch等框架以互补的方式工作。它专门致力于在GPU上快速有效地运行已经训练好的网络,已生成结果。一些训练好的框架已经集成了TensorRT,因此可以将其用于框架内加速推理。

2.2 使用TensorRT INT8量化的前提

1.硬件上必须是Nvidia的显卡,并且计算能力大于等于6.1。Nvidia GPU的计算能力可以在这个网上找到。        CUDA GPU | NVIDIA Developer

2.3 INT8量化流程

卷积的公式如下:Y = W*X + B

其中 X 是上一层的输出,即原始输入或者上一层的激活值;W 是当前层的权重; b 是当前层的偏置; Y是当前层的输出,即当前层的激活值。TensorRT的官方文档告知量化过程中偏置项可以忽略不计,即 Y = W * X 出去 bias 后,

整个量化工程精简后如下

1.通过线性映射的方式将激活值和权重从FP32转化为INT8;

2.执行卷积层运算得到INT32位激活值,如果直接使用INT8保存的话会造成过多累计损失;

3.通过再量化的方式转换回INT8作为下一层的输入;

4.当网络为最后一层时,使用反量化转换回FP32。

整个过程的关键部分就是FP32至INT8的量化、INT32至INT8的再量化以及INT8至FP32的反量化,也就是前面所说的线性量化(线性映射)

2.4 INT校准
2.4.1 INT8 校准目的

就是一种权衡。为了找到合适的缩放参数,是的量化后的INT8数值能更准确的表示出狼花钱的FP32数值,并且又不能舍弃太多远离零点的非噪声参数。

可以发现分布都不相同,那么如何选取最优的阈值呢?

这就需要一个定量的衡量指标:常用的手段是指数平滑法、直方图截断阀、KL散度校准法,TensorRT使用的是 KL散度校准法。

三)、TensorRT基础知识:

1.TensorRT是用于训练后的深度学习模型以实现高性能推理的SDK;

2.TensorRT包含用于训练后的深度学习模型的深度学习推理优化器,以及用于执行的runtime;

3.TensorRT能够以更高的吞吐量和耕地的延迟运行深度学习模型。

builder:TensorRT的模型优化器。构建器将网络定义作为输入,执行与设备无关和针对特定设备的优化,并创建引擎;

Network definition:TensorRT中模型的表示。网络定义是张量和运算符的图;

Engine: 由TensorRT构建器优化的模型的表示;

Plan:序列化格式的优化后的推理引擎。典型的应用程序将构建一次引擎,然后将其序列化为计划文件以供以后使用。要初始化推理引擎,应用程序将首先从plan文件中反序列化模型;序列化的目的:一次构建,多次使用。

Runtime:TensorRT组件,可在TensorRT引擎上执行推理;

TensorRT的工作流程:

Export The Model->select A batch Size-> select A Precision-> Convert The Model -> Deploy The Model

导出模型->选择batch大小->选择精度(FP32/FP16/INT8)->转换模型成引擎->部署(两种)

注释:

推断时,当优先考虑延迟时选择小的batch, 而优先考虑吞吐量时,选择大的batch。较大的batch需要更长的处理时间,但可以减少每个samples的平均时间;

推理通常需要比训练少的数字精度。较低的进度可以在不牺牲的精度的情况下提供更快的计算速度和耕地的内存消耗。TensorRT支持FP32,FP16,INT8;

将模型从ONNX(或WTS)转换为TensorRT引擎;

两种类型的runtime:C++ 和 python棒的独立的runtime,以及与tensorFlow的原生集成的runtime。

四)、TensorRT 之 Plugin

功能:

* 以编译后生成的文件:.so(Linux系统)/或.dll(windows)的形式插入到网络中实现某些算子

* 实现TensorRT不原生支持的层或结构

* 替换性能不足的层或结构

* 收到合并TensorRT没有自动融合的层或结构

限制条件:

* 自己实现CUDA c++ kernel, 为结果精度和性能负责

*  Plugin与其他Layer之间无法fusing

* 可能在Plugin节点前后插入reformatting节点,增加开销

五、Plugin的类型:

IPluginV2Ext(支持单一input格式和混合output格式,ExplicitBatch模式:在网络定义时,batchsize维度可以设置为*1,标记为不确定。这样同一个引擎可以支持不同的batchsize进行推理。在执行时需要针对具体的batchsize调用setBindingDimensions()设置这个维度);

IPluginV2IOExt(支持混合input/output格式,ImplicitBatch模式:是指模型在编译时固定批大小,并且在后续的推理中不允许更改这个批大小)

IPluginVDynamicExt(支持混合input/output格式,DynamicShape模式:允许用户为网络的输入定义动态尺寸。这意味着可以为输入张量指定)

五)、 C++实现 TensorRT INT8 量化

8.1 程序流程

TensorRT在做的其实只有一件事,就是把不同框架下训练得到 模型转换成 Engine,然后使用Engine进行推理。这里支持的框架包括ONNX、TensorFlow,如图

主要流程如下图:

1.构建builder,并使用builder 构建network 用于存储模型信息;

2.使用NetWork 构建Parser用于从onnx文件中解析模型信息并回传给network;

3.使用builder 构建profile 用于设置动态维度,并从dnnamicBinding中获取动态维度信息;

4.构建Calibrator 用于校准模型,并使用BatchStream加载校准数据集;

5.使用Builder构建Config用于配置生成Engine的参数,包括Calibrator 和Profile;

6.Builder 使用network 中的模型信息和Config 中的参数生成Engine 一级校准参数calParameter;

7.通过BatchStream 加载待测试数据集并传入Engine, 输出最终结果 result。

其中,Calibrator 和 BatchStream 两个类都是需要根据项目重写的

二、实践篇

一)、环境及软件安装

二)、CUDA的安装和配置

三)、 YOLOv8的克隆, 也可直接在官网下载

四)、TensorRT的安装

五)、测试TensorRT示例代码

六)、安装 OpenCV

七)、YOLOv8TensorRT加速

八)、修改CMakeLists.txt

最后)、编译tensorrtx/yolov8

三、本项目全部源码及详细教程:

q746531851

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值