☰
TensorRT 7.2.2在Ubuntu 18.04与CUDA 10.2下的安装部署与推理优化实践
2026/10/16 16:05:07 网站建设 项目流程

搞推理优化的同学应该都绕不过这个组合:TensorRT 7.2.2配上Ubuntu 18.04、CUDA 10.2、cuDNN 8.0.5。这个版本组合至今仍在不少存量生产环境里跑着,尤其是那些显卡驱动锁死在某一代、不方便整体升级的老机器。我也在这套环境上踩过不少坑,从下载源选错到动态库路径对不上,前前后后重装过四五次。这篇就把整个流程完整拆解一遍,从下载到安装,再到实际跑通一个模型,把该避开的雷都提前标出来。

这套环境搭配的适用人群很明确:一是做服务端推理部署的工程师,二是维护旧项目需要复现环境的同学,三是对TensorRT感兴趣但手头正好是这套老配置的研究者。无论你是用Python写推理脚本,还是用C++做高性能服务,这篇文章都能让你少走弯路。

1. 环境与版本匹配关系梳理

1.1 为什么选TensorRT 7.2.2而不是新版

TensorRT 7.2.2在2021年初发布,当时主打的特性是支持了更丰富的ONNX算子覆盖、改进了动态shape处理,以及对Ampere架构的优化。放到今天来看,它的定位很特殊:它是少数能同时兼容CUDA 10.2和较新cuDNN 8.x的版本。CUDA 10.2是Turing架构和部分老驱动下的常见配置,很多工业现场的机器都停留在这个版本上,因为驱动一换,整个CUDA生态都要跟着动,风险太大。

另外,TensorRT 7.2.2对Python 3.6到3.8的支持很稳定,这个Python版本区间也正好是很多老旧服务的依赖范围。所以在这个环境组合下,7.2.2不是"可用"而是"最合适"的选择。新版TensorRT虽然功能更强,但它对CUDA版本的要求往往更高,强行在CUDA 10.2上安装新版反而会因依赖不全而失败。

1.2 版本兼容性一览

在动手之前,先把兼容关系理清楚,这是整个安装过程顺利与否的前提。

组件版本要求说明
操作系统Ubuntu 18.04 x86_6416.04也可装但18.04更稳妥
CUDA10.2必须是10.2,其他小版本如10.2.89均可
cuDNN8.0.58.0.5与CUDA 10.2的搭配已验证
TensorRT7.2.2对应安装包名含"7.2.2"字样
GCC<= 89以上编译C++样例会报错
Python3.6 / 3.7 / 3.8对应不同wheel包名称

这里特别强调一下GCC版本。TensorRT 7.2.2的C++头文件和库是用较老的ABI编译的,如果你用Ubuntu 18.04自带的GCC 7.5基本没问题,但如果系统装了GCC 9以上再手动切过去,编译出来的程序链接TensorRT时很容易出现GLIBCXX版本不兼容的报错。这个细节经常被忽略,但实际踩中的人非常多。

还有一个容易混淆的点:cuDNN的版本号要精确匹配。TensorRT 7.2.2官方验证过的cuDNN版本是8.0.5,你换成8.2.x虽然也能跑,但偶尔会出现精度不一致或者内存越界这种"玄学"报错。所以能用官方搭配就千万别自行升级。

1.3 动手前检查这三样

下载安装之前,先把机器上的现状摸清楚。依次执行下面几条命令并记录输出:

# 检查显卡驱动和GPU型号 nvidia-smi # 检查CUDA版本 nvcc -V # 检查cuDNN版本 cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2

第一条命令看驱动版本和显存大小。TensorRT做推理的时候显存占用比训练小很多,但如果你要开FP16或者INT8模式,还是建议显存不低于4GB。第二条命令确认CUDA是10.2,小版本是10.2.89没关系,但如果是10.2.100之类的更新小版本,理论上兼容,实测也没问题。第三条命令确认cuDNN是8.0.5,如果没找到这个文件,说明cuDNN还没装,需要先去NVIDIA官网下载。

