详解TensorRT的C++高性能部署以及C++部署Yolo实践

news2024/9/23 7:17:47

详解TensorRT的C++高性能部署

  • 一. ONNX
    • 1. ONNX的定位
    • 2. ONNX模型格式
    • 3. ONNX代码使用实例
  • 二、TensorRT
    • 1 引言
  • 三、C++部署Yolo模型实例

一. ONNX

1. ONNX的定位

ONNX是一种中间文件格式,用于解决部署的硬件与不同的训练框架特定的模型格式兼容性问题。
在这里插入图片描述
ONNX本身其实是一种模型格式,属于文本,不是程序,因而无法直接在硬件设备上运行。因此,就需要ONNX Runtime、TensorRT等软件栈(推理框架(引擎))来加载ONNX模型,从而使得它在硬件设备上能够高效地推理。
在这里插入图片描述

许多芯片厂商依托自研的推理框架,NVIDIA的TensorRT、Intel的OpneVINO等可以充分发挥自家芯片的能力,但是普适性较差,你没有办法应用到其它的芯片上。
而,ONNX Runtime等通用性强,可以运行在不同的软硬件平台。
所以,PyTorch模型的部署通用流程一般如下:
首先,训练PyTorch等深度学习框架的网络模型;接着,将模型转换为ONNX模型格式;最后,使用推理框架把ONNX模型高效地运行在特定的软硬件平台上。
在这里插入图片描述

2. ONNX模型格式

ONNX (Open Neural Network Exchange)
一种针对机器学习所设计的开放式的文件格式,用于存储训练好的模型不同的训练框架可采用相同格式存储模型交互。由微软,亚马逊,Facebook和BM等公司共同发起。
在这里插入图片描述
下图,是经典的LeNet-5由PyTorch框架转换ONNX中间格式后,netron.app可视化的结构图。ONNX模型是一个有向无环图,图中的每个结点代表每个用于计算的算子,所有算子的集合称之为算子集,图中的表示结点的计算顺序数据的流向
在这里插入图片描述
模型属性,可以看到ONNX规范的第6个版本,PyTorch的版本,ONNX算子集的版本。
在这里插入图片描述
也可以点击结点,查看每个结点的信息。属性attributes记录的就记录超参数信息。1个输入,1个输出(名称为11)等等。
在这里插入图片描述
ONNX中定义的所有算子构成了算子集,访问网页,可以查看所有算子的定义。
算子在不同的版本,可能会有差异,比如这里的全局平均池化AveragePool,ONNX中AveragePool的属性中pads是个list,而PyTorch中是1个int,所以PyTorch导出ONNX时,会在AveragePool前面加上1个Pad结点
在这里插入图片描述

3. ONNX代码使用实例

这里以图像分类模型转ONNX为例,进行PyTorch模型转ONNX。

import torch
import torchvision
# 选择模型推理的设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 从pytorch官方实例化预训练模型,并转验证模型
model = torchvision.models.resnet18(pretrained=False)
model = model.eval().to(device)
# 构造一个输入图像的Tensor
# 该Tensor不需要任何的意义,只要在维度上匹配模型的输入即可
# 相当于构建一个输入,走一遍模型的推理过程
x = torch.randn(1, 3, 256, 256).to(device)
# 将x输入进模型推理
output = model(x)
print(output.shape)  # 1x1000
# PyTorch模型转ONNX
with torch.no_grad():
    torch.onnx.export(model, # 要转换的模型
                      x, # 模型的任意一个匹配的输入
                      "resnet18.onnx", # 导出的文件名
                      input_names=['input'], # 输入结点的名称列表(自定义名称)
                      output_names=['output'], # 输出结点的名称列表(自定义名称)
                      opset_version=11, # ONNX的算子集版本
                      )

加载导出的ONNX模型,并验证。

import onnx
# 验证是否导出成功
# 读取onnx模型
onnx_model = onnx.load('resnet18.onnx')
# 检查模型格式是否正确
onnx.checker.check_model(onnx_model)
# 以可读的形式打印计算图
print(onnx.helper.printable_graph(onnx_model.graph))

推理引擎ONNX Runtime的使用。

import onnxruntime
import torch
# 载入onnx模型,获取ONNX Runtime推理器
ort_session = onnxruntime.InferenceSession('resnet18.onnx')
# 构造随机输入
x = torch.randn(1, 3, 256, 256).numpy()
# ONNX Runtime的输入
# 这里构建的输入和输出的名称要和上面模型导出时自定义的名称一致。
ort_inputs = {'input': x}
# ONNX Runtime的输出,是1个list,对应模型的forward输出多少个,这里就是1个
ort_output = ort_session.run(['output'], ort_inputs)[0]
pass

