缓存
缓存通过存储并复用不同层(如注意力层和前馈层)的中间输出,而非在每个推理步骤中执行完整计算,从而加速推理。它以占用更多内存为代价,显著提升生成速度,且无需额外训练。
本指南将向您展示如何使用 Diffusers 支持的缓存方法。
金字塔注意力广播
Pyramid Attention Broadcast (PAB)基于以下观察:在生成过程的连续时间步之间,注意力输出之间的差异并不大。交叉注意力层中的注意力差异最小,通常会在更长的时间步范围内进行缓存。随后是时间注意力层和空间注意力层。
并非所有视频模型都包含三种注意力机制(交叉注意力、时间注意力和空间注意力)!
PAB 可以与其他技术(如序列并行和 classifier-free guidance 并行(数据并行))结合使用,以实现近乎实时的视频生成。
设置并传递 PyramidAttentionBroadcastConfig 到流水线的 transformer 以启用该功能。spatial_attention_block_skip_range 用于控制空间注意力块中跳过注意力计算的频率,而 spatial_attention_timestep_skip_range 则是需要跳过的时间步范围。请注意选择合适的范围,因为较小的间隔可能导致推理速度变慢,而较大的间隔则可能降低生成质量。
import torch
from diffusers import CogVideoXPipeline, PyramidAttentionBroadcastConfig
pipeline = CogVideoXPipeline.from_pretrained("THUDM/CogVideoX-5b", dtype=torch.bfloat16)
pipeline.to("cuda") # or "mps", "xpu", "cpu"
config = PyramidAttentionBroadcastConfig(
spatial_attention_block_skip_range=2,
spatial_attention_timestep_skip_range=(100, 800),
current_timestep_callback=lambda: pipe.current_timestep,
)
pipeline.transformer.enable_cache(config)FasterCache
FasterCache 会缓存并复用注意力特征,其原理与 PAB 类似,因为相邻时间步之间的输出差异很小。
当使用无分类器引导进行采样时(这在大多数基础模型中很常见),该方法也可以选择跳过无条件分支预测,并在连续时间步的预测潜在输出之间存在显著冗余时,从条件分支预测中对其进行估计。
设置一个 FasterCacheConfig 并将其传递给 pipeline 的 transformer,以启用该功能。
import torch
from diffusers import CogVideoXPipeline, FasterCacheConfig
pipe line= CogVideoXPipeline.from_pretrained("THUDM/CogVideoX-5b", dtype=torch.bfloat16)
pipeline.to("cuda") # or "mps", "xpu", "cpu"
config = FasterCacheConfig(
spatial_attention_block_skip_range=2,
spatial_attention_timestep_skip_range=(-1, 681),
current_timestep_callback=lambda: pipe.current_timestep,
attention_weight_callback=lambda _: 0.3,
unconditional_batch_skip_range=5,
unconditional_batch_timestep_skip_range=(-1, 781),
tensor_format="BFCHW",
)
pipeline.transformer.enable_cache(config)SeaCache
SeaCache 在连续的降噪步骤之间比较 Spectral-Evolution-Aware (SEA) 指标。当累积的指标变化低于某个阈值时,它会跳过计算开销较大的 transformer block 堆栈,并利用缓存的残差来预测其输出。该指标由构成生成输出的视觉潜变量(visual latents)构建。如果干净的条件帧属于该输出轨迹的一部分(例如在图生视频和视生视频生成中),则应将其包含在内。应排除那些用于条件化生成但不属于输出的一部分的独立视觉提示。文本条件被排除在外,因为它不是视觉潜变量。
Cosmos 3 Transfer 将控制提示作为独立的视觉序列进行打包,因此其适配器会将它们从指示器中排除。 Control-CFG 分支在比较相同的输出轨迹时,会保留各自缓存的残差。控制提示仍然会对 transformer 进行条件约束。
该实现为以下模型提供了内置适配器:
- Cosmos 3 是主要经过优化和基准测试的集成方案。它通过 post-normalization 边界缓存完整的解码器堆栈。
- Wan T2V 在 eager 模式下使用通用的重复块路径。此集成展示了另一种单流视频 Transformer 如何向 SeaCache 提供原始视觉潜在变量;这并不意味着相同的缓存参数对 Wan 也是最优的,也不表示支持其他 Wan 变体。
其他视频 Transformer 在满足以下条件时,可以集成到通用路径中:使用 CacheMixin、暴露一个可识别的重复块列表,并在 TransformerBlockRegistry 中注册块的输入/输出布局。流水线必须在每次 Transformer 调用时进入 cache_context,附加 step_index、sigma 和 num_inference_steps,并为独立轨迹(例如条件引导和无条件引导)使用不同的上下文名称。当没有内置适配器时,请传入一个 raw_vision_callback,该回调返回构成生成输出的视觉潜在变量。请针对每个模型和调度器验证输出质量并调整缓存参数;对 Cosmos 3 的支持和基准测试结果不会自动迁移。
Cosmos 3
SeaCache 默认处于禁用状态。请在 transformer 上启用它;Cosmos 3 的去噪循环会将当前活跃的调度器步长、sigma 以及步数附加到每个 cache_context 调用中,因此无需进行额外的接线:
from diffusers import Cosmos3OmniPipeline, SeaCacheConfig
pipe = Cosmos3OmniPipeline.from_pretrained("nvidia/Cosmos3-Nano")
pipe.transformer.enable_cache(SeaCacheConfig(threshold=0.2, max_consecutive_cached=2))此模型级 API 适用于 Cosmos3OmniPipeline、Cosmos3OmniModularPipeline 和 Cosmos3DistilledModularPipeline。SeaCache 是一种近似优化,可能会改变生成的输出。当您需要每个去噪步骤都执行完整的 transformer 时,请调用 pipe.transformer.disable_cache()。
FirstBlockCache
FirstBlock Cache 会检查去噪器(denoiser)的早期层在相邻时间步之间的变化程度。如果变化较小,模型将跳过代价高昂的后续层,并复用之前的输出。
import torch
from diffusers import DiffusionPipeline
from diffusers.hooks import apply_first_block_cache, FirstBlockCacheConfig
pipeline = DiffusionPipeline.from_pretrained(
"Qwen/Qwen-Image", dtype=torch.bfloat16
)
apply_first_block_cache(pipeline.transformer, FirstBlockCacheConfig(threshold=0.2))TaylorSeer 缓存
TaylorSeer Cache 通过利用泰勒级数展开来近似并缓存去噪步骤之间的中间激活值,从而加速扩散推理。该方法基于过去的计算预测未来的输出,并在指定的间隔处复用这些结果,以减少冗余计算。
该缓存机制在极小的额外内存开销下即可取得显著效果。有关详细的性能分析,请参阅我们在此处的研究结果。
要启用 TaylorSeer Cache,请创建一个 TaylorSeerCacheConfig 并将其传递给您的 pipeline 中的 transformer:
cache_interval:在执行完整前向传播之前,复用缓存输出的步数disable_cache_before_step:初始步骤,使用完整计算来收集用于近似的数据max_order:近似精度(理论上,较高的值可以提高质量,但会增加内存使用量,我们建议将其设置为1)
import torch
from diffusers import FluxPipeline, TaylorSeerCacheConfig
pipe = FluxPipeline.from_pretrained(
"black-forest-labs/FLUX.1-dev",
dtype=torch.bfloat16,
).to("cuda") # or "mps", "xpu", "cpu"
config = TaylorSeerCacheConfig(
cache_interval=5,
max_order=1,
disable_cache_before_step=10,
taylor_factors_dtype=torch.bfloat16,
)
pipe.transformer.enable_cache(config)MagCache
MagCache 通过根据残差更新的幅度来跳过 Transformer 块,从而加速推理。它观察到,在扩散过程中,更新幅度(Output - Input)会可预测地衰减。通过基于预先计算的幅度比率累积“误差预算”,它动态地决定何时跳过计算并复用之前的残差。
MagCache 依赖于 幅度比率(mag_ratios),用于描述该衰减曲线。这些比率因模型检查点和调度器而异。内置的 FLUX_MAG_RATIOS 是在 FLUX.1 上测量得到的;其他模型(包括 Flux2 和 Flux2 Klein)需要各自进行校准运行。
要使用 MagCache,通常需遵循两步流程:校准和推理。
- 校准:使用
calibrate=True运行一次推理。该 hook 会测量残差幅度,并将计算出的比率打印到控制台。 - 推理:将这些比率传递给
MagCacheConfig以启用加速。
import torch
from diffusers import FluxPipeline, MagCacheConfig
pipe = FluxPipeline.from_pretrained(
"black-forest-labs/FLUX.1-schnell",
dtype=torch.bfloat16
).to("cuda") # or "mps", "xpu", "cpu"
# 1. Calibration Step
# Run full inference to measure model behavior.
calib_config = MagCacheConfig(calibrate=True, num_inference_steps=4)
pipe.transformer.enable_cache(calib_config)
# Run a prompt to trigger calibration
pipe("A cat playing chess", num_inference_steps=4)
# Logs will print something like: "MagCache Calibration Results: [1.0, 1.37, 0.97, 0.87]"
# 2. Inference Step
# Apply the specific ratios obtained from calibration for optimized speed.
# Note: For Flux models, you can also import defaults:
# from diffusers.hooks.mag_cache import FLUX_MAG_RATIOS
mag_config = MagCacheConfig(
mag_ratios=[1.0, 1.37, 0.97, 0.87],
num_inference_steps=4
)
pipe.transformer.enable_cache(mag_config)
image = pipe("A cat playing chess", num_inference_steps=4).images[0]
mag_ratios表示模型固有的幅度衰减曲线。针对较高步数(例如 50 步)校准的比率可复用于较低的步数(例如 20 步)。该实现使用插值将曲线映射到当前的推理步数。
对于按顺序执行 Classifier-Free Guidance 的流水线(例如 Kandinsky 5.0),校准日志可能会打印两个数组:一个用于 Conditional 通道,另一个用于 Unconditional 通道。在大多数情况下,应使用第一个数组(Conditional)。
Update on GitHub对于以批量方式运行 Classifier-Free Guidance 的流水线(例如 SDXL 或 Flux),模型处理的
hidden_states包含拼接在一起的有条件分支和无条件分支。校准过程会自动处理这一点,生成一个表示联合行为的比率数组。您可以直接使用该生成的数组,无需任何修改。