深度学习模型部署(八)TensorRT完整推理流程

TensorRT的大致流程:

在这里插入图片描述
图片来自TensorRT的官方教程

构建期

  • 模型解析
  • 计算图优化
  • 节点消除
  • 多精度支持
  • 优选kernel:选择最适合当下设备的实现
  • 导入plugin:实现自定义操作
  • 显存优化:显存池复用

运行期

  • 运行时环境:对象生命周期管理,内存显存管理,异常处理
  • 序列化反序列化:推理引擎保存为文件或者从文件中加载

具体流程

相关推理配置

需要配置logger,builder,builder_config

import numpy as np
import tensorrt as trt

import pycuda.driver as cuda
import pycuda.autoinit
# autoinit是cuda初始化要用的,必须导入

logger = trt.Logger(trt.Logger.INFO)
# 日志器,等级分为:VERBOSE, INFO, WARNING, ERROR, INTERNAL_ERROR
# VERBOSE和INFO最常用,VERBOSE会输出模型优化的详细信息,INFO只会输出模型的输入输出信息
builder = trt.Builder(logger)
# 网络构建器,仅作为构建网络的工具,不用于设置网络属性
builder_conf = builder.create_builder_config()
# 构建器配置,用于设置构建器的属性,可以设置的有:最大显存,int8量化的校正器,设置推理精度等

TensorRT对于batchsize有两种模式:

  • explicit batch模式:显式指定batchsize
    • explicit batch模式支持BN层,支持reshape层,支持Loop结构,而implicit batch模式不支持
  • implicit batch模式【为了向后兼容而保留的,不推荐使用】
    根据输入尺寸的不同,可以分为dynamic shape模式
profile = builder.create_optimization_profile()
profile.set_shape("input", (1, 1, 28, 28), (1, 1, 28, 28), (1, 1, 28, 28))
builder_conf.add_optimization_profile(profile)
# dynameic shape模式下,必须使用explicit batch模式
# dynamic shape模式下,必须使用构建器配置
# dynamic shape模式下,几乎所有的维度都可以是-1,-1表示该维度可以是任意值,除了batch维度
# dynamic shape模式需要使用optimazation profile帮助网络进行优化
# optimization profile可以设置输入张量的常见尺寸,最大尺寸,最小尺寸等

解析模型

三种方式:

  • 使用框架自带的TRT接口:Torch-TensorRT,不支持的算子会自动返回训练框架计算
  • 使用Parser:导出为onnx,然后TensorRT的parser解析onnx模型,对于不支持的算子需要手写
    • TensorRT中有自带的parser类,可以用于解析onnx模型
    parser = trt.OnnxParser(network, logger)
    onnxFile = "/home/wyq/hobby/model_deploy/onnx/onnxruntime/MNIST/mnist.onnx"
    res = parser.parse_from_file(onnxFile)
    
  • 使用TensorRT原生API搭建网络
network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH))
#网络本体,可以设置网络的输入输出,添加层,设置层的属性等
inputTensor = network.add_input(name="input", dtype=trt.float32, shape=(1,1, 28, 28))
identityLayer = network.add_identity(inputTensor)
network.mark_output(identityLayer.get_output(0))
# 添加输入层,添加一个identity层,将输入直接输出,作为输出层

设置推理精度

FP16模式

只要在建立网络的时候添加一个flag就可以指定模型使用fp16模式

builder_conf.flags = 1 << trt.BuilderFlag.FP16

设置为FP16模式后建立engine的时间比fp32模式要更长,更多kernel选择,需要插入reformat节点【数据类型转换节点】
部分层可能精度下降比较大,导致较大误差,需要使用polygraphy等工具找到误差较大的层,强制其使用fp32进行计算。

builder_conf.set_flag(trt.BuilderFlag.OBEY_PRECISION_CONSTRAINTS)
layer.precision = trt.float32

这里个人感觉还可以尝试一下用bf16来进行推理,bf16的精度比fp16高,范围比fp16小

Int8模式

INT8的精度损失比较严重,所以需要有校准集进行校准,通过范例数据来确定量化参数。
校准器需要我们自己进行实现calibrator。

config.set_flag(trt.BuilderFlag.INT8)
config.int8_calibrator = MyCalibrator

支持PTQ和QAT两种量化模式,只要模型中有量化器和解量化器,就会自动启用INT8

生成Engine

生成TRT内部表示

serializedNetwork = builder.build_serialized_network(network, builder_conf)
# 序列化网络,将网络序列化为字节流,可以保存到文件中,也可以用于反序列化

# 保存到网络文件
with open("test.engine", "wb") as f:
    f.write(serializedNetwork)

