TensorRT 基础与核心流程完整学习笔记
文章目录
- [TensorRT 基础与核心流程完整学习笔记](#TensorRT 基础与核心流程完整学习笔记)
-
- [一、TensorRT 是什么](#一、TensorRT 是什么)
- [二、TensorRT 最核心的两个阶段](#二、TensorRT 最核心的两个阶段)
- [三、Build 是什么意思](#三、Build 是什么意思)
- [四、TensorRT Build 的完整流程](#四、TensorRT Build 的完整流程)
- 五、Parser:模型解析器
- [六、Network / Network Definition 是什么](#六、Network / Network Definition 是什么)
- [七、Graph 是什么](#七、Graph 是什么)
- [八、Operator / Op 是什么](#八、Operator / Op 是什么)
- [九、Layer 和 Operator 有什么区别](#九、Layer 和 Operator 有什么区别)
- [十、Tensor 是什么](#十、Tensor 是什么)
- [十一、Shape 是什么](#十一、Shape 是什么)
- [十二、Shape Analysis:Shape 分析](#十二、Shape Analysis:Shape 分析)
- [十三、Dynamic Shape 是什么](#十三、Dynamic Shape 是什么)
- [十四、Optimization Profile 是什么](#十四、Optimization Profile 是什么)
- [十五、为什么需要 OPT Shape](#十五、为什么需要 OPT Shape)
- [十六、Graph Optimization 是什么](#十六、Graph Optimization 是什么)
- [十七、Constant Folding 是什么](#十七、Constant Folding 是什么)
- [十八、Dead Computation Removal 是什么](#十八、Dead Computation Removal 是什么)
- [十九、Layer Fusion 是什么](#十九、Layer Fusion 是什么)
- [二十、Precision 是什么](#二十、Precision 是什么)
- [二十一、Data Type / DType 是什么](#二十一、Data Type / DType 是什么)
- [二十二、Kernel 是 TensorRT 中极其重要的概念](#二十二、Kernel 是 TensorRT 中极其重要的概念)
- [二十三、同一个 Operator 为什么会有多个 Kernel](#二十三、同一个 Operator 为什么会有多个 Kernel)
- [二十四、Tactic 是什么](#二十四、Tactic 是什么)
- [二十五、Tactic 和 Kernel 的区别](#二十五、Tactic 和 Kernel 的区别)
- [二十六、Tactic Selection 是什么](#二十六、Tactic Selection 是什么)
- [二十七、Benchmark 是什么](#二十七、Benchmark 是什么)
- [二十八、Auto Tuning 是什么](#二十八、Auto Tuning 是什么)
- [二十九、为什么 TensorRT Build 会比较慢](#二十九、为什么 TensorRT Build 会比较慢)
- [三十、Tensor Layout 是什么](#三十、Tensor Layout 是什么)
- [三十一、NHWC 是什么](#三十一、NHWC 是什么)
- [三十二、Tensor Format 是什么](#三十二、Tensor Format 是什么)
- [三十三、Reformat 是什么](#三十三、Reformat 是什么)
- [三十四、Memory 是什么](#三十四、Memory 是什么)
- [三十五、Memory Planning 是什么](#三十五、Memory Planning 是什么)
- [三十六、Memory Reuse 是什么](#三十六、Memory Reuse 是什么)
- [三十七、Workspace 是什么](#三十七、Workspace 是什么)
- [三十八、Execution Plan 是什么](#三十八、Execution Plan 是什么)
- [三十九、Engine 是什么](#三十九、Engine 是什么)
- [四十、Serialization 是什么](#四十、Serialization 是什么)
- [四十一、Serialized Engine 是什么](#四十一、Serialized Engine 是什么)
- [四十二、Deserialization 是什么](#四十二、Deserialization 是什么)
- [四十三、Runtime 是什么](#四十三、Runtime 是什么)
- [四十四、TensorRT Runtime 完整流程](#四十四、TensorRT Runtime 完整流程)
- [四十五、ICudaEngine 是什么](#四十五、ICudaEngine 是什么)
- [四十六、ExecutionContext 是什么](#四十六、ExecutionContext 是什么)
- [四十七、Engine 和 ExecutionContext 区别](#四十七、Engine 和 ExecutionContext 区别)
- [四十八、Buffer 是什么](#四十八、Buffer 是什么)
- [四十九、Host 是什么](#四十九、Host 是什么)
- [五十、Device 是什么](#五十、Device 是什么)
- [五十一、H2D 是什么](#五十一、H2D 是什么)
- [五十二、D2H 是什么](#五十二、D2H 是什么)
- [五十三、Inference 是什么](#五十三、Inference 是什么)
- [五十四、CUDA Stream 是什么](#五十四、CUDA Stream 是什么)
- [五十五、enqueue 是什么意思](#五十五、enqueue 是什么意思)
- [五十六、为什么叫 enqueue 而不是 run](#五十六、为什么叫 enqueue 而不是 run)
- [五十七、Synchronous 和 Asynchronous](#五十七、Synchronous 和 Asynchronous)
- [五十八、Kernel Launch 是什么](#五十八、Kernel Launch 是什么)
- [五十九、Latency 是什么](#五十九、Latency 是什么)
- [六十、Throughput 是什么](#六十、Throughput 是什么)
- [六十一、Latency 和 Throughput 区别](#六十一、Latency 和 Throughput 区别)
- [六十二、Pre-processing 是什么](#六十二、Pre-processing 是什么)
- [六十三、Post-processing 是什么](#六十三、Post-processing 是什么)
- [六十四、Decode 是什么](#六十四、Decode 是什么)
- [六十五、NMS 是什么](#六十五、NMS 是什么)
- [六十六、Plugin 是什么](#六十六、Plugin 是什么)
- [六十七、Tensor Core 是什么](#六十七、Tensor Core 是什么)
- [六十八、CUDA Core 和 Tensor Core 简单区别](#六十八、CUDA Core 和 Tensor Core 简单区别)
- [六十九、Build 阶段到底可以归纳成哪三类问题](#六十九、Build 阶段到底可以归纳成哪三类问题)
- [七十、Runtime 阶段也可以归纳成三部分](#七十、Runtime 阶段也可以归纳成三部分)
- [七十一、完整 TensorRT 生命周期](#七十一、完整 TensorRT 生命周期)
- [七十二、最终需要建立的 TensorRT 心智模型](#七十二、最终需要建立的 TensorRT 心智模型)
- 七十三、最核心的英文词汇总结
- [七十四、一句话总结 TensorRT](#七十四、一句话总结 TensorRT)
一、TensorRT 是什么
TensorRT 是 NVIDIA 推出的一个高性能深度学习推理优化与运行框架。
它主要解决的问题不是:
"如何训练模型?"
而是:
"一个已经训练好的模型,如何在 NVIDIA GPU 上运行得更快?"
因此 TensorRT 主要用于模型部署阶段。
典型流程如下:
text
PyTorch / TensorFlow
↓
训练
↓
模型权重
↓
导出
↓
ONNX
↓
TensorRT Build
↓
TensorRT Engine
↓
TensorRT Runtime
↓
NVIDIA GPU
↓
推理结果
可以简单理解:
text
PyTorch
= 训练模型
ONNX
= 描述模型
TensorRT
= 优化并执行模型
CUDA
= 控制 GPU 进行计算
TensorRT 的核心思想是:
把训练阶段不需要的东西去掉,然后针对指定 NVIDIA GPU,对模型计算图、Kernel、内存、数据类型等进行优化。
二、TensorRT 最核心的两个阶段
从整个生命周期来看,TensorRT 可以分成两大阶段:
text
TensorRT
├── Build
│
└── Runtime
也就是:
text
Build
=
构建 / 编译模型
Runtime
=
运行模型
这是理解 TensorRT 最重要的一条主线。
可以类比 C++:
text
C++ 源代码
↓
编译器
↓
可执行程序
↓
运行程序
TensorRT 类似:
text
ONNX
↓
TensorRT Builder
↓
Engine
↓
TensorRT Runtime
所以可以粗略类比:
text
ONNX
≈ 源代码
TensorRT Builder
≈ 编译器
TensorRT Engine
≈ 可执行文件
TensorRT Runtime
≈ 程序运行环境
需要注意,这只是为了帮助理解,实际底层并不是完全等价。
三、Build 是什么意思
Build 中文一般翻译为:
构建。
但是在 TensorRT 中,实际上更接近:
编译。
TensorRT Build 并不是简单把:
text
model.onnx
转换成:
text
model.engine
如果只是文件格式变化,可以叫:
text
Convert
转换
但是 TensorRT Build 实际做了大量工作:
text
解析模型
+
检查算子
+
Shape 推导
+
计算图优化
+
Layer Fusion
+
精度处理
+
Tactic 搜索
+
Kernel 选择
+
Tensor Layout 选择
+
显存规划
+
执行计划生成
+
序列化
因此更加准确地说:
TensorRT Build 是一次模型编译和优化过程。
四、TensorRT Build 的完整流程
TensorRT Build 可以表示成:
text
ONNX
│
↓
Parser
│
↓
TensorRT Network
│
↓
Shape Analysis
│
↓
Graph Optimization
│
↓
Layer Fusion
│
↓
Precision Handling
│
↓
Tactic Search
│
↓
Kernel Selection
│
↓
Tensor Layout
│
↓
Memory Planning
│
↓
Execution Planning
│
↓
Serialized Engine
下面逐步讲。
五、Parser:模型解析器
Parser 中文叫:
解析器。
如果使用 ONNX 模型:
text
model.onnx
TensorRT 需要先把 ONNX 中保存的计算图读取出来。
ONNX 中可能包含:
text
Input
↓
Conv
↓
BatchNorm
↓
SiLU
↓
Conv
↓
Concat
↓
Resize
↓
Output
ONNX Parser 会读取:
text
Operator
Tensor
Weight
Shape
Attribute
Data Type
输入输出关系
然后转换成 TensorRT 自己能够理解的:
text
TensorRT Network
也就是:
text
ONNX Graph
↓
ONNX Parser
↓
TensorRT Network Definition
六、Network / Network Definition 是什么
Network 中文就是:
网络。
Network Definition 可以理解为:
TensorRT 内部对神经网络计算图的描述。
比如原始网络:
text
Input
↓
Conv
↓
Relu
↓
Conv
↓
Output
TensorRT 内部也需要保存:
text
有哪些 Layer
有哪些 Tensor
Layer 怎么连接
输入是什么
输出是什么
Shape 是什么
Data Type 是什么
这个内部计算图就是:
text
Network Definition
对应 TensorRT API 中常见的:
text
INetworkDefinition
七、Graph 是什么
Graph 中文叫:
图。
在深度学习部署里面,通常指:
计算图。
例如:
text
Input
│
↓
Conv
│
↓
Relu
│
↓
Add
│
↓
Output
其中:
text
Conv
Relu
Add
可以认为是图中的:
text
Node
节点
它们之间的数据连接就是:
text
Edge
边
因此:
text
Graph
=
节点 + 连接关系
深度学习模型本质上可以被表示成一张计算图。
八、Operator / Op 是什么
Operator 中文叫:
算子。
简称:
text
Op
例如:
text
Conv
MatMul
Add
Relu
Softmax
Resize
Concat
都是算子。
算子描述的是:
要进行什么数学运算。
例如:
text
Add
表示:
text
Y = A + B
而:
text
MatMul
表示矩阵乘法:
text
Y = A × B
九、Layer 和 Operator 有什么区别
在实际工程里:
text
Layer
Operator
经常混用。
可以简单理解:
text
Operator
=
一种计算规则
Layer
=
网络中的一个实际计算节点
例如 Conv 是一种 Operator。
网络中可能有:
text
Conv1
Conv2
Conv3
这三个可以认为是三个不同 Layer。
十、Tensor 是什么
Tensor 中文叫:
张量。
可以把它简单理解为:
多维数组。
例如:
text
3
是标量。
text
[1,2,3]
是一维数组。
text
[
[1,2],
[3,4]
]
是二维矩阵。
深度学习中经常使用四维 Tensor:
text
[1, 3, 640, 640]
分别表示:
text
N = Batch
C = Channel
H = Height
W = Width
所以:
text
[1,3,640,640]
表示:
text
1 张图片
3 个通道
高度 640
宽度 640
十一、Shape 是什么
Shape 中文叫:
形状。
它描述 Tensor 每个维度是多少。
例如:
text
Tensor Shape
=
[1,3,640,640]
表示:
text
N = 1
C = 3
H = 640
W = 640
Shape 对 TensorRT 非常重要,因为 Shape 会影响:
text
Kernel 选择
显存大小
计算量
Tensor Layout
Tactic
性能
十二、Shape Analysis:Shape 分析
TensorRT Build 时会进行 Shape 推导。
例如:
text
Input
[1,3,640,640]
↓
Conv stride=2
↓
[1,32,320,320]
↓
Conv stride=2
↓
[1,64,160,160]
TensorRT 必须知道每一层:
text
输入 Shape
输出 Shape
因为后面的:
text
Kernel Selection
Memory Planning
Tensor Layout
都依赖 Shape。
十三、Dynamic Shape 是什么
Dynamic Shape 中文:
动态形状。
如果模型输入始终固定:
text
[1,3,640,640]
叫:
text
Static Shape
静态 Shape
如果输入可能变化:
text
[1,3,320,320]
[1,3,640,640]
[4,3,640,640]
[8,3,1280,1280]
就属于:
text
Dynamic Shape
ONNX 中可能表示:
text
[-1,3,-1,-1]
这里的:
text
-1
表示该维度运行时才能确定。
十四、Optimization Profile 是什么
Dynamic Shape 模型不能允许无限变化。
因此 Build 时要告诉 TensorRT:
text
输入最小是多少
常用输入是多少
最大允许是多少
这就是:
Optimization Profile。
通常包括:
text
MIN
OPT
MAX
例如:
text
MIN
=
[1,3,320,320]
OPT
=
[1,3,640,640]
MAX
=
[8,3,1280,1280]
可以理解:
text
MIN
=
最小允许输入
OPT
=
最常使用、重点优化输入
MAX
=
最大允许输入
运行时实际 Shape 必须处在:
text
MIN ~ MAX
之间。
十五、为什么需要 OPT Shape
TensorRT 不仅需要知道:
text
哪些 Shape 可以运行
还希望知道:
text
你最经常运行哪个 Shape
例如你的业务 90% 都是:
text
1×3×640×640
那么:
text
OPT = [1,3,640,640]
TensorRT 可以重点针对这个 Shape 优化。
所以:
OPT Shape 不是"最大 Shape",而是"最典型、最希望优化的 Shape"。
十六、Graph Optimization 是什么
Graph Optimization 中文叫:
计算图优化。
TensorRT 会分析模型:
text
原始计算图
然后尝试生成:
text
更加适合 GPU 执行的计算图
主要包括:
text
Constant Folding
Layer Fusion
Dead Computation Removal
算子重排
冗余节点消除
Reformat 优化
等等。
十七、Constant Folding 是什么
Constant Folding 中文:
常量折叠。
例如:
text
A = 10
B = 20
C = A + B
A 和 B 都不会变化。
如果每次推理都计算:
text
C = 10 + 20
显然没有意义。
Build 时可以提前计算:
text
C = 30
于是 Runtime 根本不需要再算。
这个过程就是:
text
Constant Folding
十八、Dead Computation Removal 是什么
Dead 的意思:
无效的、不再需要的。
假设:
text
A
↓
B
↓
C
但是 C 最终没有参与 Output
那么这部分计算:
text
A → B → C
其实对最终结果没有作用。
TensorRT 可以删除。
这就是:
text
Dead Computation Elimination
或者:
text
Dead Layer Removal
十九、Layer Fusion 是什么
Layer Fusion 中文:
层融合。
例如:
text
Conv
↓
Bias
↓
ReLU
如果分别运行:
text
Kernel 1
=
Conv
Kernel 2
=
Bias
Kernel 3
=
ReLU
意味着 GPU:
text
读显存
计算
写显存
读显存
计算
写显存
读显存
计算
写显存
TensorRT 可能把它变成:
text
Conv + Bias + ReLU
然后通过一个融合 Kernel 执行。
于是:
text
读一次
↓
完成多个计算
↓
写一次
可以减少:
text
Kernel Launch
中间 Tensor
显存读写
所以 Layer Fusion 是 TensorRT 加速的重要来源之一。
二十、Precision 是什么
Precision 中文叫:
精度。
常见的数据精度包括:
text
FP32
FP16
BF16
FP8
INT8
INT4
例如:
text
FP32
=
32 bit 浮点
FP16
=
16 bit 浮点
INT8
=
8 bit 整数
一般来说数据位数越少:
text
显存占用可能越小
内存带宽压力越低
Tensor Core 利用率可能越高
计算可能更快
但同时:
text
数值精度风险增加
二十一、Data Type / DType 是什么
Data Type:
数据类型。
简称:
text
DType
例如 Tensor:
text
X
它可能是:
text
float32
float16
int8
int32
TensorRT Build 时需要知道每个 Tensor 使用什么数据类型。
Precision 和 DType 概念比较接近,但可以粗略理解:
text
Precision
=
你希望计算使用多高精度
DType
=
这个 Tensor 实际是什么数据类型
二十二、Kernel 是 TensorRT 中极其重要的概念
Kernel 中文一般叫:
核函数。
CUDA Kernel 是:
真正在 GPU 上执行的一段函数。
例如:
text
Conv
只是数学意义上的:
text
卷积运算
真正 GPU 执行时需要:
text
某段 GPU 程序
也就是:
text
CUDA Kernel
可以理解:
text
Operator
=
告诉你"算什么"
Kernel
=
告诉 GPU"具体怎么计算"
二十三、同一个 Operator 为什么会有多个 Kernel
例如:
text
MatMul
数学定义都是:
text
C = A × B
但是 GPU 上实现矩阵乘法的方法很多。
可能:
text
Kernel A
Kernel B
Kernel C
Kernel D
它们在不同情况下性能不同。
例如:
text
Shape = 1×512×512
可能 Kernel A 快。
而:
text
Shape = 32×4096×4096
可能 Kernel C 更快。
所以:
没有一个 Kernel 对所有情况都一定最好。
二十四、Tactic 是什么
Tactic 是 TensorRT 中非常关键的英文词。
中文可以理解成:
执行策略。
或者:
某个 Layer 的具体实现方案。
例如:
text
Conv Layer
可能有:
text
Tactic A
Tactic B
Tactic C
Tactic D
每个 Tactic 可能对应不同:
text
Kernel
算法
数据 Layout
Workspace
执行方案
TensorRT Build 时会尝试比较不同 Tactic。
二十五、Tactic 和 Kernel 的区别
这是必须分清的。
简单理解:
text
Tactic
=
方案
Kernel
=
真正执行的 GPU 代码
例如:
text
Conv Layer
├── Tactic A
│ ↓
│ Kernel A
│
├── Tactic B
│ ↓
│ Kernel B
│
└── Tactic C
↓
Kernel C
TensorRT 可能测试:
text
Tactic A
=
0.42 ms
Tactic B
=
0.23 ms
Tactic C
=
0.31 ms
于是最后:
text
选择 Tactic B
二十六、Tactic Selection 是什么
Tactic Selection:
Tactic 选择。
TensorRT Build 会根据:
text
GPU 型号
Shape
DType
Tensor Layout
Workspace
模型结构
寻找一个高性能 Tactic。
过程可以理解:
text
某个 Layer
↓
找到多个可执行 Tactic
↓
Benchmark
↓
比较性能
↓
选择合适方案
二十七、Benchmark 是什么
Benchmark:
性能测试。
例如:
text
Kernel A
0.40 ms
Kernel B
0.28 ms
Kernel C
0.35 ms
TensorRT 通过实际测量或内部性能信息判断:
text
哪个方案更合适
因此 Build 通常比 Runtime 慢很多。
因为 Build 要做:
text
搜索
+
测试
+
选择
而 Runtime 直接执行已经选好的方案。
二十八、Auto Tuning 是什么
Auto Tuning:
自动调优。
就是程序自动:
text
寻找不同方案
↓
测试性能
↓
选择最优或较优方案
TensorRT 的 Tactic Selection 就具有典型的自动调优思想。
二十九、为什么 TensorRT Build 会比较慢
因为 Build 做的事情很多:
text
模型解析
↓
计算图优化
↓
Shape 分析
↓
寻找多个 Tactic
↓
Benchmark
↓
选择 Kernel
↓
选择 Layout
↓
Memory Planning
↓
生成 Engine
这可能需要:
text
几秒
几十秒
数分钟
但是 Build 一般不是每次推理都执行。
通常:
text
Build 一次
↓
保存 Engine
↓
Runtime 加载 Engine
↓
执行几万、几十万甚至更多次
所以思想是:
用离线 Build 时间换线上 Runtime 性能。
三十、Tensor Layout 是什么
Tensor Layout:
Tensor 数据在内存中的排列方式。
例如图像最常见:
text
NCHW
分别表示:
text
N = Batch
C = Channel
H = Height
W = Width
例如:
text
[1,3,640,640]
三十一、NHWC 是什么
另一种排列方式:
text
NHWC
表示:
text
N = Batch
H = Height
W = Width
C = Channel
所以:
text
NCHW
和:
text
NHWC
表达的数据可能一样。
区别在于:
数据在内存中的排列顺序不同。
这会影响:
text
显存访问
向量化
Tensor Core
Kernel 性能
三十二、Tensor Format 是什么
Tensor Format:
Tensor 在 TensorRT / GPU 中的具体存储格式。
除了常见:
text
NCHW
NHWC
TensorRT 内部还可能使用更适合 GPU 向量化计算的格式。
例如概念上:
text
CHW4
CHW32
这些格式会对 Channel 做特殊打包。
目的主要是:
text
提升显存访问效率
+
提升向量化能力
+
更好利用 Tensor Core
三十三、Reformat 是什么
Reformat:
数据格式转换。
假如:
text
Layer A
输出:
text
NCHW
而:
text
Layer B
希望输入:
text
CHW32
那么中间可能:
text
Layer A
↓
Reformat
↓
Layer B
Reformat 本身有成本。
因此 TensorRT Build 需要综合考虑:
text
更快的 Layer Kernel
是否值得增加:
text
Reformat 开销
所以 TensorRT 优化通常不是:
每一层单独找最快 Kernel。
而是:
从整体 Graph 性能进行权衡。
三十四、Memory 是什么
Memory:
内存。
在 TensorRT / CUDA 中,需要区分:
text
Host Memory
和:
text
Device Memory
Host 通常指:
text
CPU
Device 通常指:
text
GPU
因此:
text
Host Memory
=
CPU RAM
Device Memory
=
GPU 显存 / VRAM
三十五、Memory Planning 是什么
Memory Planning:
内存规划。
TensorRT Build 时会分析:
text
每个 Tensor 多大
什么时候产生
什么时候被使用
什么时候已经不需要
比如:
text
Tensor A
在 Layer 3 后就再也不用。
那么 A 占用的显存就可以后面复用。
三十六、Memory Reuse 是什么
Memory Reuse:
内存复用。
例如:
text
Tensor A
占用 100 MB
使用完成
↓
这块 100 MB 显存空闲
后面的:
text
Tensor C
可能直接使用同一块显存。
于是:
text
Tensor A
↓
使用显存 X
Tensor A 生命周期结束
Tensor C
↓
继续使用显存 X
这样可以减少峰值显存。
三十七、Workspace 是什么
Workspace:
工作空间。
某些 GPU 算法为了运行,需要额外临时显存。
例如:
text
Kernel A
需要 10 MB Workspace
Kernel B
需要 500 MB Workspace
虽然 Kernel B 可能更快,但是需要更多显存。
TensorRT Build 会综合:
text
性能
+
Workspace
+
显存限制
选择合适 Tactic。
所以 Workspace 可以理解成:
Kernel 执行过程中使用的临时 GPU 工作内存。
三十八、Execution Plan 是什么
Execution Plan:
执行计划。
TensorRT Build 完成后,已经基本确定:
text
整个计算图怎么执行
Layer 的顺序
使用什么 Tactic
调用哪些 Kernel
采用什么 Layout
使用什么 Precision
显存如何安排
这些信息组合起来,可以理解成:
text
GPU 执行计划
最终封装进:
text
TensorRT Engine
三十九、Engine 是什么
Engine:
TensorRT 推理引擎。
它是 Build 阶段最重要的产物。
可以理解:
text
Engine
=
优化后的计算图
+
模型权重
+
Tactic
+
Kernel 执行信息
+
Tensor Layout
+
Shape Profile
+
Memory Plan
+
Execution Plan
所以:
text
ONNX
和:
text
Engine
完全不是一个层级。
可以理解:
text
ONNX
=
模型"应该怎么算"
Engine
=
模型"在这块 GPU 上具体怎么高效地算"
四十、Serialization 是什么
Serialization:
序列化。
TensorRT Build 完成后,Engine 是一个内存中的对象。
为了下次直接使用,需要把它保存:
text
Engine Object
↓
Serialization
↓
Binary File
例如:
text
model.engine
model.plan
本质上都属于:
text
Serialized Engine
四十一、Serialized Engine 是什么
Serialized Engine:
已序列化的 TensorRT Engine。
也就是:
text
Engine
保存到磁盘后的二进制形式。
例如:
text
yolo.engine
后面程序启动:
text
读取 yolo.engine
↓
反序列化
↓
ICudaEngine
四十二、Deserialization 是什么
Deserialization:
反序列化。
刚好和 Serialization 相反。
text
model.engine
↓
Deserialization
↓
ICudaEngine
即:
把磁盘上的 Engine 文件重新恢复为程序可以执行的 Engine 对象。
四十三、Runtime 是什么
Runtime:
运行时。
Build 解决:
text
怎么优化模型
怎么选择 Kernel
怎么规划显存
而 Runtime 解决:
text
怎么把 Engine 真正跑起来
可以简单记:
text
Build
=
准备怎么跑
Runtime
=
真正跑
四十四、TensorRT Runtime 完整流程
典型 Runtime:
text
model.engine
↓
Deserialize
↓
ICudaEngine
↓
Create ExecutionContext
↓
Set Input Shape
↓
Prepare GPU Buffer
↓
H2D
↓
enqueueV3
↓
CUDA Stream
↓
GPU Kernel Execution
↓
GPU Output
↓
D2H
↓
Post-processing
↓
Result
四十五、ICudaEngine 是什么
TensorRT 中经常看到:
text
ICudaEngine
它可以理解成:
已经加载到程序中的 TensorRT Engine 对象。
例如:
text
model.engine
只是一个文件。
读取后:
text
IRuntime
↓
deserializeCudaEngine()
↓
ICudaEngine
此时程序才能继续创建 ExecutionContext。
四十六、ExecutionContext 是什么
ExecutionContext:
执行上下文。
对应常见 API:
text
IExecutionContext
Engine 可以理解成:
text
已经编译好的程序
Context 可以理解:
text
程序的一次运行实例 / 执行状态
例如:
text
Engine
│
├── Context A
├── Context B
└── Context C
Context 里面可能保存:
text
当前输入 Shape
当前 Optimization Profile
Tensor 地址
执行相关状态
四十七、Engine 和 ExecutionContext 区别
这是 TensorRT 最重要的概念之一。
可以简单记:
text
Engine
=
怎么执行这个模型
ExecutionContext
=
这一次具体怎么执行
例如 Engine 支持:
text
MIN
=
1×3×320×320
MAX
=
8×3×1280×1280
而某个 Context 本次实际执行:
text
1×3×640×640
另外一个 Context 可能执行:
text
4×3×640×640
四十八、Buffer 是什么
Buffer:
缓冲区。
本质上:
一块保存数据的内存。
模型需要:
text
Input Buffer
保存输入。
还需要:
text
Output Buffer
保存输出。
TensorRT GPU 推理时一般需要:
text
GPU Input Buffer
GPU Output Buffer
四十九、Host 是什么
Host:
主机。
在 CUDA 中通常就是:
text
CPU 端
例如:
text
Host Memory
通常表示:
text
CPU RAM
五十、Device 是什么
Device:
设备。
在 CUDA 场景下一般指:
text
GPU
因此:
text
Device Memory
就是:
text
GPU VRAM
GPU 显存
五十一、H2D 是什么
H2D:
text
Host To Device
即:
text
CPU
↓
GPU
例如一张图片经过 CPU 前处理以后:
text
CPU Tensor
↓
cudaMemcpy
↓
GPU Input Buffer
这个过程就是:
text
H2D
五十二、D2H 是什么
D2H:
text
Device To Host
表示:
text
GPU
↓
CPU
例如模型输出:
text
GPU Output Tensor
↓
cudaMemcpy
↓
CPU
然后 CPU 做:
text
Decode
NMS
这就是:
text
D2H
五十三、Inference 是什么
Inference:
推理。
训练完成后:
text
输入数据
↓
模型
↓
输出结果
这个过程叫:
text
Inference
例如:
text
图片
↓
YOLO
↓
检测框
这就是一次模型推理。
五十四、CUDA Stream 是什么
CUDA Stream:
CUDA 流。
可以先粗略理解成:
GPU 任务队列。
例如:
text
CUDA Stream
任务 1
H2D
↓
任务 2
TensorRT Inference
↓
任务 3
D2H
GPU 会按照 Stream 中的依赖关系执行这些任务。
五十五、enqueue 是什么意思
enqueue:
入队。
即:
text
把一个任务放进执行队列
TensorRT 中经常看到:
text
enqueueV3()
可以理解成:
text
把当前 TensorRT 推理任务
提交到 CUDA Stream
即:
text
ExecutionContext
↓
enqueueV3(stream)
↓
CUDA Stream
↓
GPU 执行
五十六、为什么叫 enqueue 而不是 run
因为 TensorRT + CUDA 大量使用:
text
Asynchronous Execution
也就是:
异步执行。
CPU 调用:
text
enqueueV3()
更接近:
text
"我把这个任务提交给 GPU"
而不是:
text
"CPU 在这里一直等 GPU 全部跑完"
五十七、Synchronous 和 Asynchronous
Synchronous:
同步。
例如:
text
CPU 提交 GPU 任务
↓
CPU 等
↓
GPU 完成
↓
CPU 继续
Asynchronous:
异步。
例如:
text
CPU 提交 GPU 任务
↓
CPU 可以继续干别的
↓
GPU 后台执行
所以高性能 GPU Pipeline 一般倾向更多使用:
text
Async
五十八、Kernel Launch 是什么
Kernel Launch:
启动一个 GPU Kernel。
例如 CPU 告诉 GPU:
text
执行 Conv Kernel
这次启动就叫:
text
Kernel Launch
Kernel Launch 本身也存在开销。
所以:
text
很多小 Kernel
未必高效。
这也是:
text
Layer Fusion
重要的原因。
例如:
text
Conv
Relu
Add
三个 Kernel:
text
Launch
Launch
Launch
可能融合成:
text
一个 Kernel
减少 Kernel Launch 开销。
五十九、Latency 是什么
Latency:
延迟。
通常表示:
text
一次请求
从开始到完成需要多久
例如:
text
一张图片推理
=
5 ms
这里:
text
Latency = 5 ms
实时检测:
text
机器人
自动驾驶
摄像头检测
非常关注 Latency。
六十、Throughput 是什么
Throughput:
吞吐量。
表示:
text
单位时间可以处理多少数据
例如:
text
1000 images/s
就是吞吐量。
服务器场景通常更加关注:
text
Throughput
六十一、Latency 和 Throughput 区别
假设:
方案 A:
text
Batch = 1
1 张图片
=
3 ms
Latency 很低。
方案 B:
text
Batch = 32
32 张图片
=
32 ms
虽然一次 Batch 时间更长:
text
32 ms
但是:
text
32 张 / 32 ms
整体吞吐可能更高。
所以:
text
Latency
=
一件事情多快完成
Throughput
=
单位时间能干多少事情
六十二、Pre-processing 是什么
Pre-processing:
前处理。
在图片进入模型之前通常需要:
text
Resize
Normalize
Letterbox
颜色空间转换
HWC → CHW
uint8 → float
这些都属于:
text
Pre-processing
完整流程:
text
Raw Image
↓
Pre-processing
↓
Model
六十三、Post-processing 是什么
Post-processing:
后处理。
例如 YOLO 输出:
text
Raw Prediction
之后还可能需要:
text
Decode
Confidence Filtering
NMS
Coordinate Transform
最终才得到:
text
Bounding Box
所以:
text
Model
↓
Raw Output
↓
Post-processing
↓
Final Result
六十四、Decode 是什么
Decode:
解码。
检测模型输出往往不是最终的:
text
x1,y1,x2,y2
可能是一些网络原始预测值。
Decode 负责把这些值转换成:
text
Bounding Box
Confidence
Class
六十五、NMS 是什么
NMS:
text
Non-Maximum Suppression
中文:
非极大值抑制。
例如同一个人:
text
模型输出 10 个重叠框
NMS 会删除重复框:
text
保留最可信的框
因此:
text
Raw Boxes
↓
NMS
↓
Final Boxes
六十六、Plugin 是什么
Plugin:
插件。
TensorRT 自带很多 Operator:
text
Conv
MatMul
Relu
Softmax
Resize
...
但如果模型中有:
text
CustomOperator
TensorRT 不支持怎么办?
可以:
text
自己编写 CUDA Kernel
↓
包装成 TensorRT Plugin
↓
注册 Plugin
↓
TensorRT 使用
所以:
Plugin 本质上是 TensorRT 的自定义算子扩展机制。
六十七、Tensor Core 是什么
Tensor Core:
NVIDIA GPU 中专门用于矩阵计算的硬件单元。
深度学习大量计算最终都可以转成:
text
Matrix Multiplication
例如:
text
Linear
MatMul
Conv
Attention
所以:
text
Tensor Core
对 AI 推理非常重要。
TensorRT 会尽可能选择能够高效利用:
text
Tensor Core
的 Kernel。
六十八、CUDA Core 和 Tensor Core 简单区别
可以粗略理解:
text
CUDA Core
=
通用 GPU 计算单元
Tensor Core
=
特别擅长矩阵乘加计算的专用硬件
深度学习:
text
MatMul
Conv
Attention
通常非常适合 Tensor Core。
六十九、Build 阶段到底可以归纳成哪三类问题
TensorRT Build 看起来复杂,但本质可以归纳成三大问题:
text
Build
├── Graph
├── Kernel
└── Memory
第一:
text
Graph Optimization
=
到底算什么?
例如:
text
哪些节点删除
哪些节点融合
哪些常量提前计算
第二:
text
Kernel / Tactic Selection
=
具体怎么算最快?
例如:
text
Conv 选择哪个实现
MatMul 选择哪个 Kernel
第三:
text
Memory Planning
=
数据怎么放?
例如:
text
Tensor Layout
显存复用
Workspace
Buffer 生命周期
所以可以记:
TensorRT Build 本质就是 Graph + Compute + Memory 三方面优化。
七十、Runtime 阶段也可以归纳成三部分
Runtime 可以简化成:
text
Runtime
├── Context
├── Data
└── Execute
Context:
text
Engine
ExecutionContext
Input Shape
Optimization Profile
Data:
text
Buffer
Host
Device
H2D
D2H
Execute:
text
CUDA Stream
enqueueV3
CUDA Kernel
Synchronization
七十一、完整 TensorRT 生命周期
把前面的知识全部串起来:
text
PyTorch
│
↓
ONNX
│
↓
==================================================
BUILD
==================================================
│
ONNX Parser
│
↓
TensorRT Network
│
↓
Shape Analysis
│
↓
Optimization Profile
│
↓
Graph Optimization
│
↓
Layer Fusion
│
↓
Precision Handling
│
↓
Tactic Search
│
↓
Kernel Selection
│
↓
Tensor Layout
│
↓
Memory Planning
│
↓
Execution Planning
│
↓
Serialized Engine
│
↓
model.engine
│
==================================================
RUNTIME
==================================================
│
Deserialize Engine
│
↓
ICudaEngine
│
↓
ExecutionContext
│
↓
Set Input Shape
│
↓
Prepare Buffer
│
↓
CPU Input ──H2D──→ GPU Input Buffer
│
↓
enqueueV3()
│
↓
CUDA Stream
│
↓
GPU Kernels
│
↓
GPU Output Buffer
│
↓
D2H / GPU
│
↓
Post-processing
│
↓
Result
七十二、最终需要建立的 TensorRT 心智模型
以后看到 TensorRT,不应该只想到:
text
ONNX → Engine
而应该想到:
text
TensorRT
│
┌───────────┴───────────┐
↓ ↓
Build Runtime
│ │
模型编译优化 模型执行
│ │
┌──────┼──────┐ ┌────────┼────────┐
↓ ↓ ↓ ↓ ↓ ↓
Graph Kernel Memory Context Data Execute
Build:
text
Graph
=
优化计算图
Kernel
=
选择 GPU 计算方案
Memory
=
优化显存使用
Runtime:
text
Context
=
管理这一次运行状态
Data
=
管理 CPU/GPU 数据
Execute
=
通过 CUDA Stream 提交 GPU 执行
七十三、最核心的英文词汇总结
建议第一阶段优先记住下面这些词:
text
Tensor
张量
Shape
形状
Graph
计算图
Operator
算子
Layer
网络层
Parser
解析器
Network
网络定义
Build
构建 / 编译
Runtime
运行时
Engine
推理引擎
ExecutionContext
执行上下文
Tactic
执行策略
Kernel
GPU 核函数
Buffer
缓冲区
Memory
内存 / 显存
Workspace
临时工作显存
Host
CPU 端
Device
GPU 端
H2D
CPU → GPU
D2H
GPU → CPU
CUDA Stream
CUDA 任务流
enqueue
任务入队 / 提交任务
Inference
模型推理
Latency
单次延迟
Throughput
吞吐量
Plugin
自定义算子插件
Pre-processing
前处理
Post-processing
后处理
七十四、一句话总结 TensorRT
TensorRT 的工作可以总结成:
TensorRT 在 Build 阶段把 ONNX 等模型解析成内部计算图,然后进行 Shape 分析、图优化、算子融合、Tactic/Kernel 选择、Tensor Layout 和显存规划,最后生成高度优化的 Engine;在 Runtime 阶段加载 Engine、创建 ExecutionContext、准备 GPU Buffer,通过 CUDA Stream 和 enqueue 提交推理任务,并在 NVIDIA GPU 上执行已经优化好的 Kernel,最终得到模型输出。
更进一步压缩就是:
text
Build
=
提前决定怎么跑最快
Runtime
=
按照已经决定好的方案真正执行
这就是理解 TensorRT 最核心的一条主线。