Python版本也要确认一下:

python3 -V

建议用系统自带的Python 3.6,或者自己装一个3.7/3.8的虚拟环境。TensorRT 7.2.2的Python wheel包是按Python小版本区分的,选错版本会直接报"No matching distribution"。

2. 下载环节的操作与坑点

2.1 下载入口和版本选择

TensorRT的下载入口一般通过NVIDIA官网进入,但官网页面布局经常变,最省事的是直接从NVIDIA的归档服务器下载。

在归档目录下,你需要认准带"7.2.2"和"Ubuntu 18.04"字样的安装包,文件名大致长这样:

TensorRT-7.2.2.3.Ubuntu-18.04.x86_64-gnu.cuda-10.2.cudnn8.0.5.tar.gz

注意文件名里的三处关键信息:7.2.2.3(版本号,最后一位是内部构建号)、cuda-10.2(CUDA版本)、cudnn8.0.5(cuDNN版本)。这三个字段必须同时出现在文件名里,缺一个都不对。

下载前先确认你用的是不是Ubuntu 18.04,有个常见的乌龙是:在CentOS机器上尝试装Ubuntu的tar包,解压后动态库一律无法加载,因为发行版的glibc版本和库的依赖关系不同。TensorRT没有提供CentOS的官方包,所以这种环境下一般就走容器方案了。

2.2 tar包、deb包和Python wheel包怎么选

TensorRT 7.2.2的安装包分三种形态,很多人第一次接触时不知道选哪个。

tar包是最通用的方式,解压后手动配置环境变量,适合所有场景,也好卸载(删目录即可)。deb包是Ubuntu系的安装方式,会自动把库文件放到系统目录并注册ldconfig,但卸载时要小心残留。Python wheel包只包含Python API和对应的动态库,适合只用Python开发、不碰C++的朋友。

我个人的建议是:如果你要写C++代码,用tar包;如果纯Python开发,优先在虚拟环境里装wheel包。两种方式可以混用,但混用带来的问题就是动态库路径容易乱,新手不建议一开始就搞混装。

2.3 下载后的完整性校验

下载完成后,别急着解压。先做个哈希校验,防止下载过程文件损坏:

md5sum TensorRT-7.2.2.3.Ubuntu-18.04.x86_64-gnu.cuda-10.2.cudnn8.0.5.tar.gz

把输出的MD5值和官网给出的参考值比对。官网一般不会直接显示MD5,但NVIDIA下载页面通常提供SHA256,所以更准确的做法是:

sha256sum TensorRT-7.2.2.3.Ubuntu-18.04.x86_64-gnu.cuda-10.2.cudnn8.0.5.tar.gz

校验文件的完整性这一步看似多余,但实际上我遇到过一次下载包损坏导致的Python导入时报"undefined symbol"错误,排查了很久才发现是tar包本身不完整。所以这个步骤别跳过。

3. 安装流程与配置细节

3.1 tar包安装

tar包的安装步骤很简单,但有几个细节必须处理好。

先把包解压到统一目录:

sudo mkdir -p /opt/nvidia sudo tar -xzf TensorRT-7.2.2.3.Ubuntu-18.04.x86_64-gnu.cuda-10.2.cudnn8.0.5.tar.gz -C /opt/nvidia

解压后目录结构是:

/opt/nvidia/TensorRT-7.2.2.3/ ├── bin/ ├── include/ ├── lib/ ├── python/ ├── samples/ ├── targets/ ├── doc/ └── uff/

然后配置环境变量,把这几行加进~/.bashrc或者你的环境配置文件:

export LD_LIBRARY_PATH=/opt/nvidia/TensorRT-7.2.2.3/lib:$LD_LIBRARY_PATH export PATH=/opt/nvidia/TensorRT-7.2.2.3/bin:$PATH

