全局性能调优器是 NVIDIA TensorRT 11.1 中发布的一项自动性能调优功能。它通过为不同的模型自定义不同的优化,在 TensorRT 中提供自动、准确性感知的端到端性能调优。有关更多详细信息,请参阅本系列的第 1 部分,其中介绍了与调度 (深度学习编译器优化的关键阶段) 相关的挑战、在 TensorRT 中开发全局性能调优器功能的动机,以及为形式化问题而建立的数学理论。
本文第 2 部分使用第 1 部分中的符号来描述全局性能调优器功能的算法和架构设计。它还提供了使用它的最佳实践。
在 TensorRT 中设计全局性能调优器功能
全局性能调优器的核心设计理念是将替代调度策略表示为明确且可搜索的构建路线。编译器旋钮 (也称为编译器标志或编译器选项) 是一种配置设置,用于更改编译流程的某些方面,例如启发式、融合决策或代码生成路径。
每个可调整的旋钮都会显示一组有限的允许值,并具有一个默认值。构建路线是旋钮值的具体组合。未指定构建路由时,TensorRT 使用默认构建路由,其中每个旋钮都保留其默认值。
假设编译器包含三个通道:\(f_1\)、\(f_2\) 和 \(f_3\)。假设二进制旋钮 \(p\) 控制 \(f_2\) 使用的融合策略:当 \(p=1\) 时,通道应用水平融合;当 \(p=0\) 时,则应用垂直融合:
\(f_2(s) = \begin{cases} f’_2(s), & \text{if } p = 1 \\ f”_2(s), & \text{if } p = 0 \end{cases}\)
\(p\) 的两个可能值定义了两条构建路线,因此为输入模型 \(m\) 生成大小为 2 的候选解集:
\(B(m) = \{f_3(f’_2(f_1(m))),\, f_3(f”_2(f_1(m)))\}\)
这两种聚变策略都没有改善。水平融合可能会为一个模型生成更快的引擎,而垂直融合则可能对另一个模型更有效。即使模型本身保持不变,其结果也可能会因张量形状和目标 GPU 而发生变化。因此,选择更好的路线需要同时构建候选引擎并比较其端到端性能。
甚至这个双路由示例也捕捉到了调优的基本理念:编译器提供有意义的调度替代方案,而测量的行为可确定哪种完整的解决方案最适合当前的部署案例。
在前面介绍的数学框架中,构建路由是编译器通道的合成。在实现中,旋钮分配的组合提供了该路线的紧凑规范。更改一个或多个旋钮值可改变模型在编译流程中可调整部分的传输方式。在此抽象中,一个旋钮组合可被视为标识构建路线。
更确切地说,旋钮组合是构建路线规范,而不是对最终引擎的完整描述。TensorRT 仍会执行引擎构建的其余阶段 (包括战术选择) ,并且可能会调整单个旋钮值与网络施加的限制。路由指定了可调整配置空间中请求的选择。它不会取代 TensorRT 构建器的其他部分。
TensorRT 提供了一个紧凑的 API 表面,其具有两项基本功能:
- 应用并检查一条构建路线:setter 对构建器配置应用固定路线,而相应的 getter 则返回当前指定的路线。
- 探索可调整配置空间:一个单独的 getter 描述了可用的旋钮、其允许值、默认值及其用途。
相应的 C++ API 包括:
bool IBuilderConfig::setBuildRoute(char const* buildRoute);
char const* IBuilderConfig::getBuildRoute() const;
char const* IBuilderConfig::getAllBuildRoutes() const;
您可以使用这些 API 来实现自定义调优器。trtexec 中还提供了示例 C++ 实现。
trtexec 会按以下方式对调优进行整体组织:
- 当用户指定输入模型和类似正则表达式的可调整构建路由表达式时,
trtexec将根据搜索算法将该表达式扩展为具体构建路由的列表。 - 系统会循环遍历所有固定的构建路线。在每次迭代中,模型将使用该单一构建路径构建,然后在每次迭代中衡量准确性和性能。
- 所有在构建过程中崩溃或在推理过程中出现错误准确性的构建路线都排除在最佳引擎选择之外。选择端到端性能最佳的引擎。
TensorRT 11.1 提供了 200 多个用于调整的旋钮。如需了解更多详情,请参阅全局性能调优器文档。同样的 Python 实现也将在 Torch-TensorRT 2.15 中发布。
在端到端测量中,探索多条构建路线的实用价值显而易见。图 1 比较了默认 TensorRT 构建路由 (针对每个工作负载将标准化为 1.0 倍) 与在调优过程中找到的最佳合格路由。在这 10 个经过评估的工作负载中,调优可实现从 1.14 倍到 1.63 倍的性能提升。