TensorRT生成的Engine包含硬件相关的engine,不能跨平台使用,不同版本的TensorRT生成的engine也不能通用。
想要通用,需要确保硬件环境相同,CUDA/cuDNN/TensorRT环境都相同
相同环境下两次生成的engine也不一定完全一样

生成Engine并进行推理


engine = trt.Runtime(logger).deserialize_cuda_engine(serializedNetwork)
# 反序列化网络,将序列化的网络反序列化为可执行的引擎,可以用于推理
lTensorName = [engine.get_tensor_name(i) for i in range(engine.num_io_tensors)]
print(lTensorName)
# 获取引擎的输入输出名称

context = engine.create_execution_context()
# 创建执行上下文,用于执行推理,可以理解为GPU进程
context.set_input_shape(lTensorName[0], (1, 1, 28, 28))
# 设置输入形状

hInput = np.random.random((1, 1, 28, 28)).astype(np.float32)
# 创建输入数据,host端
dInput = cuda.mem_alloc(hInput.nbytes)
# 分配显存
houtput = np.empty((1, 1, 28, 28), dtype=np.float32)
# 创建输出数据
doutput = cuda.mem_alloc(houtput.nbytes)
# 分配显存
context.set_tensor_address(lTensorName[0], int(dInput))
context.set_tensor_address(lTensorName[1], int(doutput))
# 设置输入输出显存地址

#复制数据从host到device
cuda.memcpy_htod(dInput, hInput)
# 执行推理
context.execute_async_v3(0)
# 复制数据从device到host
cuda.memcpy_dtoh(houtput, doutput)
print(houtput)

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

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

相关文章

CVPR2024 | 改善多模态大模型底层视觉能力,NTU与商汤联合提出Q-Instruct,已开源

https://arxiv.org/pdf/2311.06783.pdf https://github.com/Q-Future/Q-Instruct 以 GPT-4V 为代表的多模态大语言模型&#xff08;MLLM&#xff09;为视觉感知和理解任务引入了范式转变&#xff0c;即可以在一个基础模型中实现多种能力。虽然当前的 MLLM 表现出了从低级视觉属…

移动距离 刷题笔记

依题意 给出两个数 n,m 两个数的坐标分标为 x1,y1 ; x2,y2; 所求最短距离即曼哈顿距离 d|x2-x1||y2-y1|; 当我们想求两个数的行号时 按正常数组的求法 &#xff08;n/w) 如果从1 开始 每一行的最后一个元素除于w的结果都比宽度1; 所以我们从1开始 于是 每一行的…

Java开发从入门到精通(七):Java的面向对象编程OOP:语法、原理、this、构造器

Java大数据开发和安全开发 &#xff08;一&#xff09;Java的面向对象编程1.1 什么是面向对象1.2 面向对象和面向过程的区别1.3 面向对象开发设计特征1.4 面向对象语法1.4.1 先创建对象模板1.4.2 实例化对象1.4.3 对象又该怎么理解?1.4.4 对象在计算机中的执行原理 1.5 类和对…

Palworld幻兽帕鲁管理员操作手册

Palworld幻兽帕鲁管理员操作手册 大家好我是艾西&#xff0c;在我们搭建完幻兽帕鲁服务器后肯定会涉及到后期的维护比如&#xff1a;角色修改&#xff0c;帕鲁修改&#xff0c;异常删除&#xff0c;公会修改&#xff0c;清理玩家&#xff0c;清理建筑&#xff0c;存档迁移等数…

寄存器(内存访问)

文章目录 寄存器&#xff08;内存访问&#xff09;1 内存中字的存储2 DS和[address]3 字的传送4 mov、add、sub指令5 数据段6 栈7 CPU提供的栈机制8 栈顶超界的问题9 push、pop指令10 栈段 寄存器&#xff08;内存访问&#xff09; 1 内存中字的存储 CPU中&#xff0c;用16位寄…

域内令牌窃取

前言 有这样一种场景&#xff0c;拿到了一台主机权限&#xff0c;是本地管理员&#xff0c;同时在这台主机上登录的是域管成员&#xff0c;这时我们可以通过dump lsass或通过 Kerberos TGT &#xff0c;但是这是非常容易被edr命中的。 本文就通过令牌窃取进行研究&#xff0c…

MySQL 篇-深入了解事务四大特性及原理

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 事务的概述 2.0 事务的特性 2.1 原子性 2.2 一致性 2.3 持久性 2.4 隔离性 2.4.1 脏读问题 2.4.2 不可重复读问题 2.4.3 幻读问题 3.0 事务的四个隔离级别 3.1…

Apache DolphinScheduler-3.2.0集群部署教程

