4. NVIDIA TensorRT加速座舱视觉模型推理

任务说明

在座舱AI场景中,驾驶员监控(DMS)与乘客状态识别等视觉模型需要满足实时性要求。本案例将完成一个最小可复现的TensorRT加速闭环:将PyTorch预训练的ResNet-18分类模型转换为ONNX,再通过TensorRT构建FP16精度的推理引擎,最终对比TensorRT与PyTorch的推理延迟,验证加速效果。

环境依赖

  • Ubuntu 20.04+ / JetPack 5.0+(车规级Orin平台)
  • TensorRT 8.5+(含trtexec命令行工具)
  • PyTorch 2.0+(仅用于导出ONNX与基准对比)
  • CUDA 11.8+、cuDNN 8.6+
  • Python 3.8+,需安装pycuda、onnx、onnxruntime(可选)

实现步骤

整体流程分为三步:导出ONNX → 构建TensorRT引擎 → 执行推理并验证。以下代码在一个Python脚本中完成全部闭环,输入为随机生成的模拟座舱图像张量(3×224×224),输出为分类置信度向量。

关键完整代码

import torch
import torchvision.models as models
import numpy as np
import tensorrt as trt
import pycuda.driver as cuda
import pycuda.autoinit
import time

# ---------- 1. 导出ONNX ----------
model = models.resnet18(pretrained=False)
model.eval()
dummy_input = torch.randn(1, 3, 224, 224)
onnx_path = "cabin_model.onnx"
torch.onnx.export(model, dummy_input, onnx_path,
                  input_names=["input"], output_names=["output"],
                  dynamic_axes={"input": {0: "batch"}, "output": {0: "batch"}},
                  opset_version=17)
print("ONNX导出完成")

# ---------- 2. 构建TensorRT FP16引擎 ----------
TRT_LOGGER = trt.Logger(trt.Logger.WARNING)
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 f:
    if not parser.parse(f.read()):
        for i in range(parser.num_errors):
            print(parser.get_error(i))
        raise RuntimeError("ONNX解析失败")

config = builder.create_builder_config()
config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30)  # 1GB
config.set_flag(trt.BuilderFlag.FP16)

engine_path = "cabin_model_fp16.engine"
serialized_engine = builder.build_serialized_network(network, config)
with open(engine_path, "wb") as f:
    f.write(serialized_engine)
print("TensorRT引擎构建完成")

# ---------- 3. 加载引擎并推理 ----------
runtime = trt.Runtime(TRT_LOGGER)
engine = runtime.deserialize_cuda_engine(serialized_engine)
context = engine.create_execution_context()

# 分配显存
input_shape = (1, 3, 224, 224)
output_shape = (1, 1000)
input_size = trt.volume(input_shape) * np.float32().itemsize
output_size = trt.volume(output_shape) * np.float32().itemsize
d_input = cuda.mem_alloc(input_size)
d_output = cuda.mem_alloc(output_size)

# 模拟座舱输入图像(随机噪声)
input_data = np.random.randn(*input_shape).astype(np.float32)
output_data = np.empty(output_shape, dtype=np.float32)

# 绑定TensorRT上下文
context.set_input_shape("input", input_shape)
bindings = [d_input, d_output]

# 预热
cuda.memcpy_htod(d_input, input_data)
context.execute_v2(bindings)
cuda.memcpy_dtoh(output_data, d_output)
cuda.Context.synchronize()

# 正式推理计时(100次取平均)
n_iter = 100
start = time.time()
for _ in range(n_iter):
    cuda.memcpy_htod(d_input, input_data)
    context.execute_v2(bindings)
    cuda.memcpy_dtoh(output_data, d_output)
cuda.Context.synchronize()
trt_time = (time.time() - start) / n_iter * 1000  # ms

# ---------- 4. PyTorch CPU/GPU基准对比 ----------
device = "cuda" if torch.cuda.is_available() else "cpu"
model.to(device)
torch_input = torch.from_numpy(input_data).to(device)

# 预热
with torch.no_grad():
    for _ in range(10):
        _ = model(torch_input)

# 计时
start = time.time()
with torch.no_grad():
    for _ in range(n_iter):
        _ = model(torch_input)
torch.cuda.synchronize() if device == "cuda" else None
torch_time = (time.time() - start) / n_iter * 1000

print(f"TensorRT FP16 平均延迟: {trt_time:.2f} ms")
print(f"PyTorch ({device}) 平均延迟: {torch_time:.2f} ms")
print(f"加速比: {torch_time / trt_time:.2f}x")
print(f"输出shape: {output_data.shape}, 前3个值: {output_data[:3]}")

运行方式

# 安装依赖
pip install torch torchvision onnx pycuda tensorrt

# 执行脚本(需在NVIDIA GPU/Orin设备上)
python trt_cabin_demo.py

验证方法与通过标准

  • 引擎构建成功:脚本输出“TensorRT引擎构建完成”,且当前目录生成cabin_model_fp16.engine文件(约30MB)。
  • 推理输出正确:输出shape为(1, 1000),数值为有限浮点数(非NaN/Inf)。
  • 加速效果达标:TensorRT FP16延迟显著低于PyTorch GPU模式(通常快2~5倍)。若在无GPU环境运行,PyTorch将回退到CPU,此时加速比会更高,但仍需确认TensorRT推理正常完成。
  • 确定性预期输出:由于输入为随机噪声,输出值无法预先确定,但可验证输出张量每个元素均为有限值,且argmax索引在0~999之间。

常见问题

  • 显存不足:将workspace从1GB降至256MB(1 << 28),或减小batch size。
  • FP16精度损失:若分类结果与FP32差异过大,可保留FP32引擎对比,或使用INT8量化(需校准数据集)。
  • 动态shape报错:本案例已设置动态batch,若需固定shape可移除dynamic_axes参数。
TensorRT加速座舱视觉模型推理流程 PyTorch ResNet-18 预训练权重 torch.onnx ONNX cabin_model.onnx 动态batch TensorRT TensorRT引擎 FP16精度 cabin_model_fp16.engine workspace: 1GB execute 推理输出 (1, 1000) 置信度 延迟: ~2-5ms 延迟对比(越低越好) PyTorch GPU ~10-15 ms TensorRT FP16 ~2-5 ms ⚡ 预期加速比: 2~5x