工作负载之间的差异是结果的核心。不同的模型具有不同的优化机会,因此不能期望单一的默认调度策略来实现每个模型的最佳性能。Global Performance Tuner (全局性能调优器) 会探索其他组装路线,拒绝不符合准确性要求的候选引擎,并选择在目标环境中测得的符合要求的最快引擎。
案例研究:性能准确性纠缠
全局性能调优器功能应用了准确性感知调优,因此理论上可以完美解决性能准确性纠结问题。思考以下思维实验。
对于图 2 所示的简单神经网络模型,可以设想有一些控制是否强制某些 IR 使用低精度内核的旋钮,这相当于通过在运算之间插入 Q/ DQ 节点将图形转换为量化图形。TensorRT 11.0 及更高版本不支持此功能,因为弱类型 API 已弃用。
此模型有四个位置可插入 Q/ DQ。假设它们由四个不同的二进制旋钮控制。然后,深度学习编译器可以在解空间中提供 24 = 16 的解。显而易见,在这 16 个候选解决方案中,性能最佳的解决方案是插入所有量化的解决方案。但是,此解决方案可能无法满足准确性要求。无 Q/ DQ 的解决方案将具有最佳准确性,但性能最差。性能和准确性错综复杂,很难知道“中间”的哪种解决方案同时满足这两种要求。
回想一下,构建器算法的概念包含精度容差。区分准确性和性能的关键在于定义清晰的准确性接受边界,并且边界需要由用户提供的准确性指标和数据集作为黄金值提供支持。
TensorRT 中的全局性能调优器功能的精度容差值也为 \(ε\)。请考虑以下三种情况:
- \(ε = 0\):根据本思维实验假设的精确匹配指标,候选输出必须与参考输出位相同。如果每个较低精度的替换至少改变一个评估输出,则只有一个无较低精度替换的解仍符合资格。
- \(ε = +\infty\):准确性要求没有施加有效的限制,因此所有 16 个候选解决方案仍然符合资格。更一般地说,假设理论解空间接受一个“空”解,该解没有执行任何有用的计算,因此运行时为零。仅受性能引导的优化器可以选择这种毫无意义的解决方案。这种有限的用例说明了为什么仅凭性能还不足以实现优化目标。
- \(ε\) 逐渐从 \(+\infty\) 变为 0:随着准确性要求变得更加严格,符合条件的候选者会设置合约,例如,从 16 个解决方案变为 14 个,然后是 13、8、7,最后是 1 个。这些计数可说明问题;实际过渡点取决于模型、参考数据和选定的准确性指标。对于 \(ε\) 的每个值,选择算法都会在符合资格的已评估候选解中选择最快的测量解。
全局性能调优器并没有消除基本的权衡。相反,它将性能和准确性在优化过程中的作用区分开来:
- 准确性决定了哪些候选解决方案是可接受的
- 性能对可接受的候选解决方案进行排名
作为一名开发者,您需要定义适合您的应用程序的精度边界,而调整则要确定该边界内评估后性能最佳的构建路线。结果是系统的约束优化过程,而不是在速度和准确性之间临时选择。
此思考实验独立于任何 TensorRT 版本所公开的特定编译器旋钮。其目的是展示更广泛的设计原则,即当调度选择表示为可调整的构建路线,而准确性被视为显式约束时,性能准确性优化变得可衡量、可复制和应用定义。
使用全局性能调优器的最佳实践
全局性能调优器使建造路线探索变得系统化,但有效的调优仍然受益于深思熟虑的搜索策略。当一个表达式包含许多变量旋钮时,可能的组合数量会迅速增加。以下实践有助于保持调优可控、可重现并与目标应用保持一致。
根据搜索空间选择搜索策略
将默认构建路线视为比较替代路线的基准。对于广泛的初始扫描,fast 搜索会评估默认路线,并一次更改一个旋钮。mixed 搜索通常是更大表达式的实际起点:它首先执行 fast 扫描,然后探索产生改进的旋钮值的组合。将 full 保留为一组精心挑选的小旋钮进行搜索,因为该旋钮会评估其完整的 Cartes 乘积。
在开始 fast 或 full 扫描之前,--dryRun 可以显示具体的路线列表,而无需构建引擎。这提供了一种在投入完整调优运行之前检查搜索空间的快速方法。mixed search 不支持 --dryRun,因为第二阶段取决于在第一阶段收集的测量结果。
将调优视为一个渐进且可恢复的过程
指定 --tuningCacheFile 后,系统会记录每次完成的迭代及其构建路径、测量的 GPU 时间和准确度结果。如果扫描中断或达到时间限制,稍后可以使用 --continue 从记录的状态恢复。借助这种方法,可以将调优作为渐进式实验进行,而无需要求每次搜索都在一次不间断的运行中完成。
当特定于路线的故障或准确性回归需要更深入的调查时,--saveAllEngines 可以保留每次迭代产生的引擎。由于此选项会消耗大量存储空间,因此最适合用于调试而非例行调优。
根据应用调整调整工作流程
所提供的输入和参考输出应代表对应用程序至关重要的部署条件。满足对一个窄数据集的准确性要求的引擎仅需根据该数据集、指标和值进行验证。包括代表性输入、重要的边界用例以及反映应用程序实际质量要求的准确性指标。
trtexec 实现提供了即用型调优器,但这并不是唯一可行的调优策略。builder-configuration API 展示了可用的旋钮并支持应用单独的构建路线,而开源 trtexec 实现演示了如何组织周围的调优循环。在比较候选性能之前,开发者可以构建特定于应用的搜索策略,引入启发式过滤器,或应用应用级准确性验证。
将之前的结果视为指导,而非普遍可迁移的解决方案
最佳构建路径特定于搜索期间使用的模型、输入形状、目标 GPU、软件堆栈以及 TensorRT 和调优器版本。改进一种部署的途径可能没有效果,也可能导致另一种部署的回归。更改模型、形状、目标硬件、CUDA 或驱动环境或相关 TensorRT 版本后,重新调整。
从之前的调优实验中获得的知识仍然很有价值。如果某些旋钮不断改进相关系列的工作负载,这种体验可以指导未来的搜索空间设计,并帮助优先考虑有前景的候选项。这种启发式方法应作为重点探索的先验方法,而每条最终路线都在其实际部署环境中得到验证和衡量。
开始使用 TensorRT 中的全局性能调优器功能
全局性能调优器功能将 TensorRT 性能优化从依赖一种通用调度策略转变为评估特定模型的替代方案。可定制的构建路线允许不同的模型和部署环境探索不同的调度决策,从而解决性能定制问题。
将候选内容生成与路线搜索分离,提供了摆脱启发式扩展的可扩展路径,减少了将每个模型特定发现编码为另一个硬编码例外的需求。准确性感知型调优还能解决性能与准确性之间的纠结。准确性决定了哪些候选引擎是可接受的,而端到端性能则决定了哪种可接受的引擎是可接受的。因此,在针对目标模型和环境评估的构建路线中,所选结果是最快的测量合格引擎。
TensorRT 提供出色的基础方案,编译器旋钮提供受控变体,而调优为每个客户确定可接受的最佳变体。这种从通用预测到模型特定的转变证明了全局性能调优器功能如何将 TensorRT 优化扩展到单一构建路径之外。
首先,请查看全局性能调优器文档和开源 trtexec 实现。使用您自己的准确性验证算法、搜索策略或优先考虑有前景的构建路线的启发式算法扩展样本。为获得更好的控制,请使用 TensorRT 构建路由 API 从头开始构建调优器,根据应用的准确性要求和性能目标定制候选项探索和验证。