【yolov8目标检测部署】TensorRT int8量化

原作者github:https://github.com/xuanandsix/Tensorrt-int8-quantization-pipline/tree/main

改进:
源代码支持的TensorRT版本为7.许多属性已经弃用;
在原有的代码上将支持的TensorRT版本从7改到8.

!!不知道如何安装TensorRT?请参考:【通俗易懂】Windows系统安装TensorRT。
!!项目排坑请参考:【Debug】TensorRT报错汇总 欢迎大家补充。

一、简介

模型量化是深度学习领域中一种重要的模型优化技术,它主要涉及将模型中的浮点数(如FP32)转换为低比特的格式(如INT8)。这样做的目的是为了减少模型的存储大小和内存占用,同时加快模型的推理速度,尤其在硬件资源受限的设备上效果显著。

模型量化的方法:
1. 训练时量化也叫量化感知训练(Quantization-Aware-Training,QAT),在训练过程中模拟量化操作,使模型适应量化,减少量化误差。
2. 训练后量化(Post-Training Quantization,PTQ),PTQ不需要再训练,因此是一种轻量级的量化方法。在模型训练好后,再通过一个校准(Calibration)流程去计算比例因子,从而实现量化过程。
这里使用第二种方法简单且高效。

二、量化流程

2.1 TensorRT提供了四种IInt8Calibrator:

  • Int8EntropyCalibrator2:当前推荐的熵校准器,默认情况下校准发生在层融合之前,推荐用于CNN模型中。
  • IInt8MinMaxCalibrator:该校准器使用激活分布的整个范围来确定比例因子,默认情况下校准发生在层融合之前,推荐用于NLP任务的模型中。
  • IInt8EntropyCalibrator: 该校准器是TensorRT最原始的熵校准器,默认情况下校准发生在层融合之后,目前已不推荐使用。
  • IInt8LegacyCalibrator: 该校准器需要用户进行参数化,默认情况下校准发生在层融合之后,不推荐使用。

2.2 IInt8Calibrator需要实现的功能

  • getBatchSize:获取校准过程中的batchSize;
  • getBatch:获取校准过程中的输入;
  • writeCalibrationCache:由于校准花费的时间比较长,调用该函数将校准参数结果写入本地文件,方便下次直接读取。
  • readCalibrationCache:读取保存在本地的校准参数文件,在生成引擎过程中会自动调用。.

2.3 TensorRT构建INT8模型引擎时,会执行下面的步骤:

构建一个32位的模型引擎,然后在校准数据集上运行这个引擎,然后为每个张量激活值的分布记录一个直方图;
从直方图构建一个校准表,为每个张量计算出一个比例因子;
根据校准表和模型的定义构建一个INT8的引擎。
校准的过程可能会比较慢,不过第二步生成的校准表可以输出到文件并可以被重用,如果校准表文件已存在,那么校准器就直接从该文件中读取校准表而无需执行前面两步。另外,与引擎文件不同的是,校准表是可以跨平台使用的。因此,我们在实际部署模型过程中可以先在带通用GPU的计算机上生成校准表,然后在Jetson Nano等嵌入式平台上去使用。为了编码方便,我们可以用Python编程来实现INT8量化过程来生成校准表。
TensorRT流程(官方)

三、关键代码:

加载校准文件:quantization.py:

import numpy as np
import util_trt
import glob,os,cv2

BATCH_SIZE = 4  # 批处理大小
BATCH = 100     # 校准批次
height = 640    # 输入高度
width = 640     # 输入宽度
CALIB_IMG_DIR = './calibration/'    # 校准图片路径
onnx_model_path = './weights/yolov8s.onnx'  # 待校准onnx模型路径

def preprocess(img):
    img = cv2.resize(img, (height, width))
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = img.transpose((2, 0, 1)).astype(np.float32)
    img /= 255.0
    return img

class DataLoader:
    def __init__(self):
        self.index = 0
        self.length = BATCH
        self.batch_size = BATCH_SIZE
        # self.img_list = [i.strip() for i in open('calib.txt').readlines()]
        self.img_list = glob.glob(os.path.join(CALIB_IMG_DIR, "*.jpg"))
        assert len(self.img_list) > self.batch_size * self.length, '{} must contains more than '.format(CALIB_IMG_DIR) + str(self.batch_size * self.length) + ' images to calib'
        print('found all {} images to calib.'.format(len(self.img_list)))
        self.calibration_data = np.zeros((self.batch_size,3,height,width), dtype=np.float32)

    def reset(self):
        self.index = 0

    def next_batch(self):
        if self.index < self.length:
            for i in range(self.batch_size):
                assert os.path.exists(self.img_list[i + self.index * self.batch_size]), 'not found!!'
                img = cv2.imread(self.img_list[i + self.index * self.batch_size])
                img = preprocess(img)
                self.calibration_data[i] = img

            self.index += 1

            # example only
            return np.ascontiguousarray(self.calibration_data, dtype=np.float32)
        else:
            return np.array([])

    def __len__(self):
        return self.length

