使用TensorRT对Yolov5进行部署【基于Python】

如果还未配置TensorRT,请看这篇博文:Win11下TensorRT环境部署

这里使用TensorRT对Yolov5进行部署流程比较固定:先将pt模型转换为onnx,再将onnx模型转为engine,所以在执行export.py时要将onnx、engine给到include。

PT模型转换为ONNX模型

PT模型地址:

方法一

python path/to/export.py --weights yolov5s.pt --include torchscript onnx coreml saved_model pb tflite tfjs

方法二

在这里插入图片描述
我们可以看到:

  • –weight 使用的是我们需要优化的权重,我这里yolov5s.pt为例
  • –opset 这里的参数如果你报错的话可以试着改小一点
  • –include 填写的是我们第一步生成的onnx文件
    在这里插入图片描述

下面我们介绍以下ONNX的构建流程:

在这里插入图片描述
这里介绍一下其中每个参数的含义:

  • model:就是需要转为ONNX的pth模型,只有源模型的结构和权重,才能转化为有效的ONNX模型。
  • model.cpu() if dynamic else model:如果启用了动态模式(dynamic=True),则将模型转移到CPU上进行导出;否则使用原始的模型。
  • im.cpu() if dynamic else im: 如果启用了动态模式,将输入张量转移到CPU上进行导出;否则使用原始的输入张量。

为什么要把模型和输入数据转移到CPU上?
CPU 是所有计算环境中最通用和兼容的硬件。当你将一个模型导出为一个通用格式,如 ONNX,目的通常是确保它可以在不同的环境和硬件上运行。使用 CPU 可以确保最大程度的兼容性,因为不是所有的环境都有 GPU 支持。这有助于确保模型能够在各种不同的硬件和软件环境中一致和可靠地工作。

  • f:这是输出文件的路径或文件对象,表示ONNX模型应该保存的位置
  • verbose = False:这个参数控制是否打印出详细的导出信息
  • opset_version=opset:指定ONNX的操作集版本,不同的版本的ONNX支持不同的特性集
  • do_constant_folding=True:控制是否进行常量折叠。表示常量折叠优化,默认为 False。如果为 True,则在导出时进行常量折叠优化。常量折叠优化将用预先计算的常量节点来替换那些所有都是常量输入的操作,在torch>=1.12版本中,进行DNN推理可能需要将do_constant_folding设置为False。这是因为在这个版本中,对一些操作进行了更多的优化。
  • input_names=[‘images’]: 定义输入节点的名称。
  • output_names=output_names: 定义输出节点的名称列表。
  • dynamic_axes=dynamic or None: 如果 dynamic 为真,则启用动态轴特性。动态轴允许模型在不同的推理请求中处理不同大小的输入。
  • keep_initializers_as_inputs:默认为 None。如果为 True,那么就导出图中的所有初始值的设定项,一般对应到参数,最后也会作为输入,添加到图中。如果为 False,那么初始值的设定项就不会作为输入添加到图中,而只是将非参数作为输入进行添加。
  • custom_opsets:用于在导出时指示自定义 opset 域和版本的字典。如果模型包含自定义的操作集,那么就可以选择在字典中指定域和操作集版本:其中KEY为操作集域名,它的 VALUE为操作集版本。注意的是,如果在这个字典中没有提供自定义的操作集,那么操作集版本就默认设置为1。
  • enable_onnx_checker:默认为 True。如果为 True,onnx 模型检查器将作为导出的一部分运行,以确保导出的模型是没有问题的 ONNX 模型。
  • use_external_data_format:默认为 False。如果为 True,那么模型就会以 ONNX 外部数据格式导出,比方说,有些模型的参数是存储在二进制文件中的,而不是存储在 ONNX 模型文件中。

onnxsim的使用

在这里插入图片描述

如果要精简onnx,就可以将simplify设置为True。设置为True,就会调用onnxsim来对原来onnx去除不必要的op操作,也叫去除胶水,在使用之前需要安装onnx-simplifer。

精简完之后可以把简化前和简化后的模型放进netron看优化了哪些地方。netron 就是一个网络结构的可视化神器。我们可以通过它来查看网络的结构。因为这里的模型太大,会占用较长的篇幅,所以本文就不展示了。

构建TensorRT引擎

