TensorRT学习笔记 1 - 概述

news2025/7/7 20:31:43

TensorRT系列笔记是作者半年来学习和使用TensorRT(后称trt)积累笔记 整理和心得。包含trt的基本概念,相关资料,实践笔记,踩坑记录等等。

本篇博客希望可以初步说清楚

  • trt是什么;
  • 模型部署为什么使用trt,以及使用trt的基本步骤

目录

1. trt是什么

1.1 从模型部署说起。

1.2 如何提升速度又减低内存

1.3 什么是TensorRT

1.4 使用注意

2. trt的基本用法

2.1 为什么trt可以为深度学习模型加速

2.2 trt使用的基本步骤 

2.3 构建期的基本方法及其比较

2.4 相关概念的介绍 

3. 小结


1. trt是什么

1.1 从模型部署说起。

算法工程师们训练了一个优秀的模型,并保存为一批参数的集合,tensorflow一般保存的是ckpt文件,torch一般保存的是pt文件。算法工程师在使用自己训练的模型的时候,使用的步骤一般是,编写推理代码,加载模型,输入测试数据,获取结果。此时算法工程师们一般更关注的是结果的准确率、语音的自然度和表现力,不关心速度、实时率、吞吐率、首包延迟等等工程性指标。ckpt和pt文件中保存了许多与前向推理无关的参数,占用内存,拖慢推理速度。并且想ckpt这样的模型,在恢复模型之前需要重新定义一遍网络结构(拜静态图所赐),速度就更慢了。

当然,爱折腾的算法工程师们,愿意花费一点点精力,把原始的模型转换成pb文件,pb文件可以只存储参数;也可以把参数和网络结构一并存储,这样就不需要重新再代码中定义网络结构,文件大小也被压缩,看起来友好了很多。

谷歌推荐的保存模型的方式是保存模型为 PB 文件,它具有语言独立性,可独立运行,封闭的序列化格式,任何语言都可以解析它,它允许其他语言和深度学习框架读取、继续训练和迁移 TensorFlow 的模型。
它的主要使用场景是实现创建模型与使用模型的解耦, 使得前向推导 inference的代码统一。另外的好处是保存为 PB 文件时候,模型的变量都会变成固定的,导致模型的大小会大大减小,适合在手机端运行。

 但是,这里的前向推理仍然是按照网络结构的定义,一个节点一个节点的计算。速度还是不尽人意。而速度和内存占用恰恰是算法工程化的工程师极度关注的东西,因为这些指标直接关系到模型上线之后的成本问题和用户体验问题。毕竟老板不希望因为推理速度慢,内存占用大,导致一个模型占用巨大的硬件成本,用户也不希望发送一个请求,在等待了漫长的一秒钟之后才收到了第一批返回数据。

因此,模型的部署绝不是简单的把训练好的模型直接放到机器上运行就完事儿了,从训练完毕到服务用户之间,必然需要有许多的工作要做,比如如何把模型变小,如何让模型变快,如何让模型实现并发,这就是模型部署部分的工作。

1.2 如何提升速度又减低内存

作为一个程序员,作为一个有一张显卡执行并行计算的程序员,作为一个有高数和线性代数等作为武器的程序员,当然是希望用尽各种方法把计算的速度提上来。

一个很直接的想法,模型内部的前向推理,本质上就是一个有一个的矩阵运算,还记得线性代数你看了一遍又一遍的矩阵运算规则吗,现在他们从一个个枯燥的公式,变成了你的有力武器。有的矩阵运算原本是先做乘法在做加法,现在可以把它们变成先做拼接在做乘法,原来的若干次运算变成了一次运算,速度是不是提升了。

如果把前向推理的所有计算都做了合并和优化,是不是计算就更快了(计算次数少了,有显卡的并行计算加持,不用太担心大矩阵运算的开销),那么多的节点优化成了一个节点,是不是内存也会变少了?那么我们的目标是不是就达成了。

当然,这些工作已经有人帮我们做了。比如百度和阿里推出了模型优化部署方案,比如英伟达推出的TensoRT。

