TensorRT框架详解

1. TensorRT 是什么? TensorRT 是 NVIDIA 推出的深度学习推理加速 SDK,主要用于把已经训练好的模型转换成适合 NVIDIA GPU 高速执行的推理引擎。它不是用来训练模型的,而是用来部署模型、加速推理、降低延迟、提高吞吐量的。NVIDIA 官方文档也明确说,TensorRT 用于优化和加…

作者:作家

1. TensorRT 是什么?

TensorRT 是 NVIDIA 推出的深度学习推理加速 SDK,主要用于把已经训练好的模型转换成适合 NVIDIA GPU 高速执行的推理引擎。它不是用来训练模型的,而是用来部署模型、加速推理、降低延迟、提高吞吐量的。NVIDIA 官方文档也明确说,TensorRT 用于优化和加速 PyTorch、TensorFlow、ONNX 等框架训练出来的模型,并支持 FP32、FP16、BF16、FP8、INT8、动态 shape、Transformer/LLM 优化等能力。

你可以把它理解成:

PyTorch / TensorFlow 负责训练模型;
ONNX 负责作为中间模型格式;
TensorRT 负责把模型编译成更快的 GPU 推理引擎;
Triton / FastAPI / C++ / Python 服务负责最终对外提供接口。


2. 为什么 TensorRT 会快?

TensorRT 的核心不是“换了个框架”,而是做了很多底层优化。

主要包括:

  1. 层融合

    比如 Conv + BN + ReLU 原本是三个计算步骤,TensorRT 可以把它们融合成一个更高效的 kernel。

  2. 精度优化

    可以从 FP32 降到 FP16、INT8、FP8 等。精度降低后,显存占用更小,计算速度更快。TensorRT 当前官方文档明确支持 FP32、FP16、BF16、FP8、INT8 等混合精度推理。

  3. 选择最优 kernel

    同一个卷积或矩阵乘法,不同 GPU 上最优执行方式不一样。TensorRT 会根据你的 GPU、输入 shape、精度,自动选择更快的执行策略。

  4. 动态 shape 优化

    比如图片可能是 640×640,也可能是 1280×720;文本长度也可能不同。TensorRT 可以为不同输入尺寸建立优化 profile。

  5. 减少运行时开销

    PyTorch 推理时仍有很多动态图和 Python 层开销,TensorRT 编译成 engine 后更接近底层 GPU 执行。


3. TensorRT 适合什么场景?

适合:

  • 图像分类
  • 目标检测,比如 YOLO
  • 图像分割
  • OCR
  • 语音模型
  • 推荐模型
  • Transformer 模型
  • LLM 推理,通常用 TensorRT-LLM,而不是普通 TensorRT

不太适合:

  • 还在频繁改模型结构的阶段
  • 需要训练或微调的阶段
  • 模型里有大量 TensorRT 不支持的特殊算子
  • CPU 部署场景
  • 你没有 NVIDIA GPU 的场景

4. TensorRT 和 TensorRT-LLM 的区别

这个一定要分清。

普通 TensorRT

主要用于:

  • CNN
  • YOLO
  • ResNet
  • UNet
  • OCR
  • 一般 ONNX 模型

典型路径:

PyTorch 模型
→ 导出 ONNX
→ TensorRT 构建 engine
→ Python/C++/Triton/FastAPI 调用

TensorRT-LLM

主要用于:

  • Qwen
  • Llama
  • DeepSeek
  • Mistral
  • Baichuan
  • ChatGLM
  • MoE 模型
  • 多 GPU LLM 推理

NVIDIA 官方 TensorRT-LLM 文档提供了 Quick Start、Docker 启动、trtllm-serve 在线服务、离线推理等流程。

典型路径:

Hugging Face LLM
→ TensorRT-LLM 转换权重
→ 构建 TensorRT-LLM engine
→ trtllm-serve / Triton / 自定义服务部署

如果你是部署课程推荐大模型、聊天模型、Qwen、Llama 这种,优先看 TensorRT-LLM。如果你是视频解析、YOLO 检测、分类、特征提取,优先看 普通 TensorRT


5. 从零到落地:普通模型 TensorRT 部署全流程

下面以 PyTorch 模型为例。


第一步:确认环境

你需要先确认:

nvidia-smi

看这几个信息:

GPU 型号
Driver Version
CUDA Version
显存大小

然后确认:

python --version
pip --version

推荐生产环境:

Linux + NVIDIA GPU + CUDA + cuDNN + TensorRT + Docker

Windows 也能做部分实验,但真正部署更建议 Linux。因为很多 TensorRT、Triton、TensorRT-LLM 生态默认以 Linux/Docker 为主。


第二步:安装 TensorRT