这里有个关键点:LD_LIBRARY_PATH必须设置,否则Python导入tensorrt时提示找不到.so文件。但如果你是通过systemd启动的服务进程,LD_LIBRARY_PATH传不进去,这种情况下建议用ldconfig注册路径:

echo "/opt/nvidia/TensorRT-7.2.2.3/lib" | sudo tee /etc/ld.so.conf.d/tensorrt.conf sudo ldconfig

用ldconfig的好处是全局生效,不需要每个shell都设置环境变量。但坏处是,如果你以后装了多个版本的TensorRT来回切换,ldconfig的注册路径会冲突。所以我的习惯是:开发调试用LD_LIBRARY_PATH,生产部署用ldconfig。

3.2 cuDNN 8.0.5的安装确认

tar包形式的TensorRT依赖系统已有的cuDNN,所以在安装TensorRT之前,确认cuDNN 8.0.5已正确安装。如果你之前是通过dpkg方式安装的cuDNN,一般位于/usr/include/x86_64-linux-gnu/和/usr/lib/x86_64-linux-gnu/。如果是手动解压的cuDNN tar包,通常在你指定的CUDA目录下。

排查方式很简单:

find /usr -name "cudnn_version.h" 2>/dev/null find /usr -name "libcudnn.so.8" 2>/dev/null

只要有libcudnn.so.8存在,并且能通过ldconfig -p | grep cudnn看到它,说明cuDNN基本就绪。另外一个检查方式是看TensorRT自带的检测脚本:

python3 /opt/nvidia/TensorRT-7.2.2.3/python/check.py

不过这个脚本需要装了Python wheel之后才能用,后面再说。

3.3 Python wheel包安装

如果你的工作流以Python为主,下一步就是装Python API的wheel包。tar包里自带的python目录下就有针对不同Python版本的wheel文件:

ls /opt/nvidia/TensorRT-7.2.2.3/python/

输出大致是:

tensorrt-7.2.2.3-cp36-none-linux_x86_64.whl tensorrt-7.2.2.3-cp37-none-linux_x86_64.whl tensorrt-7.2.2.3-cp38-none-linux_x86_64.whl

根据你当前Python版本选择对应cp36、cp37还是cp38。注意文件名里的none字段,这意味着这个wheel不依赖特定的Python ABI,理论上同一大版本下的Python小版本都能装。

然后创建虚拟环境并安装:

python3 -m venv trt_env source trt_env/bin/activate pip install /opt/nvidia/TensorRT-7.2.2.3/python/tensorrt-7.2.2.3-cp37-none-linux_x86_64.whl

注意:强烈建议在虚拟环境里用pip安装,不要用系统的pip直接装。因为系统的pip往往会关联到不同的Python版本,如果系统默认Python是3.6而你装了cp37的wheel,导入时会直接报"module 'tensorrt' has no attribute 'Runtime'"之类的错。

3.4 C++样例验证编译

如果你做C++开发,建议把samples目录里的样例编译一遍,既能验证环境完备性,也能给后续开发打底。samples的编译用的还是老一套的CMake方式:

cd /opt/nvidia/TensorRT-7.2.2.3/samples mkdir build && cd build cmake .. make -j$(nproc)

这里可能会遇到一个问题:CMake版本太老导致找不到CUDA。Ubuntu 18.04系统自带的CMake是3.10.2,对CUDA 10.2的探测有些老,最好是装CMake 3.13以上版本。如果编译报错找不到CUDA,可以先:

sudo apt update sudo apt install cmake

看看能不能升级到更高版本。如果apt里版本还是旧版,可以手动装一个CMake 3.16的源码包,这个版本对CUDA 10.2的支持很完善。

编译完成后,build/bin目录下会多出可执行的样例程序。找一个跑一下:

./build/bin/sample_mnist -d /opt/nvidia/TensorRT-7.2.2.3/samples/data/mnist