1.3 什么是TensorRT

  • 用于高效实现已经训练好的深度学习模型的推理过程的SDK
  • 内含推理优化器运行时环境
  • 目的是使得深度学习模型可以更高吞吐量更低的延迟运行
  • c++和python API可以等价混用

总结起来,tensorrt是一种与模型优化和部署相关的一整套工具,这套工具含有推理优化器和运行时环境,可以训练好的模型的推理过程做运算合并和优化生成一种新的计算流程并保存为trt引擎,并高效的完成推理过程。最终目的是提高深度学习模型的吞吐和延迟,使其更符合线上服务的需求。

1.4 使用注意

  • trt与硬件相关,A10上生成的引擎,一般无法在V100上使用
  • trt可以与cuda编程结合,提升速度和编程灵活性。

2. trt的基本用法

2.1 为什么trt可以为深度学习模型加速

  • 主要从以下两个阶段完成模型的优化和推理加速。
  • 构建期(推理优化器)
    • 模型解析/建立 : 加载onnx等其他格式的模型, 或者使用原生API搭建模型
    • 计算图优化 : 使用横向层融合和纵向层融合
    • 节点消除 : 去除无用层、无用的节点变化, 比如pad, slice, concat, shuffle
    • 多精度支持 : fp32, fp16, int8, tf32(这个过程可能插入reformat节点,用于数据类型变换)
    • 优选kernel/format : 硬件有关优化。trt是硬件相关的,每个节点有多种实现,哪一种更好需要trt选择
    • 导入plugin : 用于实现自定义的操作
    • 显存优化 : 显存池复用,显存池由trt维护
  • 运行期(运行时环境)
    • 运行时环境 : 管理对象生命期、内存、显存, 处理异常
    • 序列化与反序列化 : 推理引擎保存至磁盘,或者加载至显存

2.2 trt使用的基本步骤 

trt的使用也是遵循两个阶段。首先在构建期,使用工具把深度学习模型转换成指定精度的序列化表示(trt引擎),这是模型部署的前期准备工作;然后再运行期加载这个引擎,并编写对应的输入输出数据的处理代码,完成模型的推理。

如果你选择框架自带的parser解析深度学习模型并转化为trt引擎。

  • 构建期有几种不同的路径,这里介绍两种:
    • pt -> onnx -> trt
    • pb -> (pb2onnx模块) -> onnx -> trt
    • 可以使用int8量化,需要自己实现calibrator类。
    • onnx -> trt 这个步骤一般直接使用tensorrt提供的trtexec工具转换。
    • 不支持节点有一下几种方法

      • 修改parser: 修改trt源代码,重新编译trt
      • tensorrt实现plugin
      • 修改onnx计算图(onnx-surgeon)
      • 修改源模型
  • 运行期
    • 建立engine, context
    • 准备buffer, 用于host和device之间的数据拷贝
    • 执行推理,即执行execute(_v2)函数

如果你选择使用trt API自行搭建前向推理计算的所有流程

  • 构建阶段
    • 建立Logger, 这是日志记录器
    • 建立Builder(网络元数据)和BuilderConfig(网络元数据的选项、配置, 比如是否开启精度等)
    • 创建Network, 也就是自行搭建计算图的内容
    • 生成序列化文件
  • 运行阶段
    • 建立engine
    • 建立context, 类比cpu进程,负责管理,是执行trt的主体。
    • 准备host buffer, device buffer
    • buffer拷贝 : h -> d
    • 执行推理
    • buffer拷贝 : d -> h
    • 善后工作
  • 上述概念介绍见2.4
  • 综上,一个完整的trt开发和推理流程应该是这样的
    • 准备原始网络代码,基于tensorflow或者torch或者基于其他框架的代码。必要时需要对代码做修改。
    • 准备训练好的原始模型,比如ckpt模型等等。
    • 从ckpt模型获取模型中的所有张量以及对应的张量名称
    • 确定模型的所有输入,以及输入的形状,如果有动态形状,使用 -1 指代,并指定动态形状的范围。可以借助netron工具查看计算图。
    • 按照原始网络代码,使用trt API(python / c++)自行搭建网络,并将获取的张量值按照张量名称放进自行搭建的网络中
    • 搭建完毕之后指定网络的输出,并执行编译代码,生成engine
    • 根据模型的输入输出完成engine 的 inffer代码。见上述运行阶段步骤。