构建完onnx后,就开始从onnx转为engine。在TensorRT上主要存在以下几个对象:

  • builder:用于创建 config、network、engine 等其它对象。
  • network:在其它框架的模型解析之后,就会被用于填充到网络 network中去。
  • config:主要用于配置builder。
  • OnnxParser:用于解析onnx的模型文件,对 ONNX 进行解析并填充到 tensorrt network 的结构当中。
  • engine:根据特定的config 与特定的硬件上编译出来的引擎,只能应用于特定的 config 与硬件上。此外,引擎可以持久化保存到本地,以节省下次使用时,不必要的编译时间。engine 集成了模型结构、模型参数 与可以实现最优计算 的kernel 配置。但是于此同时,engine 与硬件和 TensorRT的版本有着强绑定,所以要求进行engine编译与执行的硬件上的TensorRT 版本要保持一致。
  • engine:根据特定的config 与特定的硬件上编译出来的引擎,只能应用于特定的 config 与硬件上。此外,引擎可以持久化保存到本地,以节省下次使用时,不必要的编译时间。engine 集成了模型结构、模型参数 与可以实现最优计算 的kernel 配置。但是于此同时,engine 与硬件和 TensorRT的版本有着强绑定,所以要求进行engine编译与执行的硬件上的TensorRT 版本要保持一致。
LOGGER.info(f'\n{prefix} starting export with TensorRT {trt.__version__}...')assert onnx.exists(), f'failed to export ONNX file: {onnx}'f = file.with_suffix('.engine')  # TensorRT engine filelogger = trt.Logger(trt.Logger.INFO)if verbose:logger.min_severity = trt.Logger.Severity.VERBOSEbuilder = trt.Builder(logger)config = builder.create_builder_config()config.max_workspace_size = workspace * 1 << 30# config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, workspace << 30)  # fix TRT 8.4 deprecation noticeflag = (1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH))network = builder.create_network(flag)parser = trt.OnnxParser(network, logger)if not parser.parse_from_file(str(onnx)):raise RuntimeError(f'failed to load ONNX file: {onnx}')inputs = [network.get_input(i) for i in range(network.num_inputs)]outputs = [network.get_output(i) for i in range(network.num_outputs)]for inp in inputs:LOGGER.info(f'{prefix} input "{inp.name}" with shape{inp.shape} {inp.dtype}')for out in outputs:LOGGER.info(f'{prefix} output "{out.name}" with shape{out.shape} {out.dtype}')if dynamic:if im.shape[0] <= 1:LOGGER.warning(f'{prefix} WARNING ⚠️ --dynamic model requires maximum --batch-size argument')profile = builder.create_optimization_profile()for inp in inputs:profile.set_shape(inp.name, (1, *im.shape[1:]), (max(1, im.shape[0] // 2), *im.shape[1:]), im.shape)config.add_optimization_profile(profile)LOGGER.info(f'{prefix} building FP{16 if builder.platform_has_fast_fp16 and half else 32} engine as {f}')if builder.platform_has_fast_fp16 and half:config.set_flag(trt.BuilderFlag.FP16)with builder.build_engine(network, config) as engine, open(f, 'wb') as t:t.write(engine.serialize())return f, None

推理代码

使用engine推理和使用pt推理的流程是大同小异的,同样是使用detect.py。区别就在于model = DetectMultiBackend(weights, device=device, dnn=dnn)中的weight是pt模型还是onnx模型还是engine模型

进入到DetectMultiBackend这个类中查看,直接跳转【ctrl + click】到构建engine的部分:

        elif engine:  # TensorRTLOGGER.info(f'Loading {w} for TensorRT inference...')import tensorrt as trt  # https://developer.nvidia.com/nvidia-tensorrt-downloadcheck_version(trt.__version__, '7.0.0', hard=True)  # require tensorrt>=7.0.0if device.type == 'cpu':device = torch.device('cuda:0')Binding = namedtuple('Binding', ('name', 'dtype', 'shape', 'data', 'ptr'))logger = trt.Logger(trt.Logger.INFO)with open(w, 'rb') as f, trt.Runtime(logger) as runtime:model = runtime.deserialize_cuda_engine(f.read())context = model.create_execution_context()bindings = OrderedDict()output_names = []fp16 = False  # default updated belowdynamic = Falsefor i in range(model.num_bindings):name = model.get_binding_name(i)dtype = trt.nptype(model.get_binding_dtype(i))if model.binding_is_input(i):if -1 in tuple(model.get_binding_shape(i)):  # dynamicdynamic = Truecontext.set_binding_shape(i, tuple(model.get_profile_shape(0, i)[2]))if dtype == np.float16:fp16 = Trueelse:  # outputoutput_names.append(name)shape = tuple(context.get_binding_shape(i))im = torch.from_numpy(np.empty(shape, dtype=dtype)).to(device)bindings[name] = Binding(name, dtype, shape, im, int(im.data_ptr()))binding_addrs = OrderedDict((n, d.ptr) for n, d in bindings.items())batch_size = bindings['images'].shape[0]  # if dynamic, this is instead max batch size

