2. TensorRT环境搭建与工具链

TensorRT 推理部署的第一道门槛不是写代码,而是把版本关系理顺。TensorRT 本身并不直接操作 GPU 硬件,它依赖 CUDA 运行时与驱动,卷积、归一化等算子的高性能实现又依赖 cuDNN,而 trtexec、Polygraphy、Nsight Systems 这些工具则分别绑定到特定版本的 TensorRT 与 CUDA。四者版本错配时,典型表现是 libcudnn.so 找不到、undefined symbol、引擎反序列化失败,或者 trtexec 能跑但 Python API 报错。因此本节按“先定版本、再装组件、后验工具链”的顺序展开。

版本匹配:先确定一条可用的版本链

版本匹配的核心是三条约束同时成立:驱动版本 ≥ CUDA 所需最低驱动;TensorRT 版本声明支持的 CUDA 版本;cuDNN 版本与 CUDA 版本对应。以 NVIDIA 官方发布矩阵中一组常见组合为例(示例,非实测):CUDA 12.2 + cuDNN 8.9.7 + TensorRT 10.0 + 驱动 535 系列。若把 TensorRT 换成 8.6,则它只支持到 CUDA 12.0,强行配 CUDA 12.2 会在加载 libnvinfer.so 时报符号缺失。

实际选型时建议反向确定:先看目标 GPU 架构(如 Ampere、Hopper)与部署环境是否锁定驱动,再由驱动上限反推 CUDA,最后查 TensorRT 支持矩阵选 TensorRT 与 cuDNN。可用以下命令确认当前环境基线:

nvidia-smi                      # 查看驱动版本与最高支持的 CUDA 版本
nvcc --version                  # 查看已安装 CUDA 编译器版本
cat /usr/local/cuda/version.json
dpkg -l | grep -E "cuda|cudnn|tensorrt"   # Ubuntu 下查看已装包版本

注意 nvidia-smi 显示的 “CUDA Version” 是驱动最高可支持的运行时版本,不等于已安装的 CUDA Toolkit 版本,两者混淆是新手最常见的误判来源。

安装顺序与关键路径

推荐顺序为:驱动 → CUDA Toolkit → cuDNN → TensorRT。CUDA 安装后需确认 /usr/local/cuda 软链接指向目标版本,并把 bin 与 lib64 加入环境变量:

export CUDA_HOME=/usr/local/cuda
export PATH=$CUDA_HOME/bin:$PATH
export LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATH

cuDNN 在 Linux 上通常是把头文件与库文件复制进 CUDA 目录,或使用 libcudnn8 的 deb 包。TensorRT 推荐用 tar 包解压后设置 LD_LIBRARY_PATH,或通过 pip 安装 tensorrt 与 tensorrt-lean。Python 侧还需保证 pycuda 或 cuda-python 与 CUDA 版本一致,否则 import tensorrt 阶段就会失败。

若使用容器部署,优先选择 nvcr.io/nvidia/tensorrt:xx.xx-py3 镜像,其内部 CUDA、cuDNN、TensorRT 已按官方矩阵配好,可跳过大部分版本排查工作。

工具链验证:trtexec、Polygraphy、Nsight Systems

安装完成后必须逐项验证,而不是等到模型转换失败才回头排查。三个工具职责不同:trtexec 负责引擎构建与性能基准,Polygraphy 负责精度与中间结果比对,Nsight Systems 负责时间线上的性能归因。

trtexec 验证可分三步。第一步确认可执行:trtexec --help。第二步用 ONNX 构建引擎并查看层信息:

trtexec --onnx=model.onnx \
        --saveEngine=model.plan \
        --fp16 \
        --minShapes=input:1x3x224x224 \
        --optShapes=input:8x3x224x224 \
        --maxShapes=input:32x3x224x224 \
        --verbose 2>&1 | tee build.log

第三步用 --loadEngine=model.plan --iterations=200 --warmUp=500 做吞吐与延迟基准,关注输出中的 Throughput、GPU Compute Time 与 Latency 分位数。若构建阶段出现 Unsupported operator,说明该算子需插件或回退,应在 Polygraphy 中进一步定位。

