- 人工智能
- 深度学习
- 分布式训练
【免费下载链接】accelerate
🚀 A simple way to launch, train, and use PyTorch models on almost any device and distributed configuration, automatic mixed precision (including fp8), and easy-to-configure FSDP and DeepSpeed support
本指南系统讲解如何在 Accelerate 分布式训练工作流中接入 PyTorch 2.0 的torch.compile:先介绍TorchDynamoPlugin的完整配置方式与底层实现,再深入区域编译(Regional Compilation)原理,并结合仓库内基准测试与源码佐证,帮助你掌握"既享受编译加速、又显著压低 LLM 类模型首次编译冷启动时间"的实战方案。
一、为什么要在 Accelerate 中使用 torch.compile
PyTorch 2.0 引入了torch.compile,它通过 JIT 将 PyTorch 代码编译为优化后的内核,从而显著加速模型执行。其核心特性可概括为三点:
- 性能提升(Performance Improvement):优化计算图,显著加快模型执行速度;
- 易于使用(Ease of Use):对既有代码改动极小,接入成本低;
- 兼容性强(Compatibility):与现有 PyTorch 代码和模型无缝协作。
当与 Accelerate 配合使用时,torch.compile会平滑地融入分布式训练流程,使你在同一套代码中同时获得分布式执行与编译优化的收益。需要说明的是,编译后的代码首次执行通常更慢(其中包含编译耗时),而后续运行会明显加快。为此torch.compile提供了多种编译模式(mode):"default"(默认)、"reduce-overhead"(利用 CUDA graphs 进一步压低调度开销)以及"max-autotune"(大规模自动调优,为模型寻找最佳内核)。
二、TorchDynamoPlugin:一行配置接入编译
Accelerate 通过TorchDynamoPlugin提供对torch.compile的无缝集成。其定义位于 src/accelerate/utils/dataclasses.py,继承自KwargsHandler,会在模型预处理阶段把编译参数透传给torch.compile。
2.1 最小可用示例
from accelerate import Accelerator from accelerate.utils import TorchDynamoPlugin # 配置编译后端 dynamo_plugin = TorchDynamoPlugin( backend="inductor", # 可选:"inductor"、"aot_eager"、"aot_nvfuser" 等 mode="default", # 可选:"default"、"reduce-overhead"、"max-autotune" fullgraph=True, dynamic=False, ) # 使用插件初始化 accelerator accelerator = Accelerator(dynamo_plugin=dynamo_plugin) # 这一步会对模型应用 torch.compile model = accelerator.prepare(model)该插件与 Accelerate 的所有其他特性与插件兼容,包括混合精度、分布式训练(DDP、FSDP、DeepSpeed)等。其兼容性在源码中得到印证:Accelerator.prepare的常规路径(src/accelerate/accelerator.py)、FSDP2 路径(src/accelerate/accelerator.py)以及 DeepSpeed 路径(src/accelerate/accelerator.py)中均按各自方式触发编译。
2.2 完整参数说明(取自源码字段定义)
下表整理了 TorchDynamoPlugin 的全部可配置字段:
| 参数 | 默认值 | 含义 |
|---|---|---|
backend | None(回退到环境变量,再回退"no") | Dynamo 编译后端,取值见下方DynamoBackend枚举 |
mode | None(回退环境变量,再回退"default") | 编译模式:"default"、"reduce-overhead"或"max-autotune" |
fullgraph | None(回退环境变量,再回退False) | 是否允许将模型拆分为多个子图;True表示要求完整图 |
dynamic | None(仅当设置了对应环境变量时生效) | 是否使用动态 shape 进行 tracing |
options | None | 传给后端的一本参数字典 |
disable | False | 将torch.compile()变成 no-op,便于测试 |
use_regional_compilation | None(回退环境变量,再回退False) | 是否启用区域编译,见本文第三节 |
其中backend的取值对应DynamoBackend枚举(src/accelerate/utils/dataclasses.py),包括:
- NO:不使用 torch dynamo;
- EAGER:用 PyTorch 直接运行提取出的 GraphModule,适合调试 TorchDynamo 问题;
- AOT_EAGER:仅使用 AotAutograd 而无编译器,适合调试,通常不会有加速;
- INDUCTOR:默认推荐后端,基于 AotAutograd、CUDA graphs 与 codegen 出的 Triton 内核,是获取明显加速的主流选择;
- AOT_TS_NVFUSER / NVPRIMS_NVFUSER:nvFuser 与 AotAutograd/TorchScript 或 PrimTorch 组合;
- CUDAGRAPHS:cudagraphs 配合 AotAutograd;
- OFI / FX2TRT / ONNXRT / TENSORRT / TVM:面向推理优化的后端(TensorRT、ONNX Runtime、TVM 等);
- AOT_TORCHXLA_TRACE_ONCE / TORCHXLA_TRACE_ONCE:PyTorch/XLA 的 Dynamo 优化,分别面向训练与推理;
- HPU_BACKEND / NEURON:Habana HPU 与 AWS Neuron(Trainium/Inferentia)后端。
注意:
backend="no"时prepare不会触发任何编译;DynamoBackend在内部通过.upper()归一化,因此大小写不敏感。
2.3 环境变量配置方式
TorchDynamoPlugin.__post_init__(src/accelerate/utils/dataclasses.py)显示,所有参数都支持通过ACCELERATE_DYNAMO_前缀的环境变量覆盖,便于在不改代码的情况下切换配置:
| 环境变量 | 默认值 |
|---|---|
ACCELERATE_DYNAMO_BACKEND | "no" |
ACCELERATE_DYNAMO_MODE | "default" |
ACCELERATE_DYNAMO_USE_FULLGRAPH | "False" |
ACCELERATE_DYNAMO_USE_DYNAMIC | 未设置时不启用 |
ACCELERATE_DYNAMO_USE_REGIONAL_COMPILATION | "False" |
例如:
export ACCELERATE_DYNAMO_BACKEND=inductor export ACCELERATE_DYNAMO_MODE=reduce-overhead export ACCELERATE_DYNAMO_USE_REGIONAL_COMPILATION=True随后直接Accelerator()即可生效。相关配置项同样可以在accelerate config生成的 YAML 或accelerate launch命令行参数(如--dynamo_backend、--dynamo_mode)中指定,CLI 侧校验逻辑可参考 src/accelerate/commands/launch.py 与 src/accelerate/commands/config/cluster.py。
三、区域编译(Regional Compilation):解决 LLM 冷启动痛点
3.1 为什么要"分区域"编译
对整个模型做torch.compile,其优化问题空间通常非常巨大,导致编译(冷启动)时间很长。区域编译的思路是:不再整体编译整个模型,而是定位模型中重复的同构 block,逐个依次编译以命中编译器的缓存。
以GPT2LMHeadModel为例,重复块/类是GPT2Block,可通过model.transformer.h[0]访问;模型的其余部分(如model.lm_head)则单独编译。这种策略能显著加快 LLM 和 Transformer 类模型的编译开销/冷启动时间(该方法源自 PyTorch 官方文档中介绍的 regional compilation 配方)。
3.2 源码级原理:compile_regions 如何工作
compile_regions的实现位于 src/accelerate/utils/other.py。它通过两个辅助函数识别"重复块":
is_repeated_blocks(module)(other.py):判断一个模块是否是torch.nn.ModuleList且所有子模块为同一类;has_repeated_blocks(module)(other.py):在模块层级树的任意位置递归查找是否存在上述重复块。
核心递归逻辑_compile_regions分三种情况处理:
- 命中重复块(
is_repeated_blocks为真):新建ModuleList,对每个同构子模块逐一执行torch.compile(submodule, **compile_kwargs)。由于同构 block 依次编译会命中编译器缓存,后续 block 的编译大幅提速; - 包含重复块但本身不是(
has_repeated_blocks为真):按类重建模块外壳、绑定方法并递归处理子模块,仅对包含重复块的子层下钻; - 叶子节点:直接
torch.compile(module, **compile_kwargs)。
编译完成后,若顶层没有_orig_mod引用,则会把原始模型挂到new_module.__dict__["_orig_mod"]上,以便后续解包(decompile/unwrap)。
从测试 tests/test_compile.py 可以看到该行为的直接验证:
compiled_model = compile_regions(model, mode="reduce-overhead", backend=backend) # 编译后的模型保留对原始模型的引用 assert hasattr(compiled_model, "_orig_mod") # transformer.h[i] 与 lm_head 分别被编译 assert isinstance(compiled_model.transformer.h[0], torch._dynamo.eval_frame.OptimizedModule) assert isinstance(compiled_model.lm_head, torch._dynamo.eval_frame.OptimizedModule)此外 tests/test_compile.py 中的test_regional_compilation_cold_start直接断言了"区域编译的冷启动时间小于整体编译"这一核心结论。
3.3 如何在 Accelerate 中开启区域编译
通过TorchDynamoPlugin的use_regional_compilation=True开启:
# 配置编译后端 dynamo_plugin = TorchDynamoPlugin( use_regional_compilation=True, ... # 其他参数,如 backend、mode ) # 使用插件初始化 accelerator accelerator = Accelerator(dynamo_plugin=dynamo_plugin) # 这一步会对模型应用 compile_regions model = accelerator.prepare(model)在Accelerator.prepare中,当use_regional_compilation为真时,常规分布式路径调用compile_regions(model, **dynamo_plugin.to_kwargs())(accelerator.py)。值得注意的细节是TorchDynamoPlugin.to_kwargs()(dataclasses.py)会把use_regional_compilation从透传给torch.compile的关键字参数中剔除,保证该开关只由 Accelerate 消费、不会传给 PyTorch。
3.4 直接使用 compile_regions 工具函数
你也可以脱离Accelerator,像使用torch.compile一样直接调用accelerate.utils.compile_regions:
from accelerate.utils import compile_regions from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("gpt2") compiled_model = compile_regions(model, mode="reduce-overhead") # compiled_model.transformer.h[0] 现在是 OptimizedModule, # 内部 (_orig_mod) 仍是原始 GPT2Block,其余部分单独编译其 docstring 示例(other.py)展示了编译后compiled_model.transformer.h[0]成为OptimizedModule、内部保留原始GPT2Block结构的结果。
3.5 DeepSpeed 与 FSDP2 场景下的专用变体
由于不同分布式封装对torch.compile的敏感度不同,仓库额外提供了两个变体:
compile_regions_deepspeed(other.py):针对DeepSpeedEngine.module。因为模型被DeepSpeedEngine包裹并挂载了大量 hooks、参数 offload 等,直接torch.compile(...)会干扰这些机制,因此改用原地的module.compile()方法逐块编译。在 accelerator.py 中,当 DeepSpeed 版本满足条件且开启了编译与区域编译时会被调用;compile_regions_fsdp2(other.py):与compile_regions类似,但同样使用原地的module.compile()。其必要性在于:torch.compile(module)返回的OptimizedModule的__call__会绕过nn.Module._call_impl,导致之后由fully_shard添加的 forward/pre hooks 不再触发、逐层 all-gather/reshard 失效;而原地的module.compile()保留_call_impl调用路径,使 FSDP2 hooks 依然生效。该行为由 tests/fsdp/test_fsdp.py 的test_compile_regions_fsdp2_preserves_block_class测试覆盖(验证isinstance检查通过,block 类被保留)。
在 FSDP2 路径中,开启区域编译时还会额外设置两个torch._dynamo.config开关(accelerator.py):capture_scalar_outputs = True与skip_fwd_side_effects_in_bwd_under_checkpoint = True,以匹配 per-block 编译配方,适应 MoE token-choice 分派的动态 shape,并保持激活检查点(AC)+ 编译边界的一致性。
四、完整训练示例
将上述要素组合成一个可运行的训练片段:
import torch from torch.utils.data import DataLoader from accelerate import Accelerator from accelerate.utils import TorchDynamoPlugin dynamo_plugin = TorchDynamoPlugin( backend="inductor", mode="reduce-overhead", # 利用 CUDA graphs 压低调度开销 use_regional_compilation=True, # 针对重复 block 分区域编译 ) accelerator = Accelerator(dynamo_plugin=dynamo_plugin) model, optimizer, train_dataloader = accelerator.prepare( model, optimizer, train_dataloader ) for step, batch in enumerate(train_dataloader): with accelerator.accumulate(model): outputs = model(**batch) loss = outputs.loss accelerator.backward(loss) optimizer.step() optimizer.zero_grad()首次进入训练循环时,模型会按区域依次编译;从源码路径看,编译发生在prepare阶段(accelerator.py),而实际触发 JIT 编译则是在第一次前向推理时。若后续需要解包编译后的模型(例如保存权重),可使用accelerator.unwrap_model(model, keep_torch_compile=False),其底层通过 extract_model_from_parallel 配合_orig_mod引用还原原始模型——has_compiled_regions与is_compiled_module(other.py)正是用于判断模型是否带有编译包装。
五、基准测试:区域编译 vs 整体编译
仓库在 benchmarks/torch.compile/README.md 中给出了系统性对比实验,基准脚本为 benchmarks/torch.compile/regional_compilation.py。实验设计要点如下:
- 对比三种方案:Baseline(不编译,纯 eager 执行)、Full compilation(
torch.compile()整体编译)、Regional compilation(accelerate.utils.compile_regions()); - 测试模型为 1B~13B 参数的 LLaMA 系列因果语言模型(如 Llama-3.2-1B、3B、8B 与 13B 级模型);
- 分别在 batch size 1 与 4、序列长度 128 下测量编译时间(
COMPILE_ITERS = 2次取中位数,语句中会先重置 dynamo 并清空 inductor 缓存)与推理时间(INFERENCE_ITERS = 100次); - 刻意在
torch.no_grad()上下文之外运行前向,以模拟训练环境(需要梯度)下的真实表现。
运行方式:
python regional_compilation.py脚本会自动下载模型配置、构建模型,并输出基于torch.utils.benchmark的横向对比表(含 colorize 高亮)。
关键结论
- 性能相当:区域编译的加速效果与整体编译接近,对更大规模模型尤其如此;
- 编译更快:区域编译显著缩短模型编译耗时,对部署场景更友好;
- batch size 的影响:随着 batch size 增大,两种编译策略的性能差距缩小,说明编译开销在大 batch 场景下的占比更低;
- 模型规模考量:模型越大,区域编译在编译时间上的节省越可观;
- 实践价值:对真实应用而言,区域编译是优化训练冷启动时间的务实选择,尤其适合大模型场景。
需要说明的是,上述结论来自仓库内部基准脚本的设计与文档描述,具体数值会随硬件、PyTorch 版本与模型结构而变化,建议在自身环境上运行 regional_compilation.py 复现验证。此外该仓库还有一个相关的区域编译示例 benchmarks/torch.compile/regional_compilation.py 及其配套图片目录 benchmarks/torch.compile/imgs,可供深入分析。
六、结论
整体编译(Full Compilation)与区域编译(Regional Compilation)都能显著加速模型执行,而区域编译在编译时间与运行时性能之间提供了更务实的平衡,尤其适合"大模型 + 较大 batch size"的训练冷启动优化。实践中:
- 追求最大推理/训练吞吐,可选用
backend="inductor", mode="reduce-overhead"或"max-autotune"; - 追求更快的首次编译与部署体验,建议叠加
use_regional_compilation=True; - 使用 DeepSpeed 或 FSDP2 时,Accelerate 已内置对应的区域编译变体,无需手工处理 wrapper 带来的 hook 兼容问题;
- 所有参数均可通过
ACCELERATE_DYNAMO_*环境变量无侵入切换,便于在 CI 或多机环境中灵活调整。
- 人工智能
- 深度学习
- 分布式训练
【免费下载链接】accelerate
🚀 A simple way to launch, train, and use PyTorch models on almost any device and distributed configuration, automatic mixed precision (including fp8), and easy-to-configure FSDP and DeepSpeed support
相关推荐
CopilotKit Tool Rendering 实战:用 useRenderTool 把后端工具调用渲染成聊天内的 React 卡片
CopilotKit Tool Rendering 实战:用 useRenderTool 把后端工具调用渲染成聊天内的 React 卡片 本篇基于 Copilo
人工智能深度学习分布式训练vLLM-Omni 区域编译(Regional Compilation)实践指南:配置、动态形状与 MiniMax-H3 固定 packed shape 优化
vLLM Omni 区域编译(Regional Compilation)实践指南:配置、动态形状与 MiniMax H3 固定 packed shape 优化
人工智能大模型模型推理服务多模态语音音频媒体生成本地部署PyTorch torch.compile 编译时间优化实战:从避免重编译到嵌套编译区域
PyTorch torch.compile 编译时间优化实战:从避免重编译到嵌套编译区域 torch.compile 是一个即时编译器(JIT),首次调用编译后
人工智能机器学习深度学习分布式训练模型编译
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考