集群部署方案(2 Master 3 Worker) Apache DolphinScheduler官网&#xff1a;https://dolphinscheduler.apache.org/zh-cnApache DolphinScheduler使用文档&#xff1a;https://dolphinscheduler.apache.org/zh-cn/docs/3.2.0截止2024-01-19&#xff0c;最新版本&#xff1a;3…

【学一点儿前端】vue3+vite不能使用require引入包的问题(require is not defined)

问题 今天本来想简单敲个码&#xff0c;结果遇到一个报错&#xff1a;require is not defined 原因 查了各方资料&#xff0c;原因如下&#xff1a; 前端有很多的工具包是commonjs的写法&#xff0c;只能用require引入&#xff0c;而vitevue3构建的项目不能使用require&…

Gemma: Open Models Based on Gemini Research and Technology

Gemma: Open Models Based on Gemini Research and Technology 相关链接&#xff1a;arxiv 关键字&#xff1a;Gemma、Google DeepMind、open models、language understanding、reasoning 摘要 这项工作介绍了Gemma&#xff0c;一系列轻量级、最先进的开放模型&#xff0c;基于…

C++中的STL-string类

文章目录 一、为什么学习string类&#xff1f;1.1 C语言中的字符串 二、准库中的string类2.2 string类2.3 string类的常用接口说明2.4 string类对象的容量操作2.5 string类对象的访问及遍历操作2.5 string类对象的修改操作2.7 string类非成员函数2.8 模拟实现string 一、为什么…

Python环境搭建 -- Python与PyCharm安装

一、Python安装 我们先找到Python的官方网站&#xff0c;在浏览器中搜索Python即可&#xff0c;然后进入Python官网 点击Downloads&#xff0c;选择对应匹配的操作系统 点进去之后&#xff0c;Python的版本分为稳定的版本和前置版本&#xff0c;前置的版本就是还没有发行的版本…

接口自动化测试思路和实战 —— 编写线性测试脚本实战!

接口自动化测试框架目的 测试工程师应用自动化测试框架的目的: 增强测试脚本的可维护性、易用性(降低公司自动化培训成本&#xff0c;让公司的测试工程师都可以开展自动化测试)。 自动化测试框架根据思想理念和深度不同&#xff0c;渐进式的分为以下几种: 线性脚本框架 模块…

室内定位在数字化中的应用

随着数字化经济的迅速发展&#xff0c;室内定位技术正逐渐成为一个不可或缺的重要组成部分。它不仅能够提升用户体验&#xff0c;还能够帮助企业实现更精准的市场定位和营销策略。本文将探讨室内定位在数字化经济中的应用及其带来的优势。 首先&#xff0c;室内定位技术在商业…

原生php单元测试示例

下载phpunit.phar https://phpunit.de/getting-started/phpunit-9.html 官网 然后win点击这里下载 新建目录 这里目录可以作为参考&#xff0c;然后放在根目录下 新建一个示例类 <?phpdeclare(strict_types1);namespace Hjj\DesignPatterns\Creational\Hello;class He…

Python3虚拟环境之pipenv

pipenv是python官方推荐的包管理工具&#xff0c;集成了virtualenv, pip和pyenv三者的功能。集合了所有的包管理工具的长处&#xff0c;自动为项目创建和管理虚拟环境。 安装 pip install pipenv在Pycharm中使用 修改Pipfile的安装源参数url&#xff0c;改为https://pypi.tun…

基于Python的中医药知识问答系统设计与实现

[简介] 这篇文章主要介绍了基于Python的中医药知识问答系统的设计与实现。该系统利用Python编程语言&#xff0c;结合中医药领域的知识和技术&#xff0c;实现了一个功能强大的问答系统。文章首先介绍了中医药知识的特点和传统问答系统的局限性&#xff0c;然后提出了设计思路…

如何在Windows系统部署Plex影音站点并实现公网访问内网媒体库

文章目录 1.前言2. Plex网站搭建2.1 Plex下载和安装2.2 Plex网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 用手机或者平板电脑看视频&#xff0c;已经算是生活中稀松平常的场景了&#xff0c;特别是各…

《鸟哥的Linux私房菜》第6章——总结与习题参考答案

目录 一、 简介 二、一些新了解的指令 1.touch- 修改文件时间或创建新文件 2.umask-新建文件/目录的默认权限 3.文件隐藏属性 4.文件特殊权限 5.file-观察文件类型 三、简答题部分 一、 简介 本章介绍了一些常用的文件与目录指令&#xff0c;包括新建/删除/复制/移动/查…

devops-git【部署及配置】

1、安装Git Linux做为服务器端系统&#xff0c;Windows作为客户端系统&#xff0c;分别安装Git&#xff1a; 【服务器端】 输入git --version 若出现 -bash:git:command not found则需要安装git&#xff1b;服务器端&#xff1a;输入yum -y install git安装完后&#xff0c;…