TensorRT量化

系列文章目录

第一章 YOLOv5模型训练集标注、训练流程
第二章 YOLOv5模型转ONNX,ONNX转TensorRT Engine
第三章 TensorRT量化


文章目录

  • 系列文章目录
  • 前言
  • 一、量化
  • 二、量化在TensorRT中的实现
  • 三、预处理(Preprocess)和后处理(Postprocess)
  • 总结


前言

学习笔记–恩培老师


一、量化

深度学习量化是将深度学习模型中的参数(例如权重)从浮点数转换成整理或者定点数的过程,这样做可以减少模型的存储和计算成本,从而达到模型压缩和运算加速的目的。

  • 加快推理速度:访问一次32位浮点型可以访问4次Int8整型数据;
  • 减少存储空间和内存占用:在边缘设备(如嵌入式)上部署更实用。

提升速度的同时,量化也会带来精度损失,为了尽可能减少量化过程中精度的损失,需要使用各种校准方法来降低信息的损失。TensorRT中支持两种INT8整型数据:

  • 熵校准
  • 最小最大值校准

熵校准是一种动态校准算法,使用KL散度(KL Divergence)来度量推理数据和校准数据之间的分布差异。在熵校准中,校准数据是从实时推理数据中采集,它将INT8精度量化参数看作概率分布,根据推理数据和校准数据的KL散度来更新量化参数。这种方法优点是可以更好地反映实际推理数据的分布。

最小最大值校准使用最小最大值算法来计算量化参数。在最小最大值校准中,需要使用一组代表性的校准数据来生成量化参数,首先将推理中的数据进行统计,计算数据的最小值和最大值,然后根据这些值来计算量化参数。

一般选择500-1000张数据用于量化。

二、量化在TensorRT中的实现

在 TensorRT 中,可以通过实现 IInt8EntropyCalibrator2 接口或者 IInt8MinMaxCalibrator 接口来执行熵校准或最小最大值校准。

  • IInt8EntropyCalibrator2接口是用于执行熵校准的。需要实现该接口,并提供一个数据生成器,该生成器生成用于校准的数据。在校准过程中,TensorRT将分析每个张量的分布并选择合适的量化参数。你可以在校准过程中自定义数据生成器,例如从文件加载数据集并进行预处理。
  • IInt8MinMaxCalibrator接口是用于执行最小最大值校准的。需要实现该接口,并提供一个数据生成器,该生成器生成用于校准的数据。在校准过程中,TensorRT 将计算每个张量的最小和最大值,并使用它们作为量化参数。你可以在校准过程中自定义数据生成器,例如从文件加载数据集并进行预处理。

以下是一个使用 IInt8EntropyCalibrator2 接口的示例:

import tensorrt as trtclass EntropyCalibrator(trt.IInt8EntropyCalibrator2):def __init__(self, data_dir, batch_size, input_shape):# 初始化数据生成器self.data_dir = data_dirself.batch_size = batch_sizeself.input_shape = input_shapedef get_batch_size(self):return self.batch_sizedef get_batch(self, names):# 从数据生成器中获取一个批次的数据# 返回一个包含每个输入名称和对应数据的字典batch_data = ...return batch_data# 创建 TensorRT builder 和配置
builder = trt.Builder(...)
config = builder.create_builder_config()# 设置 Int8 校准器
calibrator = EntropyCalibrator(data_dir, batch_size, input_shape)
config.int8_calibrator = calibrator# 构建和优化 TensorRT 引擎
network = builder.create_network()
engine = builder.build_engine(network, config)

使用 IInt8MinMaxCalibrator 接口也类似,只需实现不同的接口方法。

运行代码

#将会读取 c3.mp4 文件,并将其每一帧保存为以 sample0001.png、sample0002.png、
#sample0003.png等命名的 PNG 图像文件。
ffmpeg -i c3.mp4 sample%04d.png #ls 命令获取当前目录下所有的 PNG 图像文件,并使用 shuf 命令随机选择其中的 200 个文件,
#并将结果保存到 filelist.txt 文件中。
ls *.png | shuf -n 200 > filelist.txt#将Build后的参数分布是onnx,校准目录(用于拼接完整图片路径),文件列表路径
./build/build weights/yolov5s_person.onnx ./media/ ./media/filelist.txt

三、预处理(Preprocess)和后处理(Postprocess)

YOLOv5预处理步骤如下

  1. letterbox: 即保持原图比例(图像直接resize到输入大小效果不好),将图片放在一个正方形画布中,多余部分用黑色填充。
  2. Normalization(归一化):将像素值缩放到[0,1]间;
  3. 颜色通道顺序调整:BGR2RGB
  4. NHWC转为NCHW

letterbox的实现,可以使用opencv的cv::warpAffine