2.3 构建期的基本方法及其比较

构建期是把深度学习模型转换成trt引擎的步骤,有三种不同的方法。方法不同,但是目的不同,区别在于难度和灵活度等。但是一般情况下,使用API搭建的方式,性能可以达到最优。

  • 第一种: 使用框架自带的trt接口, 比如tf-trt, troch-tensorrt
    • 这种方式简单灵活,部署仍然使用的原始框架。
    • 对于不支持的算子,不需要书写plugin,而是会自动会滚到原始框架中进行计算。
  • 第二种:最推荐 使用parser, 比如tf/torch/.. -> onnx. -> tensorrt
    • 流程成熟, onnx通用性比较好,方便网络调整,兼顾效率性能
    • 对于不支持的算子,可以通过修改网络,修改parser, 书写plugin等方法实现。
  • 第三种: 使用API自行搭建网络
    • 性能最优,精细控制网络,兼容性最好

2.4 相关概念的介绍 

  • Logger, 日志记录器, 多个builder可以共享一个logger
    • 可选参数: verbose, info, warning, error, internal_error, 用于产生不同等级的日志,有详细到简略
  • Builder, 引擎构建器,是构建推理引擎的核心对象
    • builder = trt.BUilder(logger)
    • 仅仅作为构建引擎的入口
    • Dynamic shape模式必须使用 builderConfig以及相关的API
  • Builderconfig, 网络属性设置选项
    • config = builder.create_builder_config()
    • 设置是否开启疯跑6, int8量化等
    • 设置其他高级选项,比如 set_static_sources/set_timing_cache/algorithm_selector
  • Network, 网络具体构建
    • network = builder.creat_network()
  • explicit batch模式和 implicit batch模式
    • implicit模式中,所有张量的batch维度不会显式指定,而是在运行期再指定
    • explitcit模式(推荐)表示,所有张量的batch维度,需要显式的指定。
    • onnx倒入的模型默认使用explicit batch 模式
  • dynamic shape模式
    • 使用这种模式的原因:
    • 在实际场景中,需要使用同一个模型处理不同尺寸的数据,如图像分辨率,语音文本的长度等都是随时变化的
    • 实际场景中,数据的batch大小也是随时变化的,
    • 因此,允许模型张量的部分维度延迟到运行在做具体指定或者确认。
    • 构建阶段需要使用builder.create_optimization_profile指定该张量所有可变维度的变化范围
    • 运行阶段,需要使用context.set_binding_shape(axis, [reshape])指定张量的实际维度
  • binding
    • engine/context给所有的输入输出张量都安排了位置
    • 总共有engine.num_bindings个binding, 输入张量在前,输出张量在后(只有一个profile时)
    • 运行阶段绑定张量形状,要按照指定的位置绑定,这样trt才能初始化整个网络,当指定输入形状之后,trt会自动计算输出张量的形状,便于用户获取输出张量的形状,提前为输出张量开辟空间,拷贝输出数据。
    • 要注意,在指定多个profile是,binding的规则会比较复杂。
  • buffer
    • cuda的异构计算
      • 同时准备cpu内存和gpu显存
      • 开始计算之前,把数据从内存拷贝到显存
      • 计算时的输入输出数据都在gpu上进行读写
      • 计算完成之后,把结果从gpu拷贝到cpu
  • 序列化与反序列化
    • 二者环境必须完全统一,版本统一,应将统一
    • 同一个平台同一个环境生成的engine也可能不同。原因是在不同的构造过程中,由于轻微的扰动,同一个算子的优化使用了不同的实现。
    • 一种解决方式是,使用algorithmSelector或者timemingCache多次生成一模一样的engine。

