TensorRT-10.0 碎碎念

好久没看TensorRT了,一是大模型太火,很多注意力都在大模型上,另一个是之前TensorRT的性能也足够,没有更新的必要。现在TensorRT也更新了正式的10.0GA版本,也是时候看下新版trt有什么新特性,是否值得老版模型的迁移。

这篇之后也会随时更新。

值得看的新特性

安装方式

With 10.0, apt-get install tensorrt or pip install tensorrt will install all relevant TensorRT libraries for C++ or Python.

这个话题还是提一下比较好。

我之前是用trt一直都是直接下载好tar包( TensorRT 10.0 GA for Linux x86_64 and CUDA 12.0 to 12.4 TAR Package)解压自己再设置环境,没怎么用过dep和rpm的形式,因为这两种方式都需要sudo和root权限,而且版本无法选择也不够灵活。

使用tar包的好处是可以方便切换TensorRT的版本进行测试,不同版本只要设置好环境变量就行:

export LD_LIBRARY_PATH=/software/TensorRT-8.6.1.6/lib:$LD_LIBRARY_PATH

唯一注意的就是在安装python版本trt的时候(一般这个python安装包在下好的tar中),环境变量也要设置成对应的trt的lib地址,虽然也可以混用,但最好别这么搞,会有隐藏的坑。

TensorRT的安装方式现在更多了,

tensorrt                 10.0.1
tensorrt-cu12            10.0.1
tensorrt-cu12-bindings   10.0.1
tensorrt-cu12-libs       10.0.1

不过通过这种方式安装只能使用python API,需要TensorRT C++ APIs,最好还是按照tar的方式安装。

注意点

  • A full installation of TensorRT including TensorRT plan file builder functionality. This mode is the same as the runtime provided prior to TensorRT 8.6.0.
  • A lean runtime installation. This installation is significantly smaller than the full installation and allows you to load and run engines that were built with a version compatible builder flag. This installation will not provide the functionality to build a TensorRT plan file.
  • A dispatch runtime installation. This installation allows for deployments with the minimum memory consumption and allows you to load and run engines that were built with a version compatible builder flag and include the lean runtime. This installation will not provide the functionality to build a TensorRT plan file.

onnx parser 解析器

TensorRT 10.0 includes tooling in the ONNX parser to identify unsupported nodes when the call to parse fails. This error reporting contains node name, node type, reason for failure, and the local function stack if the node is located in an ONNX local function. You can query the number of these errors with the getNbErrors function, and get information about individual errors using the getError function

此外,TensorRT 10.0的ONNX解析器也进行了升级,新增了工具来帮助开发者在调用失败时快速识别出不受支持的节点。这些错误报告会详尽地提供节点名称、类型、失败原因,甚至包括本地函数堆栈(如果节点位于ONNX本地函数中)。通过parsegetNbErrorsgetError 等函数,开发者可以轻松查询和处理这些错误信息。

Debug Tensors

In addition, Debug Tensors is a newly added API to mark tensors as debug tensors at build time. This makes it easier to identify any issues that arise in the graph. At runtime, each time the value of the tensor is written, a user-defined callback function is invoked with the value, type, and dimensions.

INT4量化

TensorRT 10.0现在支持使用INT4进行权重压缩,这一特性与硬件架构无关,具有广泛的适用性。当内存带宽成为GEMM操作性能的瓶颈,或者GPU内存资源紧张时,WoQ技术能够发挥巨大作用。在WoQ中,GEMM的权重被量化为INT4精度,而GEMM的输入数据和计算操作则保持在高精度状态。TensorRT的WoQ内核会从内存中读取4位权重,并在进行高精度点积计算之前对其进行去量化处理。

此外,块量化技术使得量化尺度中能够实现更高的粒度设置。它将张量沿单个维度划分为固定大小的块,并为每个块定义一个比例因子。这样,块中的所有元素都可以共享一个公共的比例因子,进一步提升了量化的灵活性和准确性。

运行时内存分配

  • ONNX解析器在解析调用失败时返回所有可静态确定为不支持的节点的列表。错误报告包括节点名称、节点类型、失败原因以及节点所在ONNX本地函数的本地函数栈。可以使用getNbErrors()函数查询这些错误的数量,并从getError()函数获取有关单个错误的信息。

  • Debug Tensors:添加了在构建时将张量标记为调试张量的API。在运行时,每次写入张量的值时,都会调用用户定义的回调函数,并提供值、类型和维度。

  • Runtime Allocation:createExecutionContext现在接受一个指定执行上下文设备内存分配策略(kSTATIC、kON_PROFILE_CHANGE和kUSER_MANAGED)的参数。对于用户管理的分配,添加了一个新的API updateDeviceMemorySizeForShapes,用于基于实际输入形状查询所需的大小。

  • 添加了一个新的Python示例sample_weight_stripping,展示了如何从ONNX模型构建和重新拟合去除权重的引擎(building and refitting weight-stripped engines from ONNX models.)

  • 新的REFIT_IDENTICAL标志指示TensorRT构建器在优化时假定引擎将使用与构建时提供的权重相同的权重进行重新拟合。使用此标志与kSTRIP_PLAN结合可在部署场景中最小化计划大小,例如,在计划旁边发送ONNX模型中包含权重的情况下。

  • Weight Streaming:添加了新的kWEIGHT_STREAMING标志和运行时的一组新的流式传输预算API,以允许您在设备上运行比设备内存更大的strongly typed model。例如,具有32 GB权重的强类型模型可以在具有不到32 GB VRAM的设备上运行。

  • tensorrt Debian和RPM元包现在安装TensorRT Python绑定包python3-libnvinfer、python3-libnvinfer-lean和python3-libnvinfer-dispatch。以前,还需要安装python3-libnvinfer-dev(el)包以支持C++和Python。

  • V3 plugin:现在提供了一代新的TensorRT自定义层,其中插件实现IPluginV3,并且应该配有实现IPluginCreatorV3One的插件创建器。IPluginV3的新功能包括数据依赖的输出形状、形状张量输入、自定义策略和时间缓存。

  • 插件注册表已添加键值存储,允许注册和查找用户定义的资源。

  • 新的kTACTIC_SHARED_MEMORY标志允许控制TensorRT后端CUDA内核使用的共享内存预算。在共享GPU的场景中,这很有用,因为TensorRT必须与其他应用程序共享GPU。默认情况下,该值设置为设备最大显存。

推理 enquere V3

Modifying or releasing memory that has been registered for the tensors before stream
synchronization or the event passed to setInputConsumedEvent has been being triggered results in undefined behavior

在流同步或传递给 setInputConsumedEvent 的事件被触发之前,修改或释放已为张量注册的内存会导致不确定的行为。

这是否意味着,在我进行数据预处理,准备好用于推理之后,我需要在调用 enqueueV3 之前调用 cudaStreamSynchronize?我预计不需要同步,因为所有的预处理和推理操作都是在同一个 cudaStream_t 上异步完成的,但我只是想确认我的理解是否正确,如果在这种情况下没有同步,是否会有不确定的行为。

附言:我知道在推理后,我需要在将数据移动到主机并获取结果之前,使用 cudaStreamSynchronize

关于 enqueueV3 是否需要在调用前进行流同步?答案是,如果你从预处理到推理使用的是同一个流,则不需要。

注意点

cuDNN is now an optional dependency for TensorRT and is only used to speed-up a small number of layers

cuBLAS is now an optional dependency for TensorRT and is only used to speed-up a small number of layers. I

参考