Buckets:
| # 加速推理 | |
| 扩散模型在推理阶段速度较慢,因为生成是一个迭代过程,需要在若干“步”中逐步将噪声细化为图像或视频。为了加速这一过程,您可以尝试使用不同的 [调度器](../api/schedulers/overview)、降低模型权重的精度以加快计算、采用更节省显存的注意力机制等。 | |
| 将这些技术组合使用,可以实现比单独使用任何一项技术更快的推理速度。 | |
| 本指南将介绍如何加速推理。 | |
| ## 模型数据类型 | |
| 模型权重的精度和数据类型会影响推理速度,因为更高的精度需要更多的内存来加载,并且需要更多的时间来进行计算。PyTorch 默认以 float32 或全精度加载模型权重,因此更改数据类型是一种快速提升推理速度的简单方法。 | |
| bfloat16 与 float16 类似,但对数值误差的鲁棒性更强。bfloat16 的硬件支持情况因设备而异,但大多数现代 GPU 均支持 bfloat16。 | |
| ```py | |
| import torch | |
| from diffusers import StableDiffusionXLPipeline | |
| pipeline = StableDiffusionXLPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.bfloat16 | |
| ).to("cuda") # or "mps", "xpu", "cpu" | |
| prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" | |
| pipeline(prompt, num_inference_steps=30).images[0] | |
| ``` | |
| float16 与 bfloat16 类似,但更容易出现数值误差。 | |
| ```py | |
| import torch | |
| from diffusers import StableDiffusionXLPipeline | |
| pipeline = StableDiffusionXLPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.float16 | |
| ).to("cuda") # or "mps", "xpu", "cpu" | |
| prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" | |
| pipeline(prompt, num_inference_steps=30).images[0] | |
| ``` | |
| [TensorFloat-32 (tf32)](https://blogs.nvidia.com/blog/2020/05/14/tensorfloat-32-precision-format/) 模式在 NVIDIA Ampere GPU 上受支持,它使用 tf32 执行卷积和矩阵乘法运算。存储和其他操作仍保持为 float32。与 bfloat16 或 float16 结合使用时,可显著提升计算速度。 | |
| PyTorch 默认仅对卷积启用 tf32 模式,你需要显式地为矩阵乘法启用该模式。 | |
| ```py | |
| import torch | |
| from diffusers import StableDiffusionXLPipeline | |
| torch.backends.cuda.matmul.allow_tf32 = True | |
| pipeline = StableDiffusionXLPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.bfloat16 | |
| ).to("cuda") # or "mps", "xpu", "cpu" | |
| prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" | |
| pipeline(prompt, num_inference_steps=30).images[0] | |
| ``` | |
| 有关更多详细信息,请参阅[混合精度训练](https://huggingface.co/docs/transformers/en/perf_train_gpu_one#mixed-precision)文档。 | |
| ## 缩放点积注意力 | |
| > [!TIP] | |
| > 内存高效注意力机制针对推理速度 *和* [内存占用](./memory#memory-efficient-attention) 进行了优化! | |
| [缩放点积注意力(SDPA)](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html)实现了多种注意力后端,包括 [FlashAttention](https://github.com/Dao-AILab/flash-attention)、[xFormers](https://github.com/facebookresearch/xformers) 以及原生 C++ 实现。它会自动为您的硬件选择最优的后端。 | |
| 如果您使用的是 PyTorch >= 2.0,SDPA 默认已启用,且无需对代码进行任何额外更改。不过,如果您希望自行选择,可以尝试使用其他 attention 后端。下面的示例使用 [torch.nn.attention.sdpa_kernel](https://pytorch.org/docs/stable/generated/torch.nn.attention.sdpa_kernel.html) 上下文管理器来启用高效的 attention。 | |
| ```py | |
| from torch.nn.attention import SDPBackend, sdpa_kernel | |
| import torch | |
| from diffusers import StableDiffusionXLPipeline | |
| pipeline = StableDiffusionXLPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.bfloat16 | |
| ).to("cuda") # or "mps", "xpu", "cpu" | |
| prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" | |
| with sdpa_kernel(SDPBackend.EFFICIENT_ATTENTION): | |
| image = pipeline(prompt, num_inference_steps=30).images[0] | |
| ``` | |
| ## torch.compile | |
| [torch.compile](https://pytorch.org/tutorials/intermediate/torch_compile_tutorial.html) 通过将 PyTorch 代码和运算编译为优化后的内核来加速推理。Diffusers 通常会对计算量较大的模型(如 UNet、transformer 或 VAE)进行编译。 | |
| 启用以下编译器设置以获得最大速度(有关更多选项,请参阅[完整列表](https://github.com/pytorch/pytorch/blob/main/torch/_inductor/config.py))。 | |
| ```py | |
| import torch | |
| from diffusers import StableDiffusionXLPipeline | |
| torch._inductor.config.conv_1x1_as_mm = True | |
| torch._inductor.config.coordinate_descent_tuning = True | |
| torch._inductor.config.epilogue_fusion = False | |
| torch._inductor.config.coordinate_descent_check_all_directions = True | |
| ``` | |
| 加载并编译 UNet 和 VAE。您可以从多种不同的模式中进行选择,其中 `"max-autotune"` 通过编译为 CUDA graph 来优化至最快速度。CUDA graph 通过单次 CPU 操作启动多个 GPU 操作,从而有效降低开销。 | |
| > [!TIP] | |
| > 在 PyTorch 2.3.1 中,您可以控制 torch.compile 的缓存行为。这对于 `"max-autotune"` 等编译模式尤其有益,该模式会对多个编译标志执行网格搜索,以找到最优配置。有关详细信息,请参阅 [torch.compile 中的编译时缓存](https://pytorch.org/tutorials/recipes/torch_compile_caching_tutorial.html) 教程。 | |
| 将内存布局更改为 [channels_last](./memory#torchchannelslast) 还可以优化内存和推理速度。 | |
| ```py | |
| pipeline = StableDiffusionXLPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.float16 | |
| ).to("cuda") # or "mps", "xpu", "cpu" | |
| pipeline.unet.to(memory_format=torch.channels_last) | |
| pipeline.vae.to(memory_format=torch.channels_last) | |
| pipeline.unet = torch.compile( | |
| pipeline.unet, mode="max-autotune", fullgraph=True | |
| ) | |
| pipeline.vae.decode = torch.compile( | |
| pipeline.vae.decode, | |
| mode="max-autotune", | |
| fullgraph=True | |
| ) | |
| prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" | |
| pipeline(prompt, num_inference_steps=30).images[0] | |
| ``` | |
| 首次编译速度较慢,但编译完成后速度会显著提升。请尽量仅将编译后的 pipeline 用于同一类型的推理操作。如果对不同的图像尺寸调用编译后的 pipeline,会重新触发编译,这既缓慢又低效。 | |
| ### 动态形状编译 | |
| > [!TIP] | |
| > 请务必始终使用 PyTorch 的 nightly 版本,以获得更好的支持。 | |
| `torch.compile` 会跟踪输入的形状和条件,如果这些条件发生变化,它会重新编译模型。例如,如果模型是在 1024x1024 分辨率的图像上编译的,而随后用于不同分辨率的图像,则会触发重新编译。 | |
| 为避免重新编译,请添加 `dynamic=True`,以尝试生成更具动态性的内核,从而在条件变化时避免重新编译。 | |
| ```diff | |
| + torch.fx.experimental._config.use_duck_shape = False | |
| + pipeline.unet = torch.compile( | |
| pipeline.unet, fullgraph=True, dynamic=True | |
| ) | |
| ``` | |
| 指定 `use_duck_shape=False` 可指示编译器是否应使用相同的符号变量来表示大小相同的输入。有关更多详细信息,请参阅此 [评论](https://github.com/huggingface/diffusers/pull/11327#discussion_r2047659790)。 | |
| 并非所有模型都能开箱即用地从动态编译中获益,可能需要对其进行修改。请参阅此 [PR](https://github.com/huggingface/diffusers/pull/11297/),该 PR 改进了 [AuraFlowPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/aura_flow#diffusers.AuraFlowPipeline) 的实现,使其能够受益于动态编译。 | |
| 如果动态编译在 Diffusers 模型上未按预期工作,请随时提交 issue。 | |
| ### 区域编译 | |
| [区域编译](https://docs.pytorch.org/tutorials/recipes/regional_compilation.html)通过仅编译模型中*较小且频繁重复的块*(通常是 Transformer 层)来降低冷启动延迟,并允许在后续每次出现时复用编译产物。对于许多扩散架构而言,这能提供与全图编译相同的运行时加速效果,并将编译时间缩短 8 到 10 倍。 | |
| 使用 [compile_repeated_blocks()](/docs/diffusers/v0.43.0/zh/api/models/overview#diffusers.ModelMixin.compile_repeated_blocks) 方法(一个封装了 `torch.compile` 的辅助函数)对诸如 transformer 模型等任意组件进行编译,如下所示。 | |
| ```py | |
| # pip install -U diffusers | |
| import torch | |
| from diffusers import StableDiffusionXLPipeline | |
| pipeline = StableDiffusionXLPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", | |
| dtype=torch.float16, | |
| ).to("cuda") # or "mps", "xpu", "cpu" | |
| # compile only the repeated transformer layers inside the UNet | |
| pipeline.unet.compile_repeated_blocks(fullgraph=True) | |
| ``` | |
| 要为新模型启用区域编译,请在模型类中添加一个 `_repeated_blocks` 属性,其中包含要编译的块的类名(以字符串形式)。 | |
| ```py | |
| class MyUNet(ModelMixin): | |
| _repeated_blocks = ("Transformer2DModel",) # ← compiled by default | |
| ``` | |
| > [!TIP] | |
| > 有关更多区域编译示例,请参阅参考 [PR](https://github.com/huggingface/diffusers/pull/11705)。 | |
| [Accelerate](https://huggingface.co/docs/accelerate/index) 中还提供了一个 [compile_regions](https://github.com/huggingface/accelerate/blob/273799c85d849a1954a4f2e65767216eb37fa089/src/accelerate/utils/other.py#L78) 方法,用于自动选择模型中需要编译的候选块。剩余的图会被单独编译。由于无需手动设置要编译的块或调整编译标志,该方法非常适合快速实验。 | |
| ```py | |
| # pip install -U accelerate | |
| import torch | |
| from diffusers import StableDiffusionXLPipeline | |
| from accelerate.utils import compile_regions | |
| pipeline = StableDiffusionXLPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.float16 | |
| ).to("cuda") # or "mps", "xpu", "cpu" | |
| pipeline.unet = compile_regions(pipeline.unet, mode="reduce-overhead", fullgraph=True) | |
| ``` | |
| [compile_repeated_blocks()](/docs/diffusers/v0.43.0/zh/api/models/overview#diffusers.ModelMixin.compile_repeated_blocks) 的设计是刻意保持显式的。在 `_repeated_blocks` 中列出需要重复的块,该辅助函数只会编译这些块。它通过一行代码即可提供可预测的行为,并便于推理缓存的复用。 | |
| ### 图断点 | |
| 在 torch.compile 中指定 `fullgraph=True` 非常重要,以确保底层模型中不存在图中断。这样,您就可以充分利用 torch.compile,而不会导致任何性能下降。对于 UNet 和 VAE,这会改变您访问返回变量的方式。 | |
| ```diff | |
| - latents = unet( | |
| - latents, timestep=timestep, encoder_hidden_states=prompt_embeds | |
| -).sample | |
| + latents = unet( | |
| + latents, timestep=timestep, encoder_hidden_states=prompt_embeds, return_dict=False | |
| +)[0] | |
| ``` | |
| ### GPU 同步 | |
| `step()` 函数会在去噪器每次做出预测后被[调用](https://github.com/huggingface/diffusers/blob/1d686bac8146037e97f3fd8c56e4063230f71751/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl.py#L1228),并且会对 `sigmas` 变量进行[索引](https://github.com/huggingface/diffusers/blob/1d686bac8146037e97f3fd8c56e4063230f71751/src/diffusers/schedulers/scheduling_euler_discrete.py#L476)。当将其放置在 GPU 上时,由于 CPU 与 GPU 之间的通信同步,会引入延迟。当去噪器已经被编译后,这一现象会更加明显。 | |
| 通常,`sigmas` 应[保留在 CPU 上](https://github.com/huggingface/diffusers/blob/35a969d297cba69110d175ee79c59312b9f49e1e/src/diffusers/schedulers/scheduling_euler_discrete.py#L240),以避免通信同步和延迟。 | |
| > [!TIP] | |
| > 请参阅 [torch.compile 与 Diffusers:性能巅峰实战指南](https://pytorch.org/blog/torch-compile-and-diffusers-a-hands-on-guide-to-peak-performance/) 博客文章,了解如何使用 `torch.compile` 最大化扩散模型的性能。 | |
| ### 基准测试 | |
| 请参阅 [diffusers/benchmarks](https://huggingface.co/datasets/diffusers/benchmarks) 数据集,查看编译后流水线的推理延迟和内存使用数据。 | |
| [diffusers-torchao](https://github.com/sayakpaul/diffusers-torchao#benchmarking-results) 仓库还包含 Flux 和 CogVideoX 编译版本的基准测试结果。 | |
| ## 内核 | |
| [Kernels](https://huggingface.co/docs/kernels/index) 是一个用于构建、分发和加载 [Hub](https://huggingface.co/kernels-community) 上优化计算内核的库。它支持 [attention](./attention_backends#setattentionbackend) 内核以及用于 RMSNorm、GEGLU、RoPE 和 AdaLN 等操作的自定义 CUDA 内核。 | |
| [Diffusers Pipeline Integration](https://github.com/huggingface/kernels/blob/main/kernel-builder/skills/cuda-kernels/references/diffusers-integration.md) 指南展示了如何将内核与 [add cuda-kernels](https://github.com/huggingface/kernels/blob/main/kernel-builder/skills/cuda-kernels/SKILL.md) 技能进行集成。该技能可让 Claude 或 Codex 等智能体针对特定模型和您的硬件编写自定义内核。 | |
| > [!TIP] | |
| > 安装 [add cuda-kernels](https://github.com/huggingface/kernels/blob/main/kernel-builder/skills/cuda-kernels/SKILL.md) 技能,以教会智能体如何编写内核。[Codex 和 Claude 的通用自定义内核](https://huggingface.co/blog/custom-cuda-kernels-agent-skills) 博客文章对此进行了更详细的介绍。 | |
| 例如,一个自定义的 RMSNorm 内核(由 `add cuda-kernels` 技能生成)配合 [torch.compile](#torchcompile) 使用,可在 H100 上将 LTX-Video 的生成速度提升 1.43 倍。 | |
| <iframe src="https://huggingface.co/datasets/docs-benchmarks/kernel-ltx-video/embed/viewer/default/train" frameborder="0" width="100%" height="560px" | |
| > | |
| ## 动态量化 | |
| [动态量化](https://docs.pytorch.org/ao/main/api_reference/generated/torchao.quantization.Int8DynamicActivationInt8WeightConfig.html)通过降低精度以执行更快的数学运算,从而提升推理速度。这种量化方式在运行时根据数据动态确定激活值的缩放方式,而不是使用固定的缩放因子。因此,缩放因子能够更精确地与数据对齐。 | |
| 以下示例使用 [torchao](../quantization/torchao) 库对 UNet 和 VAE 应用 [动态 int8 量化](https://docs.pytorch.org/ao/main/api_reference/generated/torchao.quantization.Int8DynamicActivationInt8WeightConfig.html)。 | |
| > [!TIP] | |
| > 请参阅我们的 [torchao](../quantization/torchao) 文档,以了解如何使用 Diffusers 的 torchao 集成。 | |
| 配置编译器标签以实现最大速度。 | |
| ```py | |
| import torch | |
| from torchao import apply_dynamic_quant | |
| from diffusers import StableDiffusionXLPipeline | |
| torch._inductor.config.conv_1x1_as_mm = True | |
| torch._inductor.config.coordinate_descent_tuning = True | |
| torch._inductor.config.epilogue_fusion = False | |
| torch._inductor.config.coordinate_descent_check_all_directions = True | |
| torch._inductor.config.force_fuse_int_mm_with_mul = True | |
| torch._inductor.config.use_mixed_mm = True | |
| ``` | |
| 使用 [dynamic_quant_filter_fn](https://github.com/huggingface/diffusion-fast/blob/0f169640b1db106fe6a479f78c1ed3bfaeba3386/utils/pipeline_utils.py#L16) 过滤掉 UNet 和 VAE 中那些无法从动态量化中获益的部分线性层。 | |
| ```py | |
| pipeline = StableDiffusionXLPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.bfloat16 | |
| ).to("cuda") # or "mps", "xpu", "cpu" | |
| apply_dynamic_quant(pipeline.unet, dynamic_quant_filter_fn) | |
| apply_dynamic_quant(pipeline.vae, dynamic_quant_filter_fn) | |
| prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" | |
| pipeline(prompt, num_inference_steps=30).images[0] | |
| ``` | |
| ## 融合投影矩阵 | |
| > [!WARNING] | |
| > [fuse_qkv_projections](https://github.com/huggingface/diffusers/blob/58431f102cf39c3c8a569f32d71b2ea8caa461e1/src/diffusers/pipelines/pipeline_utils.py#L2034) 方法目前处于实验阶段,其支持范围主要限于 Stable Diffusion 流水线。有关如何为其他流水线启用该功能的更多信息,请参阅此 [PR](https://github.com/huggingface/diffusers/pull/6179)。 | |
| 在注意力块中,输入被投影到三个子空间,分别由投影矩阵 Q、K 和 V 表示。这些投影通常分别计算,但你可以将它们水平合并为一个矩阵,从而在单步中完成投影。这会增加输入投影矩阵乘法的规模,同时提升量化的效果。 | |
| ```py | |
| pipeline.fuse_qkv_projections() | |
| ``` | |
| ## 资源 | |
| - 阅读 [Presenting Flux Fast: Making Flux go brrr on H100s](https://pytorch.org/blog/presenting-flux-fast-making-flux-go-brrr-on-h100s/) 博客文章,了解如何将上述所有优化与 [TorchInductor](https://docs.pytorch.org/docs/stable/torch.compiler.html) 和 [AOTInductor](https://docs.pytorch.org/docs/stable/torch.compiler_aot_inductor.html) 结合使用,利用 [flux-fast](https://github.com/huggingface/flux-fast) 中的方法实现约 2.5 倍的加速。 | |
| 这些配方支持 AMD 硬件和 [Flux.1 Kontext Dev](https://huggingface.co/black-forest-labs/FLUX.1-Kontext-dev)。 | |
| - 阅读 [torch.compile 与 Diffusers:实现峰值性能的实战指南](https://pytorch.org/blog/torch-compile-and-diffusers-a-hands-on-guide-to-peak-performance/) 博客文章 | |
| 在使用 `torch.compile` 时最大化性能。 | |
Xet Storage Details
- Size:
- 17.3 kB
- Xet hash:
- 8c48ca056e05039303a7429fd39901127375d7fc6d3c440571eecf72be8ab556
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.