在进行前向推理时,就会调用DetectMultiBackend的forward方法:
在这里插入图片描述

其中y返回的就是推理结果。这个结果会返回到detect.py中,当detect.py捕获到结果之后,就正常走目标检测的后处理流程了。

最后

–weight填写 yolov5s.onnx

–include 填写 engine

注:如果输入.onnx生成engine报错的话可以直接在–weight填我们需要优化的权重

–include 直接填写engine,因为直接生成engine的过程中也会升成一个.onnx。

参考链接:

https://zhuanlan.zhihu.com/p/607601799
https://blog.csdn.net/m0_64524798/article/details/129187608

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

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

相关文章

Linear Regression线性回归(一元、多元)

目录 介绍&#xff1a; 一、一元线性回归 1.1数据处理 1.2建模 二、多元线性回归 2.1数据处理 2.2数据分为训练集和测试集 2.3建模 介绍&#xff1a; 线性回归是一种用于预测数值输出的统计分析方法。它通过建立自变量&#xff08;也称为特征变量&#xff09;和因变…

【Redis】五、Redis持久化、RDB和AOF

文章目录 Redis持久化一、RDB&#xff08;Redis DataBase&#xff09;触发机制如何恢复rdb文件 二、AOF&#xff08;Append Only File&#xff09;三、扩展 Redis持久化 面试和工作&#xff0c;持久化都是重点&#xff01; Redis 是内存数据库&#xff0c;如果不将内存中的数据…

微服务实战系列之ZooKeeper(实践篇)

前言 关于ZooKeeper&#xff0c;博主已完整的通过庖丁解牛式的“解法”&#xff0c;完成了概述。我想掌握了这些基础原理和概念后&#xff0c;工作的问题自然迎刃而解&#xff0c;甚至offer也可能手到擒来&#xff0c;真实一举两得&#xff0c;美极了。 为了更有直观的体验&a…

uniapp 预览图片

preImg(index){let urls []this.images.map((item,i) > {if(indexi){urls.unshift(item.file_path)}else{urls.push(item.file_path)}})uni.previewImage({urls})}

linux之Samba服务器

环境&#xff1a;虚拟机CENTOS 7和 测试机相通 一、Samba服务器_光盘共享&#xff08;匿名访问&#xff09; 1.在虚拟机CENTOS 7安装smb服务&#xff0c;并在防火墙上允许samba流量通过 2. 挂载光盘 3.修改smb.conf配置文件&#xff0c;实现光盘匿名共享 4. 启动smb服务 5.在…

JVM基础扫盲

什么是JVM JVM是Java设计者用于屏蔽多平台差异&#xff0c;基于操作系统之上的一个"小型虚拟机"&#xff0c;正是因为JVM的存在&#xff0c;使得Java应用程序运行时不需要关注底层操作系统的差异。使得Java程序编译只需编译一次&#xff0c;在任何操作系统都可以以相…

英码科技受邀参加2023计算产业生态大会,分享智慧轨道交通创新解决方案

12月13-14日&#xff0c;“凝心聚力&#xff0c;共赢计算新时代”——2023计算产业生态大会在北京香格里拉饭店成功举办。英码科技受邀参加行业数字化分论坛活动&#xff0c;市场总监李甘来先生现场发表了题为《AI哨兵&#xff0c;为铁路安全运营站好第一道岗》的精彩主题演讲&…

1951 年以来的美国ACIS 气候地图数据集(5 公里空间分辨率)

应用气候信息系统 (ACIS) NRCC NN ACIS是Applied Climate Information System的缩写&#xff0c;是由美国国家气象局&#xff08;NOAA&#xff09;开发的一种气候信息系统。ACIS气候地图是通过收集和整理全球的气象数据&#xff0c;利用计算机技术和数据分析方法生成的气候图表…

计算机组成原理-选择语句和循环语句的汇编表示

