三、深入学习TensorRT,Developer Guide篇(二)

这篇具有很好参考价值的文章主要介绍了三、深入学习TensorRT,Developer Guide篇(二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这篇文章基于官方文档的第二节 TensorRT’s Capabilities,不要认为这节没有用啊,其实知道一个工具的capability还是比较重要的,学习一个工具你得知道这个工具有啥用,能干啥,这样你在后面遇到某个问题的时候能评估出来那些工具能够解决你的问题,哪些不能,这也是我们常说的工作效率中比较重要的一环。正如这一节官方文档开头所说:这一节给你个提供一个你能用TensorRT来干什么的overview,对于Tensorrt用户来说是非常重要的。

😍😍😍老规矩看前点个赞😍😍😍

2. TensorRT’s Capabilities

2.1 C++ and Python APIs

TensorRT的API具有C++和Python的语言绑定,这两者具有几乎相同的功能。Python API促进了与Python数据处理工具包和库(如NumPy和SciPy)的互操作性。C++ API可以更高效,并且可以更好地满足一些灵活的需求,例如在汽车应用程序中。(Python API并不是适用于所有平台,具体请参考NVIDIA TensorRT Support Matrix,进去搜索一下python关键字就好)

2.2 The Programming Model

我感觉这个官方文档不够精炼,很多地方都重复描述了,但是我为了更贴近原文档,所以也有一定程度的重复描述,大家见谅。
TensorRT在两个阶段进行操作,分别是在第一阶段,通常情况下你是离线执行的,就是单独执行,你将模型提供给TensorRT进行针对GPU的优化(build phase),在第二阶段,你使用优化后的模型来进行推理(runtime phase)。

2.2.1 The Build Phase

对于build phase的高阶结构就是TensorRT的Builder(C++,Python都有对应的API),builder负责优化模型并且生成一个engine,为了构建engine,你必须:

  • 创建网络定义
  • 为这个builder进行特定配置
  • 调用这个builder来创建engine

NetworkDefinition接口(C++, Python)用来定义模型,最常见的将一个模型转换为Tensorrt的方法就是从框架中导出ONNX格式的文件,然后使用TensorRT 的 ONNX解析器来填充这个网络,但是你也可以使用TensorRT的Layer(C++, Python)和 Tensor(C++, Python)这些接口(之前遇到过一个利用TensorRT部署YOLO网络的工程,就是自己通过这些API来进行网络构建和推理的,也不要忽视这种方法哟)

不管你选择哪一种方式,你都必须定义这个网络的输入输出是哪个tensor,未标记为输出的Tensor会被认为是可以被builder优化掉的临时值(transient values),输入和输出的tensor必须被命名,这样在运行的时候,TensorRT知道如何将输入输出buffer(这些buffer是由你之前单独进行定义的)绑定到模型上。(所以你明白为什么你看到的很多TensorRT的程序都会标记输入输出了吧)

BuilderConfig接口(C++, Python)被用来指明TensorRT应该如何优化模型,在可选的配置选项中,你可以控制TensorRT对于减少计算的精度、控制内存和运行速度的平衡和限制CUDA kernels的选择的能力。由于构建器可能需要几分钟甚至更长时间才能运行,因此您还可以控制构建器搜索内核的方式,以及缓存搜索结果以供后续运行使用。

在定义了网络和设置了builder configuration后,你可以调用builder来创建engine。builder消除了死计算(dead computations),折叠常量(folds constans,本质就是一种特殊的常量),并且对操作进行重新排序和组合,这样便可以在GPU上更有效地运行。它可以选择性地降低浮点计算的精度,通过简单地在16位浮点数中运行它们,或者通过量化浮点值以便可以使用8位整数执行计算。它还使用不同的数据格式对每层的多个实现进行计时,然后计算执行模型的最佳调度,从而最大限度地减少内核执行和格式转换的综合成本。(这个很重要,在面试的时候会问你,为什么使用TensorRT能够加速和优化计算呢?这就是标准答案,你如果是大佬,还可以反问面试官这个问题,看他怎么回答,哈哈

这个时候,builder以一个序列化(serialized)的形式创建了engine,我们称之为plan(每次看到这个名字我都觉得很奇怪,为啥叫plan),plan可以立即被反序列化(deserialized)或者存到磁盘中后续再使用。

注意:

  • 默认情况下,TensorRT创建的engine是针对当前的TensorRT和GPU的,如果为其他版本或者硬件做更多更改,请参考: Version Compatibility 和 Hardware Compatibility
  • 为了减少内存开销,TensorRT的网络定义对一些参数数组(比如卷积的权重)进行的是浅拷贝。因此,在构建阶段完成之前,一定不要释放这些数组的内存。当使用ONNX解析器导入网络时,解析器拥有权重,因此在构建阶段完成之前不能销毁它,不然数据没了,构建就出问题了。
  • builder对算法进行计时,以确定最快的那一组参数。如果这时候与其他GPU工作并行执行builder,可能会扰乱时间,导致优化失败或者无法获得最好的结果,简而言之,就是在优化的时候不要使用多卡啦。

2.2.2 The Runtime Phase

对于执行阶段的TensorRT高级接口是Runtime(C++, Python),当使用runtime时,你肯定会按照下面的步骤:

  • 反序列化一个plan来创建一个engine
  • 从这个engine中创建一个执行上下文(execution context

然后,重复进行:

  • 填充用于推理的输入缓冲区(就是将数据拷贝到input buffer里面去)
  • 调用execution contextenqueueV3()函数来运行推理(其实现在很多还在用enqueue()enqueueV2()

Engine(C++, Python)接口表示一个优化后的模型,你可以从一个engine中来查询很多信息,如输入输出的tensors、需要的dimensions、数据类型、数据格式等等(这个很重要啊)

ExecutionContext接口(C++, Python)是从engine中创建来的,是推理过程中非常重要的接口。execution context包含了所与有特定调用相关联的所有状态,因此你可以拥有与单个引擎相关联的多个上下文,并且并行地运行它们。在调用推理时,必须在适当的位置设置输入和输出缓冲区,根据数据的性质,这可能在CPU或GPU内存中。如果根据模型很难判断,那可以通过查询engine来确定在哪个内存空间中提供缓冲区。

设置缓冲区后,可以对推理进行排队(enqueueV3,排到你的任务就执行你的任务)。所需的内核在CUDA流上排队,并尽快将控制返回给应用程序(否则可能导致长时间的阻塞)。一些网络需要在CPU和GPU之间进行多次控制传输,因此控制可能不会立即返回。要等待异步执行完成,请使用cudaStreamSynchronize在流上同步。

2.3 Plugins

TensorRT对于一些没有原生支持的操作,提供了一个Plugin接口来允许自己实现相应的操作。Plugin通过TensorRT的PluginRegistry创建和注册,这样就可以被ONNX解析器在翻译网络的时候找到。TensorRT附带了一个插件库,其中许多插件和一些附加插件的源代码可以在这里找到(算子不支持的话,优先建议你来这里搜搜看)。你也可以实现你自己的plugins并且和engine一起进行序列化操作。

2.4 Types and Precision

TensorRT 支持 FP32、FP16、INT8、INT32、UINT8 和 BOOL 数据类型。有关层 I/O 数据类型规范, 请参阅TensorRT Operator 文档。

  • FP32、FP16:未量化的高精度类型
  • INT8
    • 隐式量化:解释为量化整数类型,一个INT8的tensor必须有一个关联的缩放因子(要不是通过calibration要不是通过setDynamicRange API)(多解释一点,calibration就是通过放入一堆数据,比如几十上百张图片来决定量化的max和min再确定sacle factor,这些数据被称之为calibration set,这也是面试可能会问的问题。还有基于这个的另一个问题,就是1. 如何选择calibration set中的数据,答案是注意和真实场景的数据的分布尽量保持一致 2. 如果calibration中的数据出现了问题,比如严重不正确的异常值怎么办呢?这个我也不知道答案是什么,个人理解是加强数据的筛选和清洗,以及后期进行验证)
    • 显式量化:解释为有符号整型,从INT8转换或者转换到INT8需要显式地经过Q/DQ层(这个没见过,我们后面有机会再回来补充)
  • UINT8
    • 一种只用在网络I/O的数据类型
    • 在其他操作中使用数据之前,必须使用CastLayer将网络级输入从UINT8转换为FP32或FP16(也就是网络内部是没有UINT8这个数据类型的,同上一条)。
    • UINT8的网络级输出必须由一个明确插入到网络中的CastLayer产生(只支持从FP32/FP16到UINT8的转换,就是说内部如果是INT8的话,输出不可能是UINT8的?)。
    • UINT8量化目前还不支持
    • ConstantLayer不支持将UINT8作为输出数据类型
  • BOOL:常规的布尔类型,没啥特殊的

TensorRT选择CUDA kernels来完成浮点运算的时候,默认是使用FP32,有两种配置不同级别精度的方法:

  • 为了在模型级别控制精度,BuilderFlag选项(C++, Python)可以向TensorRT指示,在搜索最快的实现时,它可能会选择较低精度的实现(因为较低精度通常更快)。因此,你可以轻松地指示TensorRT对整个模型使用FP16计算。对于输入动态范围近似为1的正则化模型,这通常会产生显著的加速,而精度的变化可以忽略不计。
  • 对于细粒度控制,由于部分网络对数字敏感所以需要高的动态范围,因此某一层必须以更高的精度运行,这个时候可以为该层指定算术精度。

对于更多的精度内容,可以参考:Reduced Precision

2.5 Quantization

TensorRT支持量化浮点值,其中浮点值被线性压缩并四舍五入为8位整数。这大大提高了算术吞吐量,同时降低了存储需求和内存带宽。当量化一个浮点张量时,TensorRT必须知道它的动态范围(dynamic range)——也就是说,哪个值的范围是重要的——在量化时,超出这个范围的值将被限制。

动态范围信息可由builder根据代表性输入数据计算(这称为校准,也就是我上面说的你选择出来的那部分数据)。或者您可以在框架中执行量化感知训练(quantization-aware training, QAT, 这个挺重要的,但是我没有接触过,后面有机会补上),并将带有必要动态范围信息的模型导入到TensorRT中。

其他细节部分,请参考: Working with INT8

2.6 Tensors and Data Formats

在定义网络时,TensorRT将张量当做一个多维的C风格数组。每个层对其输入都有特定的解释:例如,2D卷积将假设其输入的最后三个维度是CHW格式(没有选择使用例如WHC格式),请参阅NVIDIA TensorRT Operator’s Reference,了解每个层如何解释其输入。注意张量被限制在最多2^31-1个元素(也就是最多32位能存储的值)。

在优化网络的同时,TensorRT在内部执行转换(包括到HWC,但也包括更复杂的格式),以使用最快的CUDA内核。通常,选择格式是为了优化性能,应用程序无法控制这些选择(也就是说完全是内部的,我们无法选择)。然而,底层数据格式在I/O边界(网络输入和输出,以及向插件传递数据和从插件传递数据)上是暴露出来的,以允许应用程序将不必要的格式转换最小化。(这里我又想到一个面试题,就是对于这种并行的处理,CHW和HWC哪个更高效呢?考虑到这种高度并行的处理,数据之间可以并行化是最重要的,所以HWC是更高效的,因为可以拆分为m*n*c,m和n就是对应卷积核的大小,这样可以在多个kernel中进行并行计算,但是对于CHW却是不好拆分的,也就是不好进行并行计算的)。

对于其他的细节部分,请参考: I/O Formats

2.7 Dynamic Shapes

默认情况下,TensorRT是基于已经定义好的输入的形状进行优化的(batch size、image size等),但是builder也可以被配置为允许在运行的过程中进行维度的调整。为了进行这种设置,你需要在builder configuration中指定一个或多个OptimizationProfile实例(C++, Python)包含每个输入的最小和最大形状,以及该范围内的优化点(optimization point)。

TensorRT为每个配置文件创建一个优化的引擎,选择在[minimum,maximum]范围内的所有shapes的CUDA kernels,并且在优化点是最快的——通常每个配置文件有不同的内核,你可以在运行时选择配置文件。(这里也有一个面试题:如何给TensorRT设置Dynamic Shapes

对于其他的细节部分,请参考:Working with Dynamic Shapes

2.8 DLA

TensorRT 支持 NVIDIA 的深度学习加速器 ( NVIDIA’s Deep Learning Accelerator, DLA),这是许多 NVIDIA SoC 上存在的专用推理处理器,支持 TensorRT 层的子集。 TensorRT 允许你在 DLA 上执行网络的一部分,而在 GPU 上执行其余部分;对于可以在任一设备上执行的层,你可以在构建器配置中逐层选择目标设备。(就是当有DLA可用的时候,你设置某些层运行在DLA上,会让算法变得更强)

对于其他的细节部分,请参考:Working with DLA

2.9 Updating Weights

构建engine时,你可以指定稍后更新其权重。如果你经常更新模型的权重而不更改结构,例如在强化学习中或在保留相同结构的情况下重新训练模型时,这可能会很有用。权重更新是使用Refitter (https://docs.nvidia.com/deeplearning/tensorrt/api/c_api/classnvinfer1_1_1_i_refitter.html、https://docs.nvidia.com/deeplearning/tensorrt/api/python_api/infer/Core/Refitter.html)接口。(这也是一个很实用的功能接口)

对于其他的细节部分,请参考:Refitting an Engine

2.10 trtexec Tool

包含在samples文件夹中的是一个命令行包装工具,称为trtexec。trtexec是一个可以直接使用的 TensorRT 的工具,无需开发自己的应用程序就可以实现很多功能。(这个工具的确挺有用,我们后面应该会用到他)。trtexec有三个主要用途:

  • 根据随机或用户提供的输入数据对网络进行基准测试(测试整体效果如何,是否符合要求)。
  • 从模型生成序列化引擎(直接创建engine,不需要自己定义layertensor那些)。
  • 从构建器生成序列化时序缓存。

对于其他的细节部分,请参考: trtexec

2.11 Polygraphy

Polygraphy 是一个工具包,旨在帮助在 TensorRT 和其他框架中运行和调试深度学习模型。它包括一个Python API和 a command-line interface (CLI) 。(这个工具我目前还没有用过,比如下面提到的精度对比,我都是随机采样一些层的信息存在日志里面进行对比的,的确比较低级和繁琐,这个工具大家有空可以好好研究一下)

除此之外,通过 Polygraphy,还可以:

  • 在多个后端(例如 TensorRT 和 ONNX-Runtime)之间运行推理,并比较结果(例如API、CLI)。
  • 将模型转换为各种格式,例如后量化 TensorRT engine(例如API、CLI)。
  • 查看有关各种类型模型的信息(例如CLI)
  • 在命令行修改 ONNX 模型:
    • 提取子图(例如CLI)。
    • 优化和清理(例如CLI)。
  • 隔离 TensorRT 中的错误策略(例如CLI)。

对于其他的细节部分,请参考:Polygraphy repository

第二节的内容差不多就是这些,好累呀,不过能系统的学习一下也是非常好的,学习就是要系统,不可以东一下西一下,这一节基本就把TensorRT的特性都讲完了,后面哪些工具或者特性忘记了,可以快速的到这里来浏览一下。

😍😍😍老规矩看后也点个赞😍😍😍文章来源地址https://www.toymoban.com/news/detail-827194.html

到了这里,关于三、深入学习TensorRT,Developer Guide篇(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《CUDA C++ Programming Guide》第一章 CUDA介绍

    使用GPUs的好处 在相同的价格和功耗范围内,图形处理器 GPU 比 CPU 提供了更高的指令吞吐量和内存带宽, 许多应用程序利用这些更高的功能在 GPU 上比在 CPU 上运行得更快。相比较其他计算设备,如 FPGA,也是非常节能的,但其提供了比 GPU 少得多的编程灵活性。 GPU 和 CPU 之间

    2024年02月15日
    浏览(32)
  • CUDA与TensorRT(5)之TensorRT介绍

    TensorRT基本介绍 TensorRT是可以在NVIDIA各种GPU硬件平台下运行的一个C++推理框架。我们利用Pytorch、TF或者其他框架训练好的模型,可以转化为TensorRT的格式,然后利用TensorRT推理引擎去运行我们这个模型,从而提升这个模型在英伟达GPU上运行的速度。速度提升的比例是比较可观的

    2024年02月16日
    浏览(31)
  • Windows11(CUDA11.7)下安装TensorRT

    TensorRT有多厉害就不多说了,因为确实很好用。 作为在英伟达自家GPU上的推理库,这些年来一直被大力推广,更新也非常频繁,issue反馈也挺及时,社区的负责人员也很积极,简直不要太NICE。 那么我们应该如何入门呢 我们应该先安装好TensorRT 在博主研究了两天观摩了很多大

    2024年02月09日
    浏览(54)
  • ModuleNotFoundError: No module named ‘cuda‘、‘tensorrt‘

    先安装两个TensorRT的依赖库 点我进入TensorRT官方下载地址, win下载后得到zip文件 TensorRT-8.6.0.12.Windows10.x86_64.cuda-11.8.zip 点我进入官方TensorRT组件的版本管理   确认本机是否成功安装CUDA Toolkit, win + R 打开\\\"运行\\\",输入 cmd 终端。 输入指令: 找到本机安装CUDA的文件路径: 默认安装通常

    2024年02月16日
    浏览(33)
  • ChatGPT引领的AI面试攻略系列:cuda和tensorRT

    cuda和tensorRT(本文) AI全栈工程师 随着人工智能技术的飞速发展,该领域的就业机会也随之增多。无论是刚刚踏入这一领域的新手,还是经验丰富的专业人士,都可能面临着各种面试挑战。为了帮助广大求职者更好地准备人工智能相关的面试,本系列博客旨在提供一系列精选

    2024年03月15日
    浏览(46)
  • pytorch搭建squeezenet网络的整套工程,及其转tensorrt进行cuda加速

    本来,前辈们用caffe搭建了一个squeezenet的工程,用起来也还行,但考虑到caffe的停更后续转trt应用在工程上时可能会有版本的问题所以搭建了一个pytorch版本的。 以下的环境搭建不再细说,主要就是pyorch,其余的需要什么pip install什么。 squeezenet的网络结构及其具体的参数如下

    2024年02月09日
    浏览(39)
  • Orin 安装CUDA CUDNN TensorRT Opencv和输入法的环境配置

    有两种方法可以安装CUDA环境 在刷机完成的Orin,执行如下命令: 注释–如果在执行第三行命令,报错的话,先查看nvidia-l4t-apt-source.list 将其修改为 修改完后,重新执行上面那三行命令 CUDA 检查是否安装成功 运行命令 输出结果 如果报错,需要把nvcc添加到环境变量,方法如下

    2024年02月10日
    浏览(39)
  • yolov7的 TensorRT c++推理,win10, cuda11.4.3 ,cudnn8.2.4.15,tensorrt8.2.1.8。

    yolov7的 tensorrt8 推理, c++ 版本 环境 win10 vs2019 opencv4.5.5 cuda_11.4.3_472.50_win10.exe cudnn-11.4-windows-x64-v8.2.4.15 TensorRT-8.2.1.8.Windows10.x86_64.cuda-11.4.cudnn8.2.zip RTX2060推理yolov7, FP32 耗时 28ms  ,FP16 耗时 8ms,单帧对应总耗时30ms 和 10ms。 推理yolov7-tiny,FP32 耗时 8ms  ,FP16 耗时 2ms。 tensorr

    2024年02月15日
    浏览(45)
  • ubuntu20.04显卡驱动cuda cudnn conda TensorRT安装及配置

    如果要使用 TensorRT ,请注意CUDA 支持的最高算力要大于等于GPU本身的算力, 可以先看3小节 conda和pip换源直接看2.3小节 本人已在ubuntu20.04下安装成功。其他版本步骤应该差不多 如果帖子有帮助,感谢一键三连, ^_^ 部署有问题的小伙伴欢迎留言和加 Q 裙- 472648720 BEV各算法环境部

    2024年01月22日
    浏览(55)
  • Win11基于WSL2安装CUDA、cuDNN和TensorRT(2023-03-01)

    如果有小伙伴看了2023-03-05更新,发现设置环境变量后运行cuda代码在链接过程中仍然会有报错问题啥的,那我这里建议,先别管2023-03-05更新的内容了,还是按照我博客里的安装步骤一步一步往下安装,用 sudo apt install nvidia-cuda-toolkit 命令去安装nvcc,也不需要配置环境变量了。

    2024年02月02日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包