NVIDIA 官方安装文档提供了多种安装方式,并提醒需要先确认系统满足 prerequisites。

比较推荐两种方式。

方式一:Docker

这是最稳的方式。

docker run --gpus all -it --rm nvcr.io/nvidia/tensorrt:latest

优点:

CUDA、cuDNN、TensorRT 版本更容易匹配
少踩环境坑
适合部署

方式二:pip 安装

pip install tensorrt

但这种方式容易遇到 CUDA、驱动、Python 版本不匹配问题。学习阶段可以试,生产更建议 Docker。


第三步:训练模型

比如你有一个 PyTorch 模型:

model = MyModel()
model.load_state_dict(torch.load("model.pth"))
model.eval()

TensorRT 不负责训练,所以你要先把模型训练好。


第四步:导出 ONNX

示例:

import torch

dummy_input = torch.randn(1, 3, 640, 640).cuda()

torch.onnx.export(
model,
dummy_input,
"model.onnx",
input_names=["input"],
output_names=["output"],
opset_version=17,
dynamic_axes={
"input": {0: "batch"},
"output": {0: "batch"}
}
)

这里有几个关键点:

opset_version 不要乱选
input_names / output_names 后面部署会用到
dynamic_axes 决定是否支持动态 batch 或动态尺寸

第五步:检查 ONNX 是否正常

python -m pip install onnx onnxruntime

然后:

import onnx

model = onnx.load("model.onnx")
onnx.checker.check_model(model)
print("ONNX model is valid")

还可以用 ONNX Runtime 跑一次,确认输出没问题。


第六步:用 trtexec 测试能否构建 TensorRT engine

trtexec 是 TensorRT 常用命令行工具,ONNX-TensorRT 官方文档也说明,用户可以用 trtexec --onnx=model.onnx 快速检查 ONNX 是否能解析并构建 TensorRT engine。

基础命令:

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

如果要 FP16:

trtexec \
--onnx=model.onnx \
--saveEngine=model_fp16.engine \
--fp16

如果是动态 shape:

trtexec \
--onnx=model.onnx \
--saveEngine=model_dynamic.engine \
--minShapes=input:1x3x320x320 \
--optShapes=input:4x3x640x640 \
--maxShapes=input:8x3x1280x1280 \
--fp16

这里的含义是:

minShapes:最小输入尺寸
optShapes:最常见输入尺寸
maxShapes:最大输入尺寸

TensorRT 会重点优化 optShapes


第七步:对比精度

不要只看速度,一定要对比:

PyTorch 输出
ONNX 输出
TensorRT 输出

尤其是检测模型,要对比:

bbox 是否偏移
置信度是否接近
类别是否一致
NMS 结果是否一致

FP16 一般问题不大,但 INT8 可能明显影响精度,需要校准数据。


第八步:Python 调用 TensorRT engine

实际部署时,可以用 Python 加载 engine,然后接到 FastAPI。

大概结构是:

import tensorrt as trt
import pycuda.driver as cuda
import pycuda.autoinit

TRT_LOGGER = trt.Logger(trt.Logger.INFO)

def load_engine(engine_path):
with open(engine_path, "rb") as f:
runtime = trt.Runtime(TRT_LOGGER)
engine = runtime.deserialize_cuda_engine(f.read())
return engine

完整工程里还需要:

分配 GPU 输入输出内存
创建 execution context
把 numpy 输入拷贝到 GPU
执行 inference
把输出拷贝回 CPU
做后处理

如果你不想自己写这些底层代码,可以用:

ONNX Runtime TensorRT Execution Provider
Triton Inference Server
Ultralytics YOLO export engine
TensorRT Python API 封装库

ONNX Runtime 的 TensorRT Execution Provider 可以调用 TensorRT 引擎来加速 ONNX 模型推理。


第九步:封装成接口

例如 FastAPI:

from fastapi import FastAPI, UploadFile, File

app = FastAPI()

@app.post("/predict")
async def predict(file: UploadFile = File(...)):
image_bytes = await file.read()

# 1. 解码图片
# 2. resize / normalize
# 3. TensorRT 推理
# 4. 后处理
# 5. 返回 JSON

return {
"status": "success",
"result": []
}

接口返回可以设计成:

{
"task_id": "xxx",
"status": "done",
"result": {
"labels": [],
"boxes": [],
"scores": []
}
}

如果处理视频,建议异步:

POST /tasks/upload
GET /tasks/{task_id}
GET /tasks/{task_id}/files
GET /tasks/{task_id}/download

你前面做视频解析接口时,其实就可以把 TensorRT 模型放到 Celery worker 里面执行。


6. 从零到落地:LLM 用 TensorRT-LLM 的流程