#include <opencv2/opencv.hpp>using namespace cv;Mat letterbox(Mat& image, int width, int height)
{// 获取原始图像的宽度和高度int img_width = image.cols;int img_height = image.rows;// 计算需要添加的填充大小float scale = std::min(static_cast<float>(width) / img_width, static_cast<float>(height) / img_height);int new_width = static_cast<int>(img_width * scale);int new_height = static_cast<int>(img_height * scale);int dx = (width - new_width) / 2;int dy = (height - new_height) / 2;// 创建变换矩阵Mat M = Mat::eye(2, 3, CV_32F);M.at<float>(0, 0) = scale;M.at<float>(1, 1) = scale;M.at<float>(0, 2) = dx;M.at<float>(1, 2) = dy;// 应用变换矩阵Mat letterboxed_image;warpAffine(image, letterboxed_image, M, Size(width, height), INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));return letterboxed_image;
}int main()
{// 加载图像Mat image = imread("input.jpg");// 进行 Letterbox 处理Mat letterboxed_image = letterbox(image, 800, 800);// 显示调整后的图像并保存imshow("Letterboxed Image", letterboxed_image);imwrite("output.jpg", letterboxed_image);waitKey(0);return 0;
}

后处理

  1. 在设备上分配主机内存,用于存储复制后的数据。
  2. 使用cudaMemcpy函数将设备上的结果复制到分配的主机内存中。
  3. 释放在设备上分配的内存。
#include <cuda_runtime.h>// 假设在设备上分配了一块内存 device_output,存储了处理后的结果// 获取结果的大小和其他信息
size_t output_size = ...;
// 其他信息...// 在主机上分配内存,用于存储复制后的数据
void* host_output = malloc(output_size);// 将设备上的结果复制到主机内存中
cudaMemcpy(host_output, device_output, output_size, cudaMemcpyDeviceToHost);// 进行后续处理,如执行非极大值抑制等// 释放在主机上分配的内存
free(host_output);

总结

接下来会介绍TensorRT结合DeepStream加速过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/618141.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linuxshell日常脚本命令(1)

Linux 清理make、configure生成的文件&#xff08;灵感来自于quilt安装&#xff09; make clean #make clean 可以清除make失败的内容Linux 清理make、configure生成的文件 make clean #清除上一次make命令生成的文件 make distclean #清除上一次make以及configure命令生成的…

【MATLAB】 多元变分模态分解MVMD信号分解算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 1 基本定义 多元变分模态分解&#xff08;MVMD&#xff09;是一种信号分解方法&#xff0c;可以自适应地实现信号的频域剖分及各分量的有效分离。 MVMD算法的具体步骤如下&#xff1a; 假设原始信号S被分解为K个分量μ…

代码随想录 Leetcode160. 相交链表

题目&#xff1a; 代码(首刷看解析 2024年1月13日&#xff09;&#xff1a; class Solution { public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode *A headA, *B headB;while (A ! B) {A A ! nullptr ? A->next : headB;B B ! nullpt…

【力扣·每日一题】2182.构造限制重复的字符串(模拟 贪心 优先队列 C++ Go)

题目链接 题意 给你一个字符串 s 和一个整数 repeatLimit &#xff0c;用 s 中的字符构造一个新字符串 repeatLimitedString &#xff0c;使任何字母 连续 出现的次数都不超过 repeatLimit 次。你不必使用 s 中的全部字符。 返回 字典序最大的 repeatLimitedString 。 如果…

[易语言]易语言部署yolox的onnx模型

【官方框架地址】 https://github.com/Megvii-BaseDetection/YOLOX 【算法介绍】 YOLOX是YOLO系列目标检测算法的进一步演变和优化。它由Megvii Technology的研究团队开发&#xff0c;是一个高性能、可扩展的对象检测器。YOLOX在保留快速处理速度的同时&#xff0c;通过引入一…

textarea文本框根据输入内容自动适应高度

第一种&#xff1a; <el-input auto-completeoff typetextarea :autosize"{minRows:3,maxRows:10}" class"no-scroll"> </el-input> /* 页面的样式表 */ .no-scroll textarea {overflow: hidden; /* 禁用滚动条 */resize: none; /* 禁止用户…

NetApp E系列(E-Series)OEM产品介绍以及如何收集日志和保存配置信息

NetApp E系列是NetApp收购LSI存储后建立的一条新的产品线&#xff0c;由于LSI存储的历史悠久&#xff0c;所以这条产品线给NetApp带来了很多的OEM产品&#xff0c;可以说E系列是世界上OEM给最多公司的存储产品线也不为过&#xff0c;因为最早LSI的产品销售测率就是OEM&#xff…

2024.1.9 Spark SQL day06 homework,数据清洗

目录 一. Spark SQL中数据清洗的API有哪些&#xff0c;各自作用是什么&#xff1f; 二. 设置Spark SQL的shuffle分区数的方式有哪几种 三. 数据写出到数据库需要注意什么? 四. Spark程序运行集群分类 一. Spark SQL中数据清洗的API有哪些&#xff0c;各自作用是什么&#x…

JQuery过滤选择器-如何让某个元素换颜色(俩种方式)