如果输出中包含"Accurate"或者"PASSED"字样,说明整条链路已经通了一半。这一步跑通之后,TensorRT的安装环节才算真正结束。

4. 实际使用:把模型跑起来

4.1 用trtexec快速测试

安装完成后,第一个要认识的工具是trtexec。它在tar包的bin目录下,是TensorRT自带的命令行工具,作用是把ONNX模型转成TensorRT引擎,或者直接对已有引擎做性能测试。

先试一个最简单的ONNX模型转换:

trtexec --onnx=model.onnx --saveEngine=model.engine

这里注意几个参数的含义:

  • --onnx=xxx:指定输入的ONNX文件。
  • --saveEngine=xxx:保存生成的engine文件。
  • --fp16:开启FP16精度。
  • --int8:开启INT8,但需要指定校准数据集。
  • --minShape/minShapes/optShape/maxShape:设置动态shape范围。

如果模型输入是固定尺寸,直接跑上面这条命令即可。但大部分实际模型都是动态尺寸,例如输入维度包含可变batch大小,那么转换时就要指定动态shape:

trtexec --onnx=model.onnx \ --minShapes=input:1x3x224x224 \ --optShapes=input:8x3x224x224 \ --maxShapes=input:16x3x224x224 \ --saveEngine=model.engine

执行过程会输出每一层的构建日志。如果报错说某个ONNX算子不支持,说明这个版本的TensorRT还没覆盖该算子,需要把对应的层用Plugin实现或者修改模型结构。TensorRT 7.2.2的算子覆盖相比老版本已经好了很多,但遇到LayerNorm、GELU等Transformer结构里的常用算子时,还是有可能要写Plugin。这个问题放在后面的排查章节详细说。

生成engine之后,可以直接用trtexec做性能测试:

trtexec --loadEngine=model.engine --shapes=input:1x3x224x224

输出的关键指标是Throughput和GPU Compute Time,通过它们能判断模型在GPU上的实际推理耗时。这个方法在对比不同batch、不同精度下的性能差异时尤其好用。

4.2 Python API的完整推理流程

trtexec适合快速验证和测性能,但工程上要用Python做推理服务时,就得写代码了。下面给出一个完整的Python示例,将ONNX模型转换为engine并执行推理。

import tensorrt as trt import numpy as np import pycuda.autoinit import pycuda.driver as cuda TRT_LOGGER = trt.Logger(trt.Logger.WARNING) def build_engine(onnx_path, engine_path): builder = trt.Builder(TRT_LOGGER) network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) parser = trt.OnnxParser(network, TRT_LOGGER) with open(onnx_path, 'rb') as model: if not parser.parse(model.read()): for i in range(parser.num_errors): print(parser.get_error(i)) return None config = builder.create_builder_config() config.max_workspace_size = 1 << 30 # 1GB # 动态shape设置 profile = builder.create_optimization_profile() profile.set_shape("input", (1, 3, 224, 224), (4, 3, 224, 224), (8, 3, 224, 224)) config.add_optimization_profile(profile) engine = builder.build_engine(network, config) if engine is not None: with open(engine_path, 'wb') as f: f.write(engine.serialize()) return engine def inference(engine_path, input_data, input_name="input", output_name="output"): engine = None with open(engine_path, 'rb') as f: runtime = trt.Runtime(TRT_LOGGER) engine = runtime.deserialize_cuda_engine(f.read()) # 绑定输入输出缓冲区 h_input = input_data.astype(np.float32).ravel() h_output = np.empty(engine.get_binding_shape(output_name).volume(), dtype=np.float32) d_input = cuda.mem_alloc(h_input.nbytes) d_output = cuda.mem_alloc(h_output.nbytes) context = engine.create_execution_context() # 如果是动态shape,需要设置实际的输入尺寸 context.set_binding_shape(engine.get_binding_index(input_name), input_data.shape) cuda.memcpy_htod(d_input, h_input) context.execute_v2([int(d_input), int(d_output)]) cuda.memcpy_dtoh(h_output, d_output) return h_output

提示:这个例子依赖pycuda,需要先pip安装:pip install pycuda。另外还要确认CUDA 10.2对应的pycuda版本,直接用最新版即可。

这段代码里的两个关键点:

第一,EXPLICIT_BATCH标志。TensorRT 7.2.2开始推荐使用显式batch模式,所有动态shape都通过Profile来定义。如果你用老的implicit batch模式,即使network里写了动态维度,转换时也会报错。

第二,max_workspace_size不能设太大也不能太小。太小了会导致某些算子无法融合,性能折损严重;太大了在显存有限的设备上可能报显存不足。我通常设置为显存大小的1/4到1/3。

4.3 动态shape的坑以及FP16/INT8使用建议

动态shape是TensorRT使用中最容易踩坑的部分。要点在于:你在Profile里设定的三个shape必须覆盖所有实际运行时会遇到的输入尺寸,而且最优shape要偏向你的主流实际尺寸。

比如你的服务典型场景是batch=4,那么optShapes就设置成4,这样TensorRT在做算子融合时能针对性优化。如果你的服务偶尔来一个batch=16的请求,而你没有设定maxShapes=16,推理时会直接报"out of memory"或者"shape out of range"。

FP16是TensorRT加速效果最明显的一个模式,很多模型的FP16推理速度是FP32的两倍甚至更多。开启方式很简单,在builder config里加一行:

config.set_flag(trt.BuilderFlag.FP16)

但对某些精度敏感的模型,比如目标检测里的小目标回归头,FP16可能带来精度损失。建议开启后验证一遍精度的可接受程度,再决定是否上线。

INT8模式更复杂一些,需要准备校准数据集。TensorRT 7.2.2的INT8校准默认使用继承自TensorRT 7.1的直觉校准算法,你只需要提供一个校准数据生成器。具体代码在官方sample里有,但要注意校准数据的代表性——如果校准数据跟线上数据分布差异太大,INT8之后的精度可能会严重下降。

我实测过,在同样的Batch=8下,FP16比FP32能提升大约1.8倍,INT8比FP32能提升大约3倍。但INT8的调试成本远高于FP16,所以建议新手从FP16开始,稳定跑通之后再考虑INT8。

4.4 使用C++ API的注意事项

Python API做原型验证很方便,但生产环境追求更低延迟时,C++ API往往是首选。C++方面,建议阅读官方samples里的sampleOnnxMNIST和sampleDynamicReshape。它们展示了:

  • 如何从ONNX构建engine:流程跟Python类似,但错误处理要繁琐一些。
  • 如何做动态shape:核心是设置IOptimizationProfile并在执行时调用setBindingDimensions。
  • 如何管理GPU显存:用cudaMalloc/cudaMemcpy方式做输入输出拷贝。

C++开发中最常见的坑是:忘记在每次推理前设置输入维度。即使engine本身是动态的,context还是会记住上一次推理的形状,如果不重新设置,输出尺寸就是上一次的,结果会牛头不对马嘴。

另外,C++多线程环境下,每个线程要创建独立的ExecutionContext,不能共用同一个context,否则会出现不确定的数据竞争。

5. 常见问题与排查技巧

5.1 动态库加载失败

现象:Python执行import tensorrt时报错:

ImportError: libnvinfer.so.7: cannot open shared object file: No such file or directory

原因基本就是LD_LIBRARY_PATH没设置好。按前面说的方式配置完之后,可以用这个命令快速确认:

ldd /path/to/tensorrt/python/tensorrt/tensorrt.so | grep "not found"

如果输出里有libnvinfer.so.7的"not found",说明路径没生效。检查一下/opt/nvidia/TensorRT-7.2.2.3/lib目录下是否有libnvinfer.so.7,如果没有,说明包解压不完整,重新下载解压。

另一种情况是:明明设置了LD_LIBRARY_PATH,但启动Python的进程不是从shell启动的(比如从systemd启动的Jupyter服务),这时候环境变量没传进去。解决方法是把这个目录写进/etc/ld.so.conf.d/tensorrt.conf然后执行ldconfig。

5.2 Python版本不匹配

现象:装完对应wheel后,import tensorrt依然报错,或者虽然导入成功但API缺少某些属性。

排查步骤:

pip show tensorrt python3 -c "import tensorrt; print(tensorrt.__version__)"

如果pip show能看到包但导入报错,多半是装了错误的Python大版本wheel。另一个线索是,如果导入时出现AttributeError: module 'tensorrt' has no attribute 'Builder',一般是因为装了低版本的TensorRT,或者是不同Python版本之间路径冲突。

5.3 ONNX算子不支持

现象:trtexec转换ONNX时报类似信息:

[E] [ONNX] ModelImporter.cpp:... Assertion failed: ... Unsupported ONNX operator ...

TensorRT 7.2.2支持了大多数常见算子,但部分新模型里的算子还是没有内置支持。处理手段有三种:

  • 方法一:修改模型结构,把不支持的部分用等价算子替代。比如把LayerNormalization拆成多个基础算子。这种方式最简单,但改起来费时。
  • 方法二:自定义Plugin。TensorRT支持写C++插件来扩展算子,需要继承IPluginV2系列接口,封装成动态库,加载到engine里。这个方案性能最好但工作量最大。
  • 方法三:用ONNX simplifier工具先对图做简化。安装onnxsim后先优化一遍模型,有时能消除一部分不支持的模式。

比较推荐的排查顺序是:先做onnxsim图优化,再考虑改模型,最后才是写Plugin。

5.4 显存不足与性能调优

显存不足方面,除了降低BatchSize或关掉INT8,还有一个容易忽略的点:记得在builder config里调整max_workspace_size。如果这个值设得过大,构建engine时会直接OOM;不是运行时OOM,而是构建时OOM,因为TensorRT为了找最优实现会把所有候选kernel的workspace都预留出来。

性能调优方面,几个实测下来有效的建议:

  • 用--verbose参数看每一层的耗时:定位瓶颈层是哪个算子,重点优化它。
  • 尝试调整optShapes:让优化shape尽量贴近实际推理shape,性能可能立刻提升10%以上。
  • 检查数据预处理开销:很多场景下,预处理(resize、normalize)占据了总耗时的一半以上。考虑把预处理合入TensorRT的输入层,或者用DALI做硬件加速预处理。

5.5 常见问题速查表

问题现象可能原因解决方式
libnvinfer.so.7: cannot open shared object fileLD_LIBRARY_PATH未生效配置环境变量或ldconfig
No module named 'tensorrt'wheel包未安装或Python版本不对按Python大版本选择wheel并安装
ONNX解析失败ONNX算子不支持或图结构异常先用onnxsim简化图再转换
动态shape推理时报错输入shape超出Profile范围检查min/max shape设置
构建engine时显存溢出max_workspace_size过大降低数值或使用更低精度
转换后精度明显下降使用了INT8但没有做校准准备代表性校准数据集重新校准
CUDA初始化失败运行环境没有GPU权限检查nvidia-smi和使用用户权限
多线程推理结果错乱多个线程共享了同一ExecutionContext每个线程独立创建Context

6. 工程落地的一些经验

6.1 从"能跑"到"能上线"的完整链路

很多人安装TensorRT只是为了在本机验证一个模型,但真正要部署成服务时,还要考虑一些额外的环节。以我自己参与过的某跨平台系统推理服务为例,当时整套流程是这样的:

  • 训练好的模型导出为ONNX。
  • 用trtexec或Python API将ONNX转成TensorRT engine。
  • 将engine文件打包到镜像或服务目录,加载时反序列化。
  • 启动推理服务,接收请求并返回推理结果。
  • 压测调优,必要时重新构建engine。

有几个经验值得一说:

第一,engine是跟GPU架构绑定的。在Turing架构上构建的engine不能直接在Ampere上跑,反过来也一样。所以打包部署时一定要确认目标机器的GPU架构,或者直接在目标机器上现场构建。这也是为什么很多部署流程会选择在容器启动时做一次engine构建,而不是提前预制engine。

第二,engine文件里的kernel是编译出来的机器码,反序列化时不会做二次优化,因此构建engine的机器应该跟运行机器有相同的算力配置。举个例子,你在开发机上用A100构建的engine,放到T4上加载时会报错或性能崩坏。

第三,版本锁定的重要性。TensorRT 7.2.2的engine序列化格式在7.2.x内部是一致的,但如果升级到7.3,旧engine不一定能加载。我建议把TensorRT版本写进部署配置,避免团队协作时其他人误升版本。

6.2 环境隔离与多版本共存

做深度学习基础设施的人经常需要同时维护多个版本。TensorRT 7.2.2和更新版本可以在同一台机器上共存,只要目录分开,环境变量按需切换。我的习惯是:

  • 不同版本的TensorRT放在/opt/nvidia/tensorrt_7.2.2和/opt/nvidia/tensorrt_8.x这样的目录下。
  • 用环境变量或Docker镜像隔离,而不是全局设置ldconfig。
  • 每种TensorRT版本配套一个专用的Python虚拟环境。

在Docker场景下,比较推荐的方式是把TensorRT安装命令写进Dockerfile,每次构建镜像时现场安装。这样既能保证版本一致,也避免了宿主机环境的污染。

6.3 性能调优的心得总结

跑通之后,下一步就是让模型跑得更快。TensorRT调优的核心思路是:给TensorRT最大的自由度,让它自己做选择。

具体来说,多做这几件事:

  • 把输入数据的NCHW/NHWC选择权留给TensorRT。有人习惯在预处理阶段就把数据转成NHWC,但TensorRT对NCHW和NHWC的支持在不同算子间表现不同,提前转格式反而限制了它的优化空间。
  • 允许TensorRT重新排列网络层序。默认配置下TensorRT会做层融合和重排,如果担心精度问题刻意关闭某些优化,性能会大打折扣。建议先全开,再验证精度。
  • 多测几次不同的optShapes。固定shape的模型没得选,但动态shape模型在设定不同优化shape时的性能差异可能达到20%以上。

我还遇到过一种情况:模型输入是一个特别小的图,比如288x288,TensorRT反而因为过度优化导致构图时间很长,而推理时间并没有下降多少。这时候需要在BuilderConfig里降低算法选择的速度,直接用set_tactic_sources限制一部分可选tactic,构建速度会明显改善。

6.4 扩展建议

TensorRT 7.2.2虽然已经有些年头,但它的使用价值依然很高。如果你手头的环境也是这套老配置,有几个方向可以继续深入:

  • 将TensorRT引擎集成到推理服务框架,支持RESTful或gRPC接口,实现模型热更新。
  • 用TensorRT自带的NMS插件做目标检测后处理,省去在CPU上跑后处理的开销。
  • 尝试把多个小模型拼成一个engine做多任务推理,减少dispatch开销。
  • 利用TensorRT 7.2.2的sparsity特性,如果你有Ampere架构GPU,可以进一步压缩模型。

这三个方向里,集成推理服务框架是最实际的一个,很多做模型部署的人最终都会走到这一步。核心思路是用一个C++或Python的常驻进程加载engine,接收请求时只做反序列化和推理,不重复构建engine,这样可以把单次推理延迟稳定控制在毫秒级。

我自己在这套环境上跑了快一年,从最初连trtexec怎么用都不知道,到后来能熟练处理动态shape、写Plugin、调INT8,中间踩过的坑确实不少。好在TensorRT的生态足够成熟,遇到的问题大多有解法。希望这篇能把后来者心里"装不上、跑不通、跑不快"这三个坎都填上。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询