1. 课程导入与平台全景
在深度学习推理部署中,模型训练完成只是起点。真正决定业务体验的,是模型能否在有限算力、有限显存和严格时延约束下稳定跑起来。CUDA 与 TensorRT 的组合,正是解决这一问题的核心工具链:CUDA 提供对 NVIDIA GPU 的通用并行计算能力,TensorRT 则在此基础上针对推理做图优化、精度校准与内核自动调优。本课程的目标,是让你从“会写 CUDA 核函数”和“会调用 TensorRT API”,进阶到“能设计一条从模型到高吞吐推理服务的协同加速链路”。
一、平台要解决的核心问题
一个典型的推理任务,输入是一张 3×640×640 的 RGB 图像,模型是 ResNet-50 或 YOLOv8,输出是分类概率或检测框。若直接用 PyTorch 在 GPU 上推理,单张耗时可能在 15~25 ms;而经过 TensorRT 的 FP16 优化与层融合后,同样精度下可降到 4~7 ms。这中间的差距,来自三类工作:
- 计算图优化:合并 Conv+BN+ReLU,消除无用的 transpose 与 concat,减少 kernel launch 次数。
- 精度选择:FP32 → FP16 → INT8,在精度损失可控的前提下提升吞吐。INT8 需要校准集,通常用 500~1000 张代表性图片。
- 内核自动调优:TensorRT 在构建 engine 时,会针对目标 GPU 架构(如 Ampere、Hopper)从多个候选 kernel 中实测选优,tactic 选择本身就要花几十秒到几分钟。
CUDA 在这里不是“被替代”,而是“被调用”。TensorRT 生成的 engine 内部仍然是 CUDA kernel,只是这些 kernel 由 TensorRT 的 builder 自动挑选和编排。当你需要自定义算子、做前处理(如 letterbox、归一化)或后处理(如 NMS),仍然要手写 CUDA kernel,并通过 plugin 机制嵌入 TensorRT 网络。因此,协同加速的本质是:TensorRT 负责通用图优化,CUDA 负责定制化与边界处理,两者共享同一块 GPU 显存与流(stream)。
二、技术栈组成与数据流
从模型文件到最终推理结果,整条链路可以拆成五个阶段:模型导出、engine 构建、运行时初始化、前处理、推理与后处理。下图展示了各阶段涉及的关键对象、输入输出以及 CUDA 与 TensorRT 的分工关系。
图中最值得注意的一点是:前处理和后处理被明确划归 CUDA 侧。很多初学者会把整张图都交给 TensorRT,结果发现 resize 和 NMS 成为瓶颈。以 YOLOv8 为例,若用 OpenCV 在 CPU 上做 letterbox,单帧可能耗 3~5 ms;改成 CUDA kernel 后可以压到 0.3 ms 以内。这就是协同加速中“边界处理”必须自己掌控的原因。
三、典型应用场景
这套平台主要面向三类场景。第一类是云端高吞吐推理,例如推荐系统里的 embedding 推理、视频平台的内容审核,要求单卡 QPS 尽可能高,通常用 INT8 + 多 stream 并发。第二类是边缘低延迟推理,如自动驾驶感知、工业质检,要求端到端时延稳定在 10 ms 以内,更关注 FP16 下的确定性时延和显存占用。第三类是自定义算子密集的模型,如 BEV 感知、点云检测,标准 TensorRT 层无法覆盖,必须写 CUDA plugin 并注册到网络里。
三类场景的优化侧重点不同:云端看吞吐,边缘看尾延迟,自定义算子看 plugin 与 TensorRT 的融合边界。课程后续会分别用独立章节展开,但你现在就应该建立这个判断:先明确场景约束,再决定精度、batch 和 stream 策略。
四、学习路径规划
本课程共 30 章,建议按“先打通链路,再逐段优化”的顺序推进。前 6 章建立平台全景与 CUDA 编程基础,包括线程层次、内存模型和第一个向量加法 kernel;第 7~12 章进入 TensorRT 核心,覆盖 ONNX 解析、builder 配置、FP16/INT8 校准和 engine 序列化;第 13~20 章做协同实战,包括 CUDA plugin 编写、多 stream 流水线、动态 shape 处理和显存复用;第 21~30 章进入性能分析与工程化,涉及 Nsight Systems profiling、尾延迟排查、服务化封装和版本兼容。
cudaEvent 测出 kernel 耗时;第 10 章结束后,你应该能用 trtexec 把一个 ONNX 模型转成 FP16 engine,并对比 FP32 与 FP16 的吞吐差异。没有实测数字,优化就只是猜测。
五、一个最小可复现的起点
在进入后续章节前,先确认环境可用。以下命令用于检查 CUDA 与 TensorRT 是否就绪,并查看 GPU 架构,因为 engine 构建时的 tactic 选择与架构强相关。
nvcc --version
# 输出应包含 release 12.x 或 11.x
dpkg -l | grep nvinfer
# 确认 TensorRT 版本,如 8.6.x 或 10.x
nvidia-smi --query-gpu=name,compute_cap,memory.total --format=csv
# 示例输出:NVIDIA A10, 8.6, 24564 MiB
其中 compute_cap 为 8.6 表示 Ampere 架构,支持 TF32 与 INT8;若为 7.5 则是 Turing,INT8 支持但无 TF32。这个数字会直接影响你在 builder 里能否启用某些 tactic。记录下你的 GPU 型号、compute capability、CUDA 版本和 TensorRT 版本,后续每章的性能对比都要基于同一套环境,否则数字没有可比性。
到这里,平台全景已经铺开:CUDA 管边界与定制,TensorRT 管图优化与精度,两者通过显存和 stream 协同。接下来要做的,是从最底层的 CUDA 线程模型开始,把这条链路真正跑通。