目录 一、过滤选择器&#xff1a;eq二、过滤选择器 : lt 前言 : 在做项目时经常会遇到列表或者选择某个元素 一、过滤选择器&#xff1a;eq :eq (index)匹配一个给定索引值的元素 $("ul li:eq(0)").css("color","red");二、过滤选择器 : lt …

2024-01-11 部署Stable Diffusion遇挫记

点击 <C 语言编程核心突破> 快速C语言入门 部署Stable Diffusion遇挫记 前言一、一如既往的GitHub部署二、使用的感受总结 create by Stable Diffusion; prompt: fire water llama 前言 要解决问题: 由于近期的努力, 已经实现语音转文字模型, 通用chat迷你大模型的本地…

怎么把workspace的数据导入到simulink进行FFT分析?

怎么把数据导入到simulink在这篇博客已经阐述了&#xff0c;那么如何把数据导入到simulink还能进行FFT分析呢&#xff1f; 首先我们看simulink的FFT分析界面&#xff0c;&#xff08;前置步骤&#xff1a;导入powergui模块&#xff0c;双击powergui模块&#xff0c;Tool选项卡…

使用curl发送时间参数

# 获取当前日期 current_date$(date %Y-%m-%d)# 获取前一天的0点和23:59:59的时间&#xff0c;并格式化为yyyy-MM-dd 24hh:mm:ss begin_time$(date -d "yesterday 00:00:00" %Y-%m-%d\ %H:%M:%S) end_time$(date -d "yesterday 23:59:59" %Y-%m-%d\ %H:%M:…

发动机装备3d虚拟在线云展馆360度展示每处细节

在当今数字化的时代&#xff0c;消费者对于线上购物的需求与期待日益增长。尤其在购车这一大宗消费行为上&#xff0c;消费者不再满足于传统的图片与文字介绍。为了满足这一市场需求&#xff0c;我们引入了3D线上展示技术。 3D汽车模型实景互动展示是一种通过先进的三维建模技术…

【密码学】python密码学库pycryptodome

记录了一本几乎是10年前的书&#xff08;python绝技–用python成为顶级黑客&#xff09;中过时的内容 p20 UNIX口令破解机 里面提到了python标准库中自带的crypt库&#xff0c;经验证Python 3.12.1中并没有这个自带的库&#xff0c;密码学相关的库目前&#xff08;2024.1.12&a…

生成函数——裴蜀定理

有三种数量无限的砝码和一个天平&#xff0c;天平的一端有一个质量为 m 的物品&#xff0c;问能否通过放置砝码使得天平平衡&#xff1f; 输入 第一行包含一个整数 T (1 ≤ T ≤ 1e5)&#xff0c;表示测试用例的组数。 每组测试用例的第一行包含四个整数 a,b,c,m (1 ≤ a,b,c,…

R语言【paleobioDB】——pbdb_occurrences():从PBDB获取多个化石记录号的基本信息

Package paleobioDB version 0.7.0 paleobioDB 包在2020年已经停止更新&#xff0c;该包依赖PBDB v1 API。 可以选择在Index of /src/contrib/Archive/paleobioDB (r-project.org)下载安装包后&#xff0c;执行本地安装。 Usage pbdb_occurrences(...) Arguments 参数【...】…

一杯干红葡萄酒的酿造

一杯干红葡萄酒的酿造 一、什么是干红葡萄酒&#xff1f; 干红葡萄酒是指葡萄酒在酿造后&#xff0c;酿酒原料(葡萄汁)中的糖分完全转化成酒精&#xff0c;残糖量小于或等于4.00/L的红葡萄酒。 干红葡萄酒按颜色分可以分为 1&#xff0c;白葡萄酒:选择用白葡萄或浅色果皮的酿…

Linux命令行系列:Netcat网络工具

在大多数Linux发行版中&#xff0c;Netcat已经预装。如果需要安装或确保最新版本&#xff0c;请使用系统特定的包管理工具。例如&#xff0c;在Ubuntu上&#xff0c;可以使用以下命令安装Netcat&#xff1a; sudo apt-get install netcat 1、基本用法是在两台计算机之间建立简…

C++随机数生成:std标准库和Qt自带方法(未完待续)

std标准库 std::rand()是C中的一个随机数函数&#xff0c;它生成一个范围在0到RAND_MAX之间的伪随机整数。 在使用std::rand()之前&#xff0c;需要包含<cstdlib>头文件。 #include <cstdlib> 设置种子 在每次程序运行时&#xff0c;通常需要使用不同的种子值…

自定义数据实现SA3D

SA3D&#xff1a;Segment Anything in 3D with NeRFs 实现了3D目标分割 原理是利用SAM(segment anything) 模型和Nerf分割渲染3D目标&#xff0c; SAM只能分块&#xff0c;是没有语义标签的&#xff0c;如何做到语义连续&#xff1f; SA3D中用了self-prompt, 根据前一帧的mask…