注意事项:
1.在转ONNX时,将模型转成.eval()验证模式,因为模型在训练时,BN层、dropout都会起作用,而推理是不需要的。
2.这里导出onnx的api中第2个参数args,必须和我们使用PyTorch定义的模型model中forward函数中传入的参数一致,因为模型是torch.nn.Module,只有再执行一遍前向推理过程,也就是forward,才知道模型中有哪些算子。这也就是torch.jit.trace过程,trace得到的torch.jit.ScriptModule才是真正的计算图结构
在这里插入图片描述
3.我们在上述导出ONNX时,x = torch.randn(1, 3, 256, 256).numpy()
,代表着batch为1,每次模型的推理只能接受1张图,这么做的效率就低了。可以在导出的时候设置dynamic_axes参数,使得动态接受数据的数量
在这里插入图片描述

二、TensorRT

TensorRT是由NVIDIA 提供的一个高性能深度学习推理(inference)引擎。用于提高深度学习模型在NVIDIA GPU上运行的的推理速度和效率。

1 引言

要进行NVIDIA显卡的高性能推理,首推的还是自研发的推理引起TensorRT。使用TensorRT部署ONNX模型时,分为两个阶段:
1.构建阶段。对ONNX模型转换和优化,输出优化后模型。
在这里插入图片描述

TensorRT会解析ONNX模型,并进行多项优化
(1)模型量化。分为:训练后量化、训练时量化,均支持。下图为将FP32量化为INT8。
在这里插入图片描述

(2)层融合
(3)自动选择最合适计算的kernel。
build阶段,支持C++Python的API,也可以使用可执行程序trtexec
在这里插入图片描述

2.运行阶段。加载优化后模型,执行推理。
在这里插入图片描述
注意事项:
1.如果导出ONNX时设置了动态batch,使用trtexec转换TensorRT时,就需要加上最小shape最优shape最大shape的参数设置。这样得到的TensorRT模型就可以支持批处理了。
在这里插入图片描述
2.FP16INT8INT4低精度可以提升推理效率

三、C++部署Yolo模型实例

深度学习模型,以Yolo为例,通常在以Python和PyTorch框架训练模型后,整个推理过程分为:预处理、推理和后处理部分。而要进行模型的部署,需要把后处理的部分从模型里面摘出来。
OpenCV中的深度学习模块(DNN)只提供了推理功能,不涉及模型的训练,支持多种深度学习框架:Torch、TensorFlow、Caffe、Darknet。

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

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

相关文章

未来已来:揭秘GPT-Next如何重塑人工智能的未来

GPT-Next:性能的百倍提升 在当今这个科技日新月异的时代,人工智能(AI)无疑是最具活力和变革性的领域之一。最近,OpenAI在KDDI峰会上宣布了一项激动人心的消息:他们即将推出名为“GPT-Next”的新一代语言模…

SpringCloud之Sleuth(Micrometer)+ZipKin分布式链路追踪

(学习笔记) 1、分布式链路追踪概述 问题:在微服务框架中,一个由客户端发起的请求在后端系统中会经过多个不同的的服务节点调用来协同产生最后的请求结果,每一个前段请求都会形成一条复杂的分布式服务调用链路&#xf…

电脑桌面一键整理,高效整理,让你的电脑桌面焕然一新!

电脑桌面整理是一个能够提高工作效率、增强安全性、简化资产管理、改善用户体验的电脑软件。无论是图标管理还是文件整理,通过专业的电脑桌面整理软件都能轻松搞定,有序的管理文件、应用程序。 下面是关于Windows桌面工具的介绍与说明! 一、…

恒创科技:最小化服务器存储容量的技巧

最小化服务器存储容量的需求通常来自于希望降低硬件成本、节省能源以及提高系统性能的考虑。以下是一些实现这一目标的技巧: 1.评估您的存储需求 在开始优化服务器存储之前,您需要清楚了解实际需要和使用的空间大小。您可以使用磁盘使用情况分析器或 Tre…

day15-Linux的优化_linux15个优化

① UID 当前用户uid信息 [rootoldboy59 ~]# id uid0(root) gid0(root) groups0(root) \\UID 当前用户uid信息※② PATH 存放的是命令的位置/路径 [rootoldboy59 ~]# echo $PATH \\用$符号识别环境变量 /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bi…

自然语言处理系列六十一》分布式深度学习实战》TensorFlow深度学习框架

注:此文章内容均节选自充电了么创始人,CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】 文章目录 自然语言处理系列六十一分布式深度学习实战》TensorFlow深度学习…

JWT生成、解析token

目录 1. 导入JWT相关依赖2. JWT生成token3. JWT解析token4. 测试结果5. JWT加密、解密工具类 1. 导入JWT相关依赖 <!-- jwt认证模块--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><versio…

Linux 一个简单的中断信号实现

1.查看手册&#xff0c;学习中断处理图 流程&#xff1a;&#xff08;次级源->开关&#xff09;到 源挂起 到 开关 到 处理优先级 到 中断挂起标志 到 CPSR里面的开关&#xff08;图中未展现&#xff09; 最后cpu处理 此次我们先使用k1按键实现中断&#xff0c;即是eint8 …