def main():
    # onnx2trt
    fp16_mode = False
    int8_mode = True 
    print('*** onnx to tensorrt begin ***')
    # calibration
    calibration_stream = DataLoader()
    engine_model_path = "./weights/yolov8s_Int8.trt"
    calibration_table = 'best_calibration.cache'
    # fixed_engine,校准产生校准表
    engine_fixed = util_trt.get_engine(BATCH_SIZE, onnx_model_path, engine_model_path, fp16_mode=fp16_mode, 
        int8_mode=int8_mode, calibration_stream=calibration_stream, calibration_table_path=calibration_table, save_engine=True)
    print(engine_fixed)
    assert engine_fixed, 'Brokenls engine_fixed'
    print('*** onnx to tensorrt completed ***\n')
    
if __name__ == '__main__':
    main()

四、测试结果

model(640*640)infer_time(ms)/framesize
float32(trt)8.51.6M
int8(trt)2.14.3M

yolov8s模型FP32和INT8精度的目标检测结果分别如下面两张图片所示:

float32 tensorrtint8 tensorrt
请添加图片描述请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

酷得电子机器狗玩具 MCU方案介绍

机器狗是一种多功能、互动性强的机器人&#xff0c;适合家庭和学校环境。它不仅可以陪伴孩子们玩耍&#xff0c;还能帮助他们学习和成长。功能如下&#xff1a; 关节可动&#xff1a;机器狗的关节设计灵活&#xff0c;可以执行各种动作&#xff0c;如“坐下”、“俯卧撑”、“…

【Ant-Desgin-React 步骤条】步骤条配合组件使用

步骤条配合组件使用 基础使用多分组进度 基础使用 /* eslint-disable no-unused-vars */ import React, { useState } from react import { Button, message, Steps, theme } from antd import After from ./components/after import Now from ./components/now const steps …

纯js对比excel小工具

如何使用JavaScript和xlsx.js实现Excel文件对比&#xff1a;实战指南 在日常办公或数据分析工作中&#xff0c;我们经常需要比较两个Excel文件中的数据差异。手动对比不仅耗时费力&#xff0c;还容易出错。本文将带你通过一个简单的网页应用&#xff0c;利用JavaScript和开源库…

【产品经理】如果人人都是产品经理,那么如何提升自己的不可替代性?

任何职业都需要有危机感&#xff0c;不只是产品经理。 人有生老病死&#xff0c;相应的职场上也有升降变离。当乔布斯站在宇宙之巅望着芸芸众生说“活着就是为了改变世界”的时候&#xff0c;这话着实燃烧了我们一把。随之&#xff0c;马化腾、周鸿祎、张小龙、王小川等汹涌而入…

前端canvas项目实战——在线图文编辑器(九):逻辑画布

目录 前言一、 效果展示二、 实现步骤1. 调整布局&#xff0c;最大化利用屏幕空间2. 添加逻辑画布3. 添加遮罩4. 居中显示逻辑画布5. 一个容易被忽视的bug点 三、Show u the code后记 前言 上一篇博文中&#xff0c;我们实现了一组通用的功能按钮&#xff1a;复制、删除、锁定…

Eclipse内存分析器 Java内存分析工具MAT(Memory Analyzer Tool)的介绍与使用

1.visualvm实时监测 2.Memory Analyzer Tool打开 3.工具的使用可以参考 Java内存分析工具MAT(Memory Analyzer Tool)的介绍与使用 ------------------------ 1.我远程发现是其中一个客户端A请求服务器页面响应&#xff0c;一直得不到响应&#xff0c;然后客户端A一直请求&am…

js 字符串 第一个斜杠前最后一次出现英文字母的位置并添加自定义值,返回新值

要找到字符串中第一个斜杠&#xff08;/&#xff09;前最后一次英文字母出现的位置&#xff0c;可以使用正则表达式配合lastIndexOf方法。以下是实现这一功能的示例代码&#xff1a; 如果是匹配第一个数字前的字母加值可以看这里 function findLastLetterIndexBeforeSlash(str…

外贸旺季外贸人如何做好时间管理

第1步 记住这些原则 50-30-20原则 你工作日里50%的时间应该花在有益于你长期发展目标的事情上&#xff0c;30%的时间应该用于你完成中期(两年左右)目标的事情&#xff0c;20%的时间用于完成未来90天以内需要完成的任务。 “一个篮子”原则 One Bucket 尽可能减少自己接收新任务…

《QT实用小工具·四十六》多边形窗口