文章目录 选择语句jmpjxx示例&#xff1a;选择语句的机器级表示扩展&#xff1a;cmp指令的底层原理 循环语句使用条件转移指令实现循环用loop指令实现循环 选择语句 不一定知道指令的位置&#xff0c;所以jmp直接跳转到指令的位置很难办 jmp 标号相当于位置&#xff0c;名字…

解决win11杀毒(不能安装破解软件的问题)

1、下载火绒APP&#xff0c;打开火绒APP软件 2、点击菜单&#xff0c;选择安全设置 3、选择病毒防护&#xff0c;修改病毒处理方式为询问我 4、这样在解压激活的软件就不会被windows的杀毒软件自动删除了 5、问题解决了就点击三连吧

永久删除的文件如何恢复?这3个简单方法可以帮到你!

“我在清理电脑的过程中&#xff0c;一不小心就删除了一些很重要的文件和数据&#xff0c;很想通过某种方法将这些数据找回来&#xff0c;但是不知道应该如何操作&#xff0c;有朋友可以分享一下文件找回的简单方法吗&#xff1f;” 在日常生活和工作中&#xff0c;我们时常会遇…

【JAVA基础(对象和封装以及构造方法)】----第四天

对象和封装以及构造方法 面向对象和面向过程面向过程面向对象 类与对象及其使用定义类创建一个对象&#xff0c;操作类补充&#xff08;成员变量和局部变量&#xff09; private 修饰类 封装练习编写类编写测试输出结果 面向对象和面向过程 面向过程 在了解面向对象之前先来了…

用户行为分析遇到的问题-ubantu16,hadoop3.1.3【更新中】

用户行为分析传送门 我的版本 ubantu16 hadoop 3.1.3 habse 2.2.2 hive3.1.3 zookeeper3.8.3 sqoop 1.46/1.47 我sqoop把MySQL数据往hbase导数据时候有问题 重磅&#xff1a;大数据课程实验案例&#xff1a;网站用户行为分析&#xff08;免费共享&#xff09; 用户行为分析-小…

VR党建:VR全景技术如何助力党建知识传播

导语&#xff1a; 随着科技的不断发展&#xff0c;虚拟现实技术逐渐深入人们生活的方方面面。VR全景技术作为一种全新的沉浸式体验方式&#xff0c;被广泛应用于娱乐、教育、医疗等领域。而在党建学习中&#xff0c;VR全景技术也展现出了巨大的潜力&#xff0c;成为了一种创新…

「数据结构」二叉树1

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;C启航 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 文章目录 &#x1f349;树&#x1f349;二叉树&#x1f34c;特殊二叉树&#x1f34c;二叉树的性质&#x1f34c;存储结构 &#x1f349;…

ffmpeg入门之Windows开发之二(视频转码)

添加ffmpeg windows编译安装及入门指南-CSDN博客 的头文件和依赖库如下&#xff1a; main 函数如下&#xff1a; extern "C" { #ifdef __cplusplus #define __STDC_CONSTANT_MACROS #endif } extern "C" { #include <libavutil/timestamp.h> #in…

OpenCV-8RGB和BGR颜色空间

一. RGB和BGR 最常见的色彩空间就是RGB&#xff0c;人眼也是基于RGB的色彩空间去分辨颜色。 OpenCV默认使用的是BGR. BGR和RGB色彩空间的区别在于图片在色彩通道上的排列顺序不同。 二.HSV, HSL和YUV 1.HSV(HSB) OpenCV用的最多的色彩空间是HSV. Hue&#xff1a;色相&…

【分享】5种方法将Excel设置为“只读”

将Excel表格设置以“只读方式”打开&#xff0c;可以提醒或者防止表格被随意改动&#xff0c;今天小编来分享一下将Excel设置为“只读”的5种方法。 方法一&#xff1a;通过“保护工作簿”设置 首先&#xff0c;打开Excel表格依次点击菜单选项卡【文件】→【信息】→【保护工作…

【无标题】CTF之SQLMAP

拿这一题来说 抓个包 复制报文 启动我们的sqlmap kali里边 sqlmap -r 文件路径 --dump --dbs 数据库 --tables 表

数据库操作习题12.12

考虑如下的人员数据&#xff0c;其中加下划线的是主码&#xff0c;数据库模式由四个关系组成: employee (empname, street, city) works (empname, compname, salary) company(id, compname, city) managers (empname, mgrname) 其中 关系 employee 给出人员的基本信息,包括人员…