Polygraphy 的典型用法是比对 ONNX 与 TensorRT 引擎的输出差异,判断精度损失是否可接受:

polygraphy run model.onnx \
  --trt --onnxrt \
  --atol 1e-3 --rtol 1e-3 \
  --save-outputs outputs.json

它会逐输出给出最大绝对误差与相对误差,并标出首个不匹配的层。若误差集中在某一层,可结合 polygraphy inspect model 查看该层精度设置。

Nsight Systems 用于回答“时间花在哪里”。采集命令为 nsys profile -o trt_profile trtexec --loadEngine=model.plan --iterations=100,随后用 nsys stats 或 GUI 打开 .nsys-rep。重点观察 H2D/D2H 拷贝、kernel 执行、同步等待三段占比:若拷贝占比过高,说明输入输出未做 pinned memory 或 batch 组织不合理;若 kernel 间空隙大,可能是 shape 频繁切换导致重新构建执行上下文。

TensorRT 工具链版本依赖与验证路径 版本依赖链(自下而上约束) GPU 驱动 535 系列(示例) CUDA Toolkit 12.2 cuDNN 8.9.7 TensorRT 10.0 Python 绑定 tensorrt / cuda-python 约束方向:驱动 ≥ CUDA 最低要求;TensorRT 声明支持的 CUDA 决定上限;cuDNN 必须与 CUDA 对应 工具链验证分工 trtexec • ONNX → plan 构建 • 动态 shape 配置 • 吞吐 / 延迟基准 • 层信息与告警 Polygraphy • ONNX vs TRT 输出比对 • atol / rtol 判定 • 定位首个偏差层 • inspect model 结构 Nsight Systems • nsys profile 采集 • H2D / D2H 拷贝占比 • kernel 执行与空隙 • 同步等待归因 验证顺序与失败定位 环境变量 import 测试 trtexec 构建 Polygraphy 比对 nsys 性能归因 LD_LIBRARY_PATH 符号缺失 → 版本错配 算子不支持 → 插件/回退 误差超限 → 精度设置 拷贝/空隙 → 数据通路 示例版本组合仅用于说明匹配关系,实际以 NVIDIA 官方支持矩阵为准

常见故障与判断依据

把验证结果与故障现象对应起来,可以显著缩短排查时间。ImportError: libcudnn.so.8: cannot open shared object file 说明 cuDNN 未安装或 LD_LIBRARY_PATH 未包含其路径;undefined symbol: _ZN...cudnn... 说明 cuDNN 版本低于 TensorRT 要求;Serialization assertion 或引擎加载失败通常意味着构建引擎与运行引擎的 TensorRT 版本不一致,引擎不具备跨版本兼容性;trtexec 构建成功但 Python 报 pycuda 错误,则是 Python 绑定与 CUDA 版本不匹配。

TensorRT 引擎与构建时的 TensorRT 版本、GPU 架构强绑定。跨机器部署时必须在目标机器上重新构建,或确保目标机器具备相同架构与兼容的 TensorRT 运行时,不能直接把 .plan 文件当作通用产物拷贝。

可直接使用的环境自检清单

以下清单可作为部署前的固定检查项,逐条确认后再进入模型转换阶段:

检查项命令 / 方法通过标准
驱动与 GPU 可见nvidia-smi列出目标 GPU,驱动版本满足 CUDA 要求
CUDA 编译器nvcc --version版本与 TensorRT 支持矩阵一致
cuDNN 库ldconfig -p | grep cudnn存在对应版本 libcudnn.so
TensorRT 运行时python -c "import tensorrt; print(tensorrt.__version__)"正常打印版本号
trtexec 可用trtexec --help输出帮助信息无报错
Polygraphy 可用polygraphy --version正常打印版本
Nsight Systems 可用nsys --version正常打印版本
最小构建验证trtexec 构建一个小 ONNX生成 .plan 且无 unsupported 告警

完成上述检查后,环境即具备进入模型转换与引擎构建的条件。后续所有性能与精度问题,都应先回到这条版本链与验证路径上确认基线是否干净,再讨论优化手段。