From cd6e58c52d56c955c4f6657d943d8324d5040971 Mon Sep 17 00:00:00 2001 From: Alexander Eichhorn Date: Sat, 3 Oct 2026 21:55:16 +0200 Subject: [PATCH 1/2] feat(wan): run Wan 2.2 attention on SageAttention when enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With `attention_backend: sage`, Wan 2.2 image and video denoising enter the SageAttention scope. RTX 4090, Wan 2.2 TI2V-5B GGUF Q8 at 1280×704, 121 frames: 380.9 s → 247.9 s, peak VRAM unchanged, no added flicker. --- .../content/docs/configuration/Optimization/sage-attention.mdx | 1 + invokeai/app/invocations/wan/wan_denoise.py | 2 ++ invokeai/app/invocations/wan/wan_video_denoise.py | 2 ++ 3 files changed, 5 insertions(+) diff --git a/docs/src/content/docs/configuration/Optimization/sage-attention.mdx b/docs/src/content/docs/configuration/Optimization/sage-attention.mdx index 7b21d964d13..6c1d3201c2e 100644 --- a/docs/src/content/docs/configuration/Optimization/sage-attention.mdx +++ b/docs/src/content/docs/configuration/Optimization/sage-attention.mdx @@ -36,6 +36,7 @@ compared with PyTorch's default attention there: | Video model (as measured) | Resolution | Generation | Notes | | --- | --- | --- | --- | | LTX-2.5 distilled (int8) | 1248×704, 121 frames | 72.0 s → 63.4 s (−12 %) | Video self-attention only; text cross-attention and the audio streams stay on PyTorch. | +| Wan 2.2 TI2V-5B (GGUF Q8) | 1280×704, 121 frames | 380.9 s → 247.9 s (−35 %) | | At 1024×1024 most of a step is spent outside attention, so the gain is small; at high resolutions and for video, attention dominates. GGUF models spend much of each step dequantizing weights, which SageAttention does not touch. diff --git a/invokeai/app/invocations/wan/wan_denoise.py b/invokeai/app/invocations/wan/wan_denoise.py index 85e7e0c2feb..3509dfaa8a7 100644 --- a/invokeai/app/invocations/wan/wan_denoise.py +++ b/invokeai/app/invocations/wan/wan_denoise.py @@ -52,6 +52,7 @@ from invokeai.backend.stable_diffusion.diffusers_pipeline import PipelineIntermediateState from invokeai.backend.stable_diffusion.diffusion.conditioning_data import WanConditioningInfo from invokeai.backend.util.devices import TorchDevice +from invokeai.backend.util.sage_attention import sage_attention_scope from invokeai.backend.wan.memory_optimization import wan_memory_optimization from invokeai.backend.wan.sampling_utils import get_spatial_scale_factor, make_noise @@ -653,6 +654,7 @@ def low_lora_factory() -> Iterable[PatchSpec]: ), ) exit_stack.callback(swapper.close) + exit_stack.enter_context(sage_attention_scope()) for step_idx, t in enumerate(tqdm(timesteps, desc="Denoising (Wan 2.2)", total=total_steps)): timestep = t.expand(latents.shape[0]) diff --git a/invokeai/app/invocations/wan/wan_video_denoise.py b/invokeai/app/invocations/wan/wan_video_denoise.py index bb23f3e14a1..1e1bf100205 100644 --- a/invokeai/app/invocations/wan/wan_video_denoise.py +++ b/invokeai/app/invocations/wan/wan_video_denoise.py @@ -42,6 +42,7 @@ from invokeai.backend.stable_diffusion.diffusers_pipeline import PipelineIntermediateState from invokeai.backend.stable_diffusion.diffusion.conditioning_data import WanConditioningInfo from invokeai.backend.util.devices import TorchDevice +from invokeai.backend.util.sage_attention import sage_attention_scope from invokeai.backend.wan.memory_optimization import wan_memory_optimization from invokeai.backend.wan.sampling_utils import ( get_default_latent_channels, @@ -311,6 +312,7 @@ def low_lora_factory() -> Iterable[PatchSpec]: ), ) exit_stack.callback(swapper.close) + exit_stack.enter_context(sage_attention_scope()) for step_idx, t in enumerate( tqdm(timesteps, desc=f"Denoising Wan 2.2 video ({self.num_frames} frames)", total=total_steps) From 3d1a8b49f08d84f0fa0cbb0ec6bf5ad6dfee4912 Mon Sep 17 00:00:00 2001 From: Alexander Eichhorn Date: Tue, 13 Oct 2026 00:59:53 +0200 Subject: [PATCH 2/2] docs(attention): add the Wan 2.2 A14B measurements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At 832×480 with 81 frames SageAttention halves denoising (121.5 s → 60.9 s); at 1280×720 a 24 GB GPU is already full with PyTorch's attention and it got slower (293 s → 662 s), tracked in #9831. --- .../content/docs/configuration/Optimization/sage-attention.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/content/docs/configuration/Optimization/sage-attention.mdx b/docs/src/content/docs/configuration/Optimization/sage-attention.mdx index 754e8df5d64..f736aabef3d 100644 --- a/docs/src/content/docs/configuration/Optimization/sage-attention.mdx +++ b/docs/src/content/docs/configuration/Optimization/sage-attention.mdx @@ -37,6 +37,7 @@ compared with PyTorch's default attention there: | --- | --- | --- | --- | | LTX-2.5 distilled (int8) | 1248×704, 121 frames | 72.0 s → 63.4 s (−12 %) | Video self-attention only; text cross-attention and the audio streams stay on PyTorch. The audio reads the video through cross-attention, so it changes too, but measured no more than with an exact kernel swap: no shift against the picture, same loudness. | | Wan 2.2 TI2V-5B (GGUF Q8) | 1280×704, 121 frames | 380.9 s → 247.9 s (−35 %) | | +| Wan 2.2 T2V A14B (GGUF Q4_K_M, 4-step Lightning LoRA) | 832×480, 81 frames | Denoising 121.5 s → 60.9 s (−50 %) | Measured with `device_working_mem_gb: 10`. At 1280×720 a 24 GB GPU is already full with PyTorch's attention, and SageAttention made denoising slower: 293 s → 662 s. | At 1024×1024 most of a step is spent outside attention, so the gain is small; at high resolutions and for video, attention dominates. GGUF models spend much of each step dequantizing weights, which SageAttention does not touch.