3. 小结

至此,我们了解了什么是tensorrt, trt是用来干什么的,trt是如何实现这些功能的,trt基本的使用方法,trt使用中涉及的基本概念。

后面几篇笔记,我们将会了解trt如何下载和在python环境中使用,并给出onnx转trt的一个示例(不一定可运行),给出API搭建引擎过程中的一些细节。还会给出一些相关的参考资料。

更进一步的,还会介绍一个引擎搭建完毕可运行的时候,我们如何测试他们的指标等等。

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

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

相关文章

渗透攻击MS08-067

学校课程关于Metasploit有基础的几个小实验,把它整理分享在这里。 实训目的: 熟悉Metasploit终端的使用方法,了解MS08-067漏洞,掌握对MS08-067漏洞攻击的方法。 场景描述: 在虚拟机环境下配置 “WinXP1”和“Kali …

华为机试_HJ63 DNA序列【中等】

目录 描述 输入描述: 输出描述: 解题过程 提交代码 学习代码 代码一 收藏点 描述 一个 DNA 序列由 A/C/G/T 四个字母的排列组合组成。 G 和 C 的比例(定义为 GC-Ratio )是序列中 G 和 C 两个字母的总的出现次数除以总的字…

公开竞价与封闭式竞价有什么不同?

电子竞价是电子采购的一种形式。电子采购是指通过信息和网络系统在线进行的招标采购过程。 电子竞价是指一种基于网络的系统,允许潜在供应商在网上实时竞争商品/服务的价格。电子竞价的使用方式类似于e-bay平台,出价最高者获胜。在建筑业,这…

前端_Vue_7.表单输入绑定

文章目录一、 表单输入绑定1.0. 表单&表单元素1.0.1. 表单1.0.2. 表单元素1.1. 基本用法1.1.1. 文本1.1.2. 多行文本1.1.3. 复选框1.1.4. 单选按钮1.1.5. 选择器1.2. 值绑定1.2.1. 复选框1.2.2. 单选按钮1.2.3. 选择器选项1.3. 修饰符1.3.1. .lazy1.3.2. .number1.3.3. .tr…

三角函数公式

三角函数的定义 锐角三角函数任意角三角函数正弦sin⁡Aac\sin A\dfrac acsinAca​sin⁡θyr\sin \theta\dfrac yrsinθry​余弦cos⁡Abc\cos A\dfrac bccosAcb​cos⁡θxr\cos \theta\dfrac xrcosθrx​正切tan⁡Aab\tan A\dfrac abtanAba​tan⁡θyx\tan \theta\dfrac yxtanθ…

mysql中常用命令完整大全 适用于mysql8.0

关于安装部分就去看其他人的一些文章即可网上太多,这篇文章主要就是记录本人的一些关于mysql操作上的笔记。 mysql中常用命令1.登录数据库2.查看当前数据库3.创建数据库4.删除数据库5.创建表user基于以下条件6.使用主键约束7.指定非空8.唯一约束9.默认约束10.设置表…

物联网时代下的5G融合定位,可以实现哪些功能?

5G具有高带宽、高频谱(毫米波)、多天线阵列等特性,通过提升无线定位算法的能力、室内数字系统建设、完善5G定位服务流程以及与其它定位技术和平台的结合,可提高5G定位精度。室内高精度定位服务为5G定位扩展到更多应用场景和领域构…

C++:类和对象:运算符重载

前言: 运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。 1:加号运算符重载 对于内置的数据类型, 编译器知道如何运算,可以很直观的得到结果 int a 10; …

西瓜书-支持向量机

支持向量机 支持向量:距离超平面最近的这几个训练样本点。 支持向量机的核心思想是最大化间隔γ2∣∣w∣∣\gamma \frac{2}{||w||}γ∣∣w∣∣2​。 求极大转换为求极小,转化为凸规划问题。 对偶问题 利用拉格朗日乘子法,对于不等式约束,…