1、概述 源码放在文章末尾 该项目实现了可以移动的多边形窗口&#xff0c;项目demo演示如下所示&#xff1a; 项目部分代码如下所示&#xff1a; #include "polygonwindow.h"#include <QBitmap> #include <QQuickItem> #include <QQmlFile> #in…

JAVASE->数据结构|顺序表底层逻辑

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;再无B&#xff5e;U&#xff5e;G-CSDN博客 目标&#xff1a; 1. 什么是 List 2. List 常见接口介绍 3. …

第8章 软件工程

一、软件工程概述 &#xff08;一&#xff09;软件危机 1、含义&#xff1a;落后的软件生产方式无法满足迅速增长的计算机软件需求&#xff0c;从而导致软件开发与维护过程中出现一系列严重问题的现象。 2、解决方案&#xff1a;引入软件工程的思想。 &#xff08;二&#x…

Unity 问题之 开发应用在设备上运行闪屏花屏问题的分析处理

Unity 问题之 开发应用在设备上运行闪屏花屏问题的分析处理 目录 Unity 问题之 开发应用在设备上运行闪屏花屏问题的分析处理 一、简单介绍 二、问题现象 三、问题分析 四、使用空后处理&#xff0c;解决闪屏花屏的显示问题 五、空后处理完整代码 一、简单介绍 Unity 在…

国密SSL证书在等保、关保、密评合规建设中的应用

在等保、关保、密评等合规建设中&#xff0c;网络和通信安全方面的建设是非常重要的部分&#xff0c;需要实现加密保护和安全认证&#xff0c;确保传输数据机密性、完整性以及通信主体可信认证。国密SSL证书应用于等保、关保和密评合规建设中&#xff0c;不仅能够提升网络信息系…

API接口调用失败的常见原因?如何进行排查和处理?

API接口调用失败的常见原因有以下几种&#xff1a; 1. 无效的请求参数&#xff1a;可能是由于请求参数缺失、格式错误或者不符合接口要求导致的。解决方法是检查请求参数是否正确&#xff0c;并确保按照接口文档提供正确的参数。 2. 接口权限不足&#xff1a;有些接口需要特定…

JAVA自定义日期选择器

下载jar地址&#xff0c; https://toedter.com/jcalendar/ jar包下载地址 依赖包如下图所示&#xff1a; 整个项目代码已经上传到CSDN https://download.csdn.net/download/qq_30273575/89241601?ydrefereraHR0cHM6Ly9tcC5jc2RuLm5ldC9tcF9kb3dubG9hZC9tYW5hZ2UvZG93bmxvYWQ…

Swift-31-泛型和类型操作

泛型 Swift泛型(generics) 让我们写出的类型和函数可以使用对于我们或编译器都未知的类型。 很多内建类型(包括可空类型、数组和字典)都是用泛型实现的&#xff0c;比如数组和一些集合就是用泛型方式来实现的。 一种运行时进行类型检查的技术&#xff0c;效率高但是不安全。在…

Java零基础入门到精通_Day 8

1.API 应用程序接口 Java API:指的就是JDK 中提供的各种功能的Java类这些类将底层的实现封装了起来&#xff0c;我们不需要关心这些类是如何实现的&#xff0c;只需要学习这些类如何使用即可&#xff0c;我们可以通过帮助文档来学习这些API如何使用。 2. String String 类…

记录-执行Grad-CAM所遇问题

在执行Grad-CAM所遇问题 1&#xff09; 修改后解决 2&#xff09; 修改后解决&#xff0c;因为numpy需要在cpu上进行&#xff0c;所有需要加上.cpu() 3&#xff09;plt.matshow(heatmap)出错 原因是get_heatmap()中的mean_gradients torch.mean(gradients, dim[0, 2, 3]…

Spring IOC(一)

1. Spring IOC入门 1.1 什么是Spring IoC IoC&#xff08;Inversion of Control&#xff09;&#xff0c;即控制反转&#xff0c;是一种设计原则。简单来说&#xff0c;IoC就是将程序的某种传统控制流程反转了。 在Spring框架中&#xff0c;控制反转体现在对象的创建和管理上。…

面试:Redis(缓存穿透、缓存击穿、缓存雪崩、双写一致、Redis的持久化、Redis的过期策略、Redis的数据淘汰策略、Redis的分布式锁、Redis的集群方案、Redis网络模型)

目录 一、缓存穿透 1、解决方案一&#xff1a; 2、解决方案二&#xff1a; 二、缓存击穿 1、解决方案一&#xff1a; 2、解决方案二&#xff1a; 三、缓存雪崩 1、解决方案一&#xff1a; 2、解决方案二&#xff1a; 3、解决方案三&#xff1a; 4、解决方案四&#…