requestIdleCallback和requestAnimationFrame有什么区别?

由react fiber引起的关注 组件树转为链表&#xff0c;可分段渲染渲染时可以暂停&#xff0c;去执行其他高优先级任务&#xff0c;空闲时在继续渲染&#xff08;JS是单线程的&#xff0c;JS执行的时候没法去DOM渲染&#xff09;如何判断空闲&#xff1f;requestIdleCallback 区…

想入门网络安全却不知道怎么入手,看这一篇就够了!

先聊聊&#xff0c;学习网络安全方向会遇到哪些问题&#xff1f; 打基础的时间长 学基础花费了很长的时间&#xff0c;光学语言都有好几门&#xff0c;有的人会止步于学习linux系统及命令的路上&#xff0c;更多的人会停在学习语言上面&#xff1b; 知识点掌握的不够清楚 对…

ML18_EM算法

1. 参数在贝叶斯网络中指的什么 2. 随机变量在贝叶斯网络中指的什么 在贝叶斯网络中&#xff0c;“随机变量”指的是网络中的节点&#xff0c;这些节点代表不确定事件或属性&#xff0c;它们可以取不同的值&#xff0c;并且这些值的概率分布通常未知或部分未知。随机变量可以表…

手搓LLM大模型:从零开始构建大语言模型

在人工智能的世界里&#xff0c;大型语言模型&#xff08;LLMs&#xff09;无疑是最引人注目的明星之一。这些深度神经网络模型的出现&#xff0c;为自然语言处理&#xff08;NLP&#xff09;领域带来了前所未有的变革。那么&#xff0c;这些模型究竟是如何工作的&#xff1f;它…

2024最新推荐10款英文免费录屏软件,想要录制电脑屏幕的你快看过来

你是否曾想过&#xff0c;只需几个简单的步骤&#xff0c;就能将你的电脑屏幕变成一个生动的视频故事&#xff1f;无论是展示你的游戏技巧&#xff0c;还是创建教育视频&#xff0c;录屏软件都能助你一臂之力。但面对市场上琳琅满目的录屏工具&#xff0c;选择一个合适的可能是…

【卡码网C++基础课 19.洗盘子】

目录 题目描述与分析一、栈二、栈的操作三、代码编写 题目描述与分析 题目描述&#xff1a; 在餐厅里&#xff0c;洗盘子的工作需要使用到栈这种数据结构。 假设你手里有一个盘子堆放区。现在需要模拟洗盘子的过程&#xff0c;每个盘子都有一个编号。 盘子堆放区操作说明&…

计算机网络-VRRP切换与回切过程

前面我们学习了VRRP选举机制&#xff0c;根据VRRP优先级与IP地址确定主设备与备份设备&#xff0c;这里继续进行主备切换与主备回切以及VRRP抢占模式的学习。 一、VRRP主备切换 主备选举时根据优先级选择主设备&#xff0c;状态切换为Master状态&#xff0c;那当什么时候会切换…

Verilog语法+:和-:有什么用?

Verilog语法:和-:主要用于位选择&#xff0c;可以让代码更简洁。 一、位选择基础 在Verilog中&#xff0c;位选择可以通过直接索引来实现&#xff0c;例如&#xff1a; reg [7:0] data; wire select_a; wire [2:0] select_b; assign select_a data[3]; assign select_b …

【sensor】激光雷达的分类和优缺点(六)

【sensor】镜头评价指标及测试方法&#xff08;一&#xff09; 【sensor】镜头评价指标及测试方法(二)—畸变与分辨率 【sensor】镜头评价指标及测试方法&#xff08;三&#xff09;--------测量原理及3D相机调查 【sensor】镜头评价指标及测试方法【四】————手机摄像头调查…

PAT甲级-1044 Shopping in Mars

题目 题目大意 一串项链上有n个钻石&#xff0c;输入给出每个钻石的价格。用m元买一个连续的项链子串&#xff08;子串长度可为1&#xff09;&#xff0c;如果不能恰好花掉m元&#xff0c;就要找到最小的大于m的子串&#xff0c;如果有重复就输出多个&#xff0c;按递增顺序输…

2.2ceph集群部署准备-软件准备上

系统的选择 操作系统的选取&#xff0c;除了要考虑ceph本身的运行&#xff0c;一般情况下还需要考虑的因素有如下几点 系统本身的稳定性 目前稳定可靠的系统主要是基于x86和arm的linux系统&#xff0c;ceph并不能安装到windows上&#xff0c;分支上&#xff0c;debian和redhat…

sponge创建的服务与dtm连接使用etcd、consul、nacos进行服务注册与发现

本文介绍sponge创建的 transfer 服务(grpc)如何与 dtm 使用服务注册与发现连接的。此示例在同一台机器上运行的服务&#xff0c;默认 IP 地址为 127.0.0.1。如果服务运行在不同的机器上&#xff0c;请在 transfer 和 dtm 的配置文件中&#xff0c;将 127.0.0.1 替换为相应的主机…