安全网络身份认证系统的设计与实现

本文章源码地址:https://gitee.com/sukels/shirohttps://gitee.com/sukels/shiro 摘 要 随着互联网的飞速发展,Web应用的安全问题日益凸显。为了保护Web应用中用户和企业的敏感信息,认证授权加密已经成为了Web应用中不可缺少的部分。但是随之而来是巨大的代码工作…

欧科云链半年报解读Final

欧科云链半年报解读:净利润同比扭亏为盈,区块链大数据等创新业务贡献新增长曲线 日前,欧科云链控股(01499.HK)发布2022年度截至9月30日止的六个月中期报告。报告显示,公司在2022年4月1日至2022年9月30日实现…

【idea插件】EasyCode介绍与使用

1.简介 EasyCode是idea的一个插件,主要功能是代码生成,类似的插件还有jpa support EasyCode是idea的一个插件,可以采用图形化的方式对数据的表生成entity,controller,service,dao,mapper……无 需任何编码,简单而强大。可以大幅度的提高开发效率.下面来…

UG/NX二次开发Siemens官方NXOPEN实例解析—2.7 DiameterSymbol

列文章目录 UG/NX二次开发Siemens官方NXOPEN实例解析—2.1 AssemblyViewer UG/NX二次开发Siemens官方NXOPEN实例解析—2.2 Selection UG/NX二次开发Siemens官方NXOPEN实例解析—2.3 Selection_UIStyler UG/NX二次开发Siemens官方NXOPEN实例解析—2.4 File2Points UG/NX二次…

第三章:远程登陆Linux系统-[实操篇]

一:为什么需要远程登陆Linux 1.1示意图 1.2说明 说明: 公司开发时候, 具体的情况是这样的 1) linux 服务器是开发小组共享的. 2) 正式上线的项目是运行在公网的. 3) 因此程序员需要远程登录到 centos 进行项目管理或者开发. 4) 画出简单的网络拓扑…

Vue3——路由的query参数和命名路由以及默认插槽slot的使用

这里主要在message页面组件和detail页面组件介绍 看一个案例,当一个二级路由下面又有许多个不同的跳转页面的时候,比如下图的about/message/detail , 需要分别展示多条信息,这里不能给每一条信息都配置一个组件,那样当信息的数量…

RocketMQ-RocketMQ 系统架构以及消息的概念

文章目录一、RocketMQ的消息模型1、RocketMQ的基础消息模型,一个简单的Pub/Sub模型2、RocketMQ 扩展后的消息模型3、RocketMQ的部署模型二、RocketMQ的系统架构2、Consumer3、Name Server3.1、路由注册3.2、路由剔除3.3、路由发现3.4、Client 对 NameServer选择策略…

Spring5框架总结学习(从入门到进阶)-AOP

文章目录AOP1、基本概念2、底层原理3、底层原理实现4、AOP(术语)5、准备工作6、基于注解实现AOP 1、基本概念 面向切面编程可用对各个业务逻辑各个部分进行隔离 2、底层原理 AOP底层使用动态代理 有2种情况动态代理 有接口 使用JDK动态代理无接口 使…

ffmpeg编译安装

ffmpeg编译安装前言一、下载ffmpeg二、编译安装2.1 Linux编译ffmpeg2.2 Windows编译ffmpeg总结前言 Fmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含…

154. SAP UI5 Smart Table 和 Smart Filter Bar 的联合使用方法介绍

本教程第 147 个步骤,我们介绍了 SAP UI5 Smart Table 控件的用法: SAP UI5 应用开发教程之一百四十七 - SAP UI5 SmartTable 控件的使用介绍如下图所示: 本步骤我们在 Smart Table 本身的基础上再进一步,学习如何将 Smart Table 配合 Smart Filter Bar 共同使用。 先看一…

JDK之强软弱虚引用

Java中强软弱虚引用的整体架构: 强引用 当内存不足,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会对该对象进行回收,死都不收。 强引用是我们最常见的普通对象引用,只要还有强引用指向一个对象…