你写了 model = torch.compile(model),然后代码就跑得快了一点。
但 它到底做了什么?TVM、Triton、IR 各自扮演什么角色?
本课给你一个完整的鸟瞰图。不需要记住每个缩写——先建立方位感,后面的课再逐一深入。
torch.compile + Triton(你已经在用);推理部署 → TVM 或 TensorRT。这两条线分工明确,换 TVM 做训练不会有收益。
PyTorch 默认以 Eager Mode 运行:
每次你调用一个操作,PyTorch 就立刻启动一个 GPU kernel。问题:
编译的目标就是:抓住计算图 → 合并小操作为大 kernel → 减少 launch 和显存往返。
Dynamo 做的事情很直观:它 劫持 Python 解释器的帧评估钩子(frame evaluation hook),在代码执行前拦截字节码,把 PyTorch 操作记录成一张 FX 图。
关键概念:Graph Break。Dynamo 不是万能的——遇到它不认识的代码(data-dependent control flow、不支持的操作),图会断开。断点太多,编译的好处就少了。用 torch.compile(fullgraph=True) 可以检测断点。
Inductor 拿到 FX Graph 后做两件事:
第一步:算子融合(Operator Fusion)
这是编译最大的性能收益来源。对于 transformer 里大量的 element-wise 操作(LayerNorm 周围的 add、mul、div),融合能减少 60-80% 的显存带宽消耗。
第二步:降低到 Loop-level IR
FX Graph 是算子级别的("这里有一个 add,这里有一个 relu")。Loop-level IR 是更底层的("这里有一个循环,循环体里做加法,再做 relu")。这个降低让 Inductor 可以决定:
Inductor 把 Loop-level IR 翻译成 Triton 代码(一种 Python-like 的 GPU kernel 语言),然后 Triton 编译器把 Triton 代码编译成 PTX(NVIDIA GPU 的汇编中间表示),最终由 NVIDIA 驱动编译成 GPU 可执行的 SASS。
Triton 的核心创新:block-level 编程。手写 CUDA 需要分别管理 thread 和 block,Triton 只需要你在 block 层面描述计算,它自动处理:
这就是为什么 torch.compile 能"零成本"加速——你不需要写任何 kernel 代码。
PyTorch 2.0: The Journey to 2x Training Speedups (arXiv:2304.04487) — Meta 团队对 torch.compile 架构最权威的阐述。IR = Intermediate Representation = 中间表示。
编译器的本质是对信息做 representation(表示)→ transformation(变换)。每一步你换一种表示,在那个表示上做某种变换,然后传到下一层。
| IR 层次 | 谁产生 | 表示什么 | 适合做什么优化 |
|---|---|---|---|
| FX Graph | Dynamo | 算子级 DAG(add、matmul、softmax…) | 算子替换、死代码消除、常量折叠 |
| Loop-level IR | Inductor | 循环 + 访存模式 | 算子融合、分块(tiling)、向量化、布局选择 |
| Triton IR | Inductor 输出 | Block-level GPU 语义 | 线程映射、共享内存分配、自动调优 |
| PTX | Triton 编译器 | NVIDIA GPU 虚拟 ISA | 寄存器分配、指令调度 |
| SASS | NVIDIA 驱动 | 具体 GPU 架构的机器码 | —(最终执行) |
| TVM Relay/Relax | TVM(推理) | 模型级计算图(替代 FX Graph 角色) | 跨算子融合、layout rewrite、量化、异构调度 |
| torch.compile + Triton | Apache TVM | NVIDIA TensorRT | |
|---|---|---|---|
| 主要场景 | 训练 + 推理 | 推理(多硬件) | 推理(NVIDIA only) |
| IR 层数 | FX → Loop → Triton 三层 | Relax → TIR 两层 | 单一计算图 IR |
| Kernel 生成 | Triton(自动, 运行时 JIT) | AutoTVM / MetaSchedule(需 auto-tuning, 小时级) | 手写 CUDA 库(cuDNN、cuBLAS) |
| 硬件覆盖 | NVIDIA GPU + x86 CPU | GPU + CPU + Mobile + FPGA + … | NVIDIA GPU only |
| 训练支持 | ✅ 原生支持 | ❌ 无 autograd 引擎 | ❌ 推理 only |
| 编译开销 | 秒-分钟(首次 JIT) | 分钟-小时(auto-tuning) | 分钟(builder 构建 engine) |
| NVIDIA GPU 推理峰值 | 接近 TensorRT(90-95%) | 接近 TensorRT(85-95%) | 🥇 最强(手写库 + 硬件专调) |
所以 TensorRT 是推理场景的"终极答案"——它用的是 NVIDIA 手写的 cuDNN/cuBLAS kernel,不是自动生成的。代价是:只支持 NVIDIA GPU、有限的算子覆盖、不碰训练。
torch.compile + Triton 是目前 PyTorch 训练加速的 唯一生产级方案。TVM 和 TensorRT 都不处理训练。# 当前你可能这样用:
model = torch.compile(model)
# 试试这样:
model = torch.compile(
model,
mode="max-autotune", # Triton 尝试多个 kernel 配置,选最快的
fullgraph=True, # 强制全图编译,报错说明有 graph break
)
Mode 对比:
| Mode | 编译时间 | 运行时速度 | 适用 |
|---|---|---|---|
"default" | 最快 | good | 开发调试 |
"reduce-overhead" | 快 | better | 小 batch、多用 CUDA Graphs 消除 launch overhead |
"max-autotune" | 慢(首次几分钟) | best | 大规模训练、静态 shape、跑得久值得等编译 |
这一课你只需要记住三个东西:
torch.compile 怎么调,不在要不要换 backend