如果你是部署 Qwen、Llama、DeepSeek 这种,不建议走普通 ONNX → TensorRT 的路线,而是走 TensorRT-LLM。

NVIDIA TensorRT-LLM 官方文档提供了安装、Docker、Quick Start、trtllm-serve 在线服务、离线推理等内容。

基本流程是:

准备模型
→ 准备 Docker 环境
→ 转换权重
→ 构建 engine
→ 启动服务
→ 调接口测试
→ 压测
→ 上线

第一步:准备模型

例如:

Qwen2.5-7B-Instruct
Llama-3.1-8B-Instruct
DeepSeek-R1-Distill-Qwen

确认:

模型架构是否被 TensorRT-LLM 支持
tokenizer 是否完整
config.json 是否正常
权重格式是否标准

第二步:启动 TensorRT-LLM Docker

示意:

docker run --gpus all -it --rm \
--ipc=host \
--ulimit memlock=-1 \
--ulimit stack=67108864 \
-v /mnt/models:/models \
nvcr.io/nvidia/tensorrt-llm/release:latest

第三步:构建 LLM engine

不同版本命令会变化,所以要以当前 TensorRT-LLM 官方文档为准。典型逻辑是:

trtllm-build \
--model_dir /models/Qwen2.5-7B-Instruct \
--output_dir /models/qwen_trt_engine \
--max_batch_size 8 \
--max_input_len 4096 \
--max_seq_len 8192

参数含义:

max_batch_size:最大批量
max_input_len:最大输入长度
max_seq_len:最大总长度

这些参数会直接影响:

显存占用
最大上下文
并发能力
推理速度

第四步:启动服务

例如:

trtllm-serve /models/qwen_trt_engine

然后用 HTTP 请求测试。


第五步:压测

你要测:

首 token 延迟 TTFT
每秒输出 token 数 tokens/s
并发数
GPU 显存占用
请求失败率
长上下文稳定性

不要只测一个问题。要测:

短 prompt
长 prompt
单用户
多用户
长输出
高并发
异常输入

7. 最常见的坑和解决方法


坑 1:CUDA、驱动、TensorRT 版本不匹配

表现:

ImportError
libnvinfer.so not found
CUDA driver version is insufficient
engine 反序列化失败

解决:

nvidia-smi

先看驱动版本,再根据官方支持矩阵选择 TensorRT / CUDA / cuDNN。TensorRT 官方支持矩阵用于确认平台、GPU 和软件兼容性。

最稳做法:

直接用 NVIDIA 官方 Docker
不要自己手动拼 CUDA + TensorRT + cuDNN

坑 2:ONNX 导出失败

常见原因:

模型里有 Python 控制流
forward 里面有 list/dict 复杂操作
使用了 ONNX 不支持的算子
opset 版本不合适
输入 shape 不固定

解决:

先把模型 forward 简化
用 torch.onnx.export 导出
用 onnx.checker 检查
必要时换 opset_version

比如:

opset_version=17

不行就试:

opset_version=16
opset_version=18

坑 3:TensorRT 不支持某些 ONNX 算子

表现:

Unsupported operator
No importer registered for op
Could not parse ONNX

TensorRT 官方 operators 文档提供了 ONNX 算子支持列表,并指出如果有不支持的算子,可以通过 TensorRT plugin 扩展。

解决路径:

1. 换模型结构
2. 改 ONNX 导出方式
3. 用 onnx-simplifier 简化模型
4. 把不支持算子替换成支持算子
5. 自己写 TensorRT plugin
6. 改用 ONNX Runtime CUDA / TensorRT EP 混合执行

常用:

pip install onnxsim
python -m onnxsim model.onnx model_sim.onnx

坑 4:动态 shape 没设置好

表现:

输入 640 可以跑
输入 1280 报错
batch=1 可以跑
batch=4 报错

原因:

TensorRT engine 构建时没有声明动态 shape 范围。

解决:

trtexec \
--onnx=model.onnx \
--saveEngine=model.engine \
--minShapes=input:1x3x320x320 \
--optShapes=input:4x3x640x640 \
--maxShapes=input:8x3x1280x1280 \
--fp16

坑 5:FP16 速度没提升

可能原因:

GPU 不适合 FP16
模型太小,瓶颈在数据预处理
输入输出拷贝耗时太多
后处理耗时太多
batch 太小

解决:

用 trtexec 单独测 engine 性能
把预处理、后处理分开计时
尽量减少 CPU-GPU 拷贝
使用 batch 推理
视频任务可以多帧 batch

坑 6:INT8 精度下降明显

INT8 需要校准数据。校准数据不合理,就会导致模型输出质量下降。

解决:

准备有代表性的 calibration dataset
不要只拿几张图校准
对比 FP32 / FP16 / INT8 精度
检测任务要看 mAP,不要只看速度

简单建议:

第一次上线优先 FP16
稳定后再尝试 INT8

坑 7:engine 不能跨机器使用

TensorRT engine 和这些因素强相关:

TensorRT 版本
CUDA 版本
GPU 架构
构建参数

所以不要以为一个 .engine 文件可以随便复制到任何机器上跑。

解决:

在哪台机器/哪类 GPU 上部署,就在哪类环境里 build engine
生产镜像里固定 TensorRT 版本

坑 8:模型输出和 PyTorch 不一致

可能原因:

预处理不一致
NCHW / NHWC 搞反
RGB / BGR 搞反
normalize 参数不一致
FP16 数值误差
NMS 后处理不一致

解决:

逐层排查:

同一张输入图
PyTorch 输出
ONNX 输出
TensorRT 输出
逐个比较

尤其注意:

image = image[:, :, ::-1]  # BGR/RGB 转换
image = image / 255.0
image = image.transpose(2, 0, 1)

坑 9:视频任务里 GPU 很快,但整体还是慢

常见原因:

视频解码慢
逐帧读写慢
图片预处理慢
后处理慢
磁盘 IO 慢
接口阻塞

解决:

视频解码用 ffmpeg / GPU decode
多帧 batch 推理
推理和写文件分离
Celery 异步任务
结果文件分目录存储
数据库只存 metadata,不存大文件

比如:

uploads/
outputs/
task_id/
frames/
result.json
annotated.mp4

坑 10:LLM 用 TensorRT-LLM 时显存爆炸

常见原因:

max_seq_len 设置太大
max_batch_size 设置太大
KV Cache 占用太高
模型本身太大
没有量化
并发过高

解决:

降低 max_batch_size
降低 max_seq_len
使用 FP16 / BF16 / FP8 / INT8 / INT4 方案
限制最大输入长度
限制最大输出长度
使用多 GPU tensor parallel

例如:

7B 模型不要一开始就 max_seq_len=32768
先从 4096 或 8192 测起

8. 一个真正落地的项目结构

如果你做的是普通模型,比如视频分析、检测、分类,可以这样设计:

project/
app/
main.py # FastAPI 接口
inference/
engine.py # TensorRT engine 加载
preprocess.py # 预处理
postprocess.py # 后处理
tasks/
celery_app.py
video_tasks.py # 视频异步处理
database/
models.py
crud.py
config.py

models/
model.onnx
model_fp16.engine

data/
uploads/
outputs/

scripts/
export_onnx.py
build_engine.sh
benchmark.py

requirements.txt
Dockerfile
docker-compose.yml

9. 推荐落地路线

你不要一上来就搞 INT8、多 GPU、Triton、TensorRT-LLM。建议按这个顺序:

第一阶段:能跑

PyTorch 模型推理成功
导出 ONNX 成功
ONNX Runtime 推理成功

第二阶段:能加速

trtexec 构建 engine 成功
FP16 engine 推理成功
对比 PyTorch 输出

第三阶段:能服务化

FastAPI 接口调用 TensorRT
支持上传文件
返回推理结果

第四阶段:能处理任务

Celery 异步处理
任务状态查询
结果文件保存
支持多个任务排队

第五阶段:能上线

Docker 部署
日志记录
异常处理
GPU 显存监控
接口鉴权
结果清理机制

第六阶段:进一步优化

batch 推理
INT8 量化
Triton Inference Server
多 GPU
动态 batching

10. 最小可用命令流程

假设你已经有 model.onnx

检查 ONNX

python -m onnxsim model.onnx model_sim.onnx

构建 TensorRT engine

trtexec \
--onnx=model_sim.onnx \
--saveEngine=model_fp16.engine \
--fp16

动态 shape 构建

trtexec \
--onnx=model_sim.onnx \
--saveEngine=model_dynamic_fp16.engine \
--fp16 \
--minShapes=input:1x3x320x320 \
--optShapes=input:4x3x640x640 \
--maxShapes=input:8x3x1280x1280

Benchmark

trtexec \
--loadEngine=model_fp16.engine \
--warmUp=200 \
--duration=10

11. 什么时候不建议用 TensorRT?

这些情况下先别急着上 TensorRT:

模型还没稳定
接口还没写完
数据预处理还在改
业务逻辑还没定
GPU 资源不确定
模型推理本身不是瓶颈

比如你的系统如果慢在:

视频下载
视频解码
文件写入
数据库查询
队列等待

那先上 TensorRT 不一定有明显收益。

正确顺序是:

先定位瓶颈
再决定是否 TensorRT