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 频繁切换导致重新构建执行上下文。
常见故障与判断依据
把验证结果与故障现象对应起来,可以显著缩短排查时间。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 版本不匹配。
.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 告警 |
完成上述检查后,环境即具备进入模型转换与引擎构建的条件。后续所有性能与精度问题,都应先回到这条版本链与验证路径上确认基线是否干净,再讨论优化手段。