ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

使用 Polygraphy 处理 TensorRT 低精度推理(TF32/FP16/INT8):精度验证、问题定位与精度约束覆盖指南

使用 Polygraphy 处理 TensorRT 低精度推理(TF32/FP16/INT8):精度验证、问题定位与精度约束覆盖指南 使用 Polygraphy 处理 TensorRT 低精度推理TF32/FP16/INT8精度验证、问题定位与精度约束覆盖指南【免费下载链接】TensorRTNVIDIA® TensorRT™ is an SDK for high-performance deep learning inference on NVIDIA GPUs. This repository contains the open source components of TensorRT.项目地址: https://gitcode.com/GitHub_Trending/tens/TensorRT导读本文基于 TensorRT 开源仓库内 Polygraphy 工具的实战指南 work_with_reduced_precision.md系统讲解如何在 TensorRT 中启用 TF32 / FP16 / INT8 等低精度优化并使用 Polygraphy 验证引擎精度是否满足要求。全文将围绕模型能否跑低精度 → 精度不达标时如何定位问题层 → 如何通过精度约束让关键层回退 FP32 → 仍不达标时的模型级优化手段这一完整排障链路展开并深入对应示例与源码帮助读者掌握一条可直接复制的低精度推理精度调试方法论。一、背景TensorRT 为什么能直接跑低精度TensorRT 的核心价值之一是能让用 FP32 训练出来的模型在几乎不做额外工程工作的情况下以TF32、FP16 等低精度实现运行并获得可观的推理加速。在 NvInfer.h 定义的构建配置中开发者可以通过BuilderFlag::kTF32、BuilderFlag::kFP16、BuilderFlag::kINT8等开关启用对应精度Polygraphy 的--tf32、--fp16、--int8参数正是对这套配置的 CLI 封装。但有一条重要前提必须明确FP16/TF32 与 INT8 的复杂度截然不同。TF32 与 FP16TensorRT 可以自动选择层实现通常无需额外步骤直接收益INT8一般不能直接启用需要额外进行校准calibration等步骤才能达到可接受的精度详见 NVIDIA TensorRT 开发者指南中的 Working With INT8 章节以及 Polygraphy 的 INT8 校准示例。因此能否直接跑低精度这个问题的标准答案是TF32 / FP16 通常可以开箱即用INT8 需要校准流程介入。二、第一步用 Polygraphy 对比验证引擎精度启用低精度之后的第一件事就是确认生成的引擎输出是否满足精度要求。Polygraphy 提供了最直接的验证手段用run子工具把 TensorRT 引擎与 ONNX-Runtime 放在一起跑直接比较两者输出。完整的操作指南见 01_comparing_frameworks 示例。2.1 最小对比命令以示例自带的dynamic_identity.onnx一个带动态输入形状的模型为例polygraphy run dynamic_identity.onnx --trt --onnxrt该命令会自动生成合成输入数据 → 分别用 TensorRT 与 ONNX-Runtime 执行推理 → 比较两者的输出。由于模型带动态维度Polygraphy 默认会把动态维度覆盖为constants.DEFAULT_SHAPE_VALUE即1并给出警告建议显式用--input-shapes指定输入形状让对比更可控polygraphy run dynamic_identity.onnx --trt --onnxrt \ --input-shapes X:[1,2,4,4]2.2 启用低精度参与对比要验证低精度 TensorRT 引擎的精度只需在命令中追加精度标志polygraphy run dynamic_identity.onnx --trt --fp16 --onnxrt \ --input-shapes X:[1,2,4,4]即TensorRT 侧以 FP16 优化构建引擎ONNX-Runtime 侧保持 FP32 作为黄金参考两者输出进行对比。--tf32、--int8同理。注意INT8 要达到可接受精度通常需要额外的校准步骤参见 01_int8_calibration_in_tensorrt 示例 中如何用 Polygraphy CLI 完成校准。2.3 调整容差与比较指标低精度对比的关键默认容差是为 FP32 精度设计的在低精度对比中往往过严。因此需要配合--atol绝对容差与--rtol相对容差放宽限制。此外还可以通过--check-error-stat更换比较指标可选值包括指标含义elemwise默认逐元素比较只要存在某个索引同时超出 atol 与 rtol 即失败mean比较张量平均绝对/相对误差median比较张量中位绝对/相对误差max比较张量最大绝对/相对误差Polygraphy 的比较逻辑以两个输出out0、out1为例先计算absdiff out0 - out1与reldiff absdiff / abs(out1)再对每个索引i检查absdiff[i] atol and reldiff[i] rtol任一索引同时满足即判定失败。这比max指标更宽松——当索引i触发 absdiff 超限、索引j触发 reldiff 超限但两者不是同一索引时max比较会失败而elemwise可能通过。综合示例——以 FP16 引擎与 ONNX-Runtime 对比采用 median 指标、atol/rtol 均为0.001polygraphy run dynamic_identity.onnx --trt --fp16 --onnxrt \ --input-shapes X:[1,2,4,4] \ --atol 0.001 --rtol 0.001 --check-error-stat median提示--atol、--rtol、--check-error-stat均支持按输出分别指定详见run子工具的帮助输出。2.4 逐层对比定位误差从哪一层引入当网络输出整体不匹配时更有价值的做法是逐层对比中间张量观察误差在何处被放大。这需要--trt-outputs与--onnx-outputs两个选项它们接受一个或多个张量名特殊值mark all表示对比模型中的所有张量polygraphy run dynamic_identity.onnx --trt --onnxrt \ --trt-outputs mark all \ --onnx-outputs mark all配合--fail-fast选项可以在输出出现首个不匹配时立即退出方便快速锁定第一个出错的层。注意--trt-outputs mark all有时会因时序、层融合选择、格式约束差异而扰动生成的引擎反而掩盖故障。此时需要更精细的手段二分定位失败模型并生成能复现错误的最小化测试用例参见 Reducing Failing ONNX Models。三、第二步FP16 失败时的外部对照自检如果使用--trt --fp16后精度不可接受一个关键问题是这是 TensorRT 特有的问题还是模型本身在低精度下就难以工作Polygraphy 给出的自检思路是用 ONNX-Runtime 把同一模型以 FP16 跑一遍。若 ONNX-Runtime 的 FP16 推理同样失败说明问题大概率出在模型自身对低精度的适应性上此时需要调整模型结构或添加精度约束而不是继续调试 TensorRT 构建选项。对应的操作指南是 04_converting_models_to_fp16 示例核心步骤如下。3.1 将 ONNX 模型转换为 FP16polygraphy convert --fp-to-fp16 -o identity_fp16.onnx identity.onnx可选检查转换后的模型polygraphy inspect model identity_fp16.onnx3.2 分别在 ONNX-Runtime 下运行 FP32 与 FP16 模型并对比先跑 FP32 模型保存输入与输出作为黄金参考polygraphy run --onnxrt identity.onnx \ --save-inputs inputs.json --save-outputs outputs_fp32.json再跑 FP16 模型复用同样的输入并与 FP32 输出对比polygraphy run --onnxrt identity_fp16.onnx \ --load-inputs inputs.json --load-outputs outputs_fp32.json \ --atol 0.001 --rtol 0.0013.3 检查 FP16 模型中间输出是否出现 NaN / InfFP16 常见故障模式是中间激活溢出产生 NaN 或无穷大。使用--onnx-outputs mark all配合--validate校验所有中间张量polygraphy run --onnxrt identity_fp16.onnx --onnx-outputs mark all --validate如果 FP16 模型在 ONNX-Runtime 下就无法通过那么下一步就应转向调整模型或按下文添加精度约束让关键计算回到 FP32。四、第三步定位精度故障的问题层确认精度问题后通用的下一步是把导致精度失败的层隔离出来。这属于 TensorRT 精度排障的通用方法论Polygraphy 单独整理了一份指南debug_accuracy.md其中包含如何系统地缩小范围定位对精度影响最大的层结合run子工具的逐层输出对比上文 2.4 节与 Reducing Failing ONNX Models 的模型精简技巧通过--trt-outputs等选项在 TensorRT 侧标记中间张量作为输出观测各层实际误差。定位到问题层之后就进入本文的核心章节对这些层施加精度约束让它们回退到 FP32。五、第四步覆盖精度约束——让问题层回退 FP32一旦识别出问题层就可以用 Polygraphy 实验性地把这些层约束为 FP32验证精度是否恢复。完整可运行的示例见 08_adding_precision_constraints 示例其中附带了一个专门构造的needs_constraints.onnx模型其网络结构为x - MatMul (I_rot90) - Add (FP16_MAX) - Sub (FP16_MAX) - MatMul (I_rot90) - out即水平翻转输入 → 加上FP16_MAX再减去FP16_MAX→ 再水平翻转。当x为正时第二步的中间值必然超出 FP16 可表示范围这是设计好的因此该子图必须用 FP32 计算。但 TensorRT 不知道x的取值范围GEMM步骤 1、3在 FP16 下更快逐点运算步骤 2在 FP16 下更快且避免 FP32↔FP16 重排格式所以不施加约束时 TensorRT 通常会让整条链路都跑 FP16从而产生精度失败。Polygraphy 提供了三种施加精度约束的方式。5.1 方式一--layer-precisions命令行选项直接为指定层设置精度本示例要求 TensorRT 8.4 及以上polygraphy run needs_constraints.onnx \ --trt --fp16 --onnxrt --val-range x:[1,2] \ --layer-precisions Add:float16 Sub:float32 --precision-constraints prefer \ --check-error-stat median该命令刻意强制Add层跑 FP16、Sub层跑 FP32从而阻止两者被融合让Add的输出溢出 FP16 范围——这样对比更容易按预期失败方便理解约束的语义。实际排障时应把需要恢复精度的层指定为float32例如--layer-precisions Add:float32 Sub:float32。5.2 方式二网络后处理脚本--trt-network-postprocess-script在已解析的 TensorRT 网络上程序化地修改层精度。仓库提供的 add_constraints.py 演示了完整写法import tensorrt as trt def postprocess(network): for layer in network: # 将 Add 和 Sub 层的计算精度设为 FP32 if layer.name in (Add, Sub): layer.precision trt.float32 # 将 Add 层的输出精度设为 FP32。 # 若不设置即使计算本身是 FP32中间输出仍可能以 FP16 存储。 if layer.name Add: layer.set_output_type(0, trt.float32)对应命令polygraphy run needs_constraints.onnx --onnxrt --trt --fp16 --precision-constraints obey \ --val-range x:[1,2] --check-error-stat median \ --trt-network-postprocess-script ./add_constraints.py要点--trt-npps是--trt-network-postprocess-script的简写Polygraphy 默认执行脚本中的postprocess函数若要用其他函数用冒号后缀指定如--trt-npps my_script.py:custom_func。5.3 方式三网络加载脚本完全手动构建网络第三种方式最彻底用 TensorRT Python API 手动构建整个网络在构建过程中直接设置层精度。前提是先了解 04_defining_a_tensorrt_network_or_config_manually 示例 的网络脚本模板。首先用 ONNX-Runtime 生成参考输入与黄金输出polygraphy run needs_constraints.onnx --onnxrt --val-range x:[1,2] \ --save-inputs inputs.json --save-outputs golden_outputs.json然后运行仓库提供的 constrained_network.py。该脚本先用NetworkFromOnnxPath(./needs_constraints.onnx)解析模型再通过func.extend(...)扩展加载流程遍历网络把Add、Sub层及其输出类型约束为 FP32与 add_constraints.py 逻辑一致并强制 TensorRT 遵守约束polygraphy run constrained_network.py --precision-constraints obey \ --trt --fp16 --load-inputs inputs.json --load-outputs golden_outputs.json \ --check-error-stat median注意除了显式约束的层TensorRT 仍可能出于整体性能考虑让网络中其他层以 FP32 运行——这是允许的只要精度满足要求即可。可选当 TensorRT 没有满足精度约束的层实现时允许其忽略约束以保证网络可运行polygraphy run constrained_network.py --precision-constraints prefer \ --trt --fp16 --load-inputs inputs.json --load-outputs golden_outputs.json \ --check-error-stat median5.4 关于obey与prefer两个约束模式两个命令中的--precision-constraints参数是理解整套机制的关键obey遵守TensorRT 必须严格按照约束选择层实现约束是硬性要求prefer偏好TensorRT 优先尝试满足约束但在没有对应实现或影响构建时可以选择性地忽略。从 NvInfer.h 中BuilderFlag与层精度相关的 API 可以看出这一语义对应 TensorRT 网络构建阶段对层精度layer.precision与输出类型layer.set_output_type的处理策略前者是严格过滤后者是优化偏好。日常排障建议先用obey验证约束后精度能否恢复若构建失败再退到prefer。六、其他手段当 FP32 回退不够用时如果把问题层回退到 FP32仍不足以恢复精度或者导致不可接受的性能回退那么问题往往已经超出推理侧配置的范畴需要回到训练侧修改模型帮助中间激活的动态范围保持在可表达的界限内。原文档给出三条实用技术路线训练时归一化输入值例如把 RGB 输入数据缩放到[0, 1]训练与推理使用同一套归一化可显著收窄激活的动态范围使用 Batch Normalization 与正则化技术帮助稳定训练过程中的激活分布间接提升低精度推理的数值稳定性INT8 场景使用量化感知训练QAT若目标精度是 INT8可考虑在训练阶段引入量化感知训练这是业界公认提升 INT8 推理精度的主流手段。需要说明的是这些建议属于模型训练侧的通用最佳实践Polygraphy 仓库内同样提供了配套的量化工具链见 pytorch-quantization 与 tensorflow-quantization 子项目可作为 QAT 落地的参考实现。七、完整排障流程小结把以上步骤串起来就是一条完整的低精度推理精度排障链路启用低精度--trt --fp16 / --tf32 │ ▼ ① 与 ONNX-Runtime 对比--trt --onnxrt注意放宽 --atol/--rtol、选择 --check-error-stat │ 失败 ▼ ② FP16 外部对照自检polygraphy convert --fp-to-fp16 onnxrt 运行 NaN/Inf 校验 │ 确认是 TensorRT 侧问题 ▼ ③ 定位问题层--trt-outputs/--onnx-outputs mark all、--fail-fast、模型精简 │ ▼ ④ 覆盖精度约束--layer-precisions / 网络后处理脚本 / 网络加载脚本obey 或 prefer │ 仍不达标 ▼ ⑤ 训练侧优化输入归一化、BN/正则化、QAT每一步都有对应的 Polygraphy 命令与仓库示例可验证框架对比见 01_comparing_frameworksFP16 转换见 04_converting_models_to_fp16精度约束见 08_adding_precision_constraints精度调试总纲见 debug_accuracy.md。延伸阅读How to Debug Accuracy精度调试总指南故障层隔离的完整方法论Comparing Across Runs对比预构建引擎或网络脚本与 ONNX-Runtime 的场景Dynamic Shapes in TensorRT为引擎指定优化 profile 的 CLI 用法Comparing with Custom Input Data用真实数据替代合成输入Checking for Intermediate NaN or Infinities中间张量数值合法性校验Reducing Failing ONNX Models失败模型的最小化复现。【免费下载链接】TensorRTNVIDIA® TensorRT™ is an SDK for high-performance deep learning inference on NVIDIA GPUs. This repository contains the open source components of TensorRT.项目地址: https://gitcode.com/GitHub_Trending/tens/TensorRT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表