Skip to content

Commit 24d65c9

Browse files
committed
add caching docs
1 parent 81d7f89 commit 24d65c9

6 files changed

Lines changed: 1025 additions & 4 deletions

File tree

nunchaku/caching/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

nunchaku/caching/diffusers_adapters/__init__.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,101 @@
1+
"""
2+
Diffusers Pipeline Adapters for Nunchaku Caching.
3+
4+
This module provides adapter functions that integrate Nunchaku's caching capabilities
5+
with diffusers pipelines. The adapters automatically detect pipeline types and apply
6+
the appropriate caching strategy without requiring manual configuration.
7+
8+
The module serves as a unified interface for applying caching to different types of
9+
diffusion pipelines, currently supporting:
10+
11+
- Flux pipelines (FluxPipeline and related variants)
12+
- SANA pipelines (SanaPipeline and related variants)
13+
14+
Key Features:
15+
- Automatic pipeline type detection
16+
- Unified interface for different caching strategies
17+
- Seamless integration with existing diffusers workflows
18+
- Support for both shallow and deep caching patches
19+
20+
Example:
21+
Basic usage with automatic pipeline detection::
22+
23+
from diffusers import FluxPipeline
24+
from nunchaku.caching.diffusers_adapters import apply_cache_on_pipe
25+
26+
# Load any supported pipeline
27+
pipe = FluxPipeline.from_pretrained("black-forest-labs/FLUX.1-dev")
28+
29+
# Apply caching automatically based on pipeline type
30+
cached_pipe = apply_cache_on_pipe(
31+
pipe,
32+
residual_diff_threshold=0.1,
33+
use_double_fb_cache=True
34+
)
35+
36+
# Use the cached pipeline normally
37+
image = cached_pipe(prompt="A beautiful landscape")
38+
39+
Note:
40+
The adapter functions modify the pipeline in-place, adding caching capabilities
41+
while preserving the original API. The caching behavior is transparent to the
42+
user and doesn't require changes to existing code.
43+
"""
44+
145
from diffusers import DiffusionPipeline
246

347

448
def apply_cache_on_pipe(pipe: DiffusionPipeline, *args, **kwargs):
49+
"""
50+
Apply caching to a diffusers pipeline with automatic type detection.
51+
52+
This function serves as a unified interface for applying Nunchaku caching
53+
to different types of diffusion pipelines. It automatically detects the
54+
pipeline type based on the class name and delegates to the appropriate
55+
caching implementation.
56+
57+
Args:
58+
pipe (DiffusionPipeline): The diffusers pipeline to apply caching to
59+
*args: Variable positional arguments passed to the specific caching function
60+
**kwargs: Variable keyword arguments passed to the specific caching function.
61+
Common arguments include:
62+
- residual_diff_threshold (float): Similarity threshold for cache validity
63+
- use_double_fb_cache (bool): Whether to use double first-block caching
64+
- shallow_patch (bool): Whether to use shallow patching only
65+
- verbose (bool): Whether to enable verbose caching messages
66+
67+
Returns:
68+
DiffusionPipeline: The same pipeline instance with caching applied
69+
70+
Raises:
71+
ValueError: If the pipeline type is not supported (doesn't start with "Flux" or "Sana")
72+
AssertionError: If the input is not a DiffusionPipeline instance
73+
74+
Example:
75+
With a Flux pipeline::
76+
77+
from diffusers import FluxPipeline
78+
pipe = FluxPipeline.from_pretrained("black-forest-labs/FLUX.1-dev")
79+
cached_pipe = apply_cache_on_pipe(
80+
pipe,
81+
residual_diff_threshold=0.12,
82+
use_double_fb_cache=True
83+
)
84+
85+
With a SANA pipeline::
86+
87+
from diffusers import SanaPipeline
88+
pipe = SanaPipeline.from_pretrained("Efficient-Large-Model/Sana_600M_512px")
89+
cached_pipe = apply_cache_on_pipe(
90+
pipe,
91+
residual_diff_threshold=0.1
92+
)
93+
94+
Note:
95+
The function modifies the pipeline in-place and returns the same instance.
96+
Currently supported pipeline types are those with class names starting
97+
with "Flux" or "Sana".
98+
"""
599
assert isinstance(pipe, DiffusionPipeline)
6100

7101
pipe_cls_name = pipe.__class__.__name__

nunchaku/caching/diffusers_adapters/flux.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,57 @@
1+
"""
2+
Flux Pipeline Caching Adapter.
3+
4+
This module provides caching adapters specifically for Flux diffusion pipelines.
5+
It implements both transformer-level and pipeline-level caching integration,
6+
enabling efficient inference through advanced first-block caching strategies.
7+
8+
The module supports both single and double first-block caching for Flux models,
9+
with automatic context management to ensure proper cache lifecycle during
10+
inference.
11+
12+
Key Functions:
13+
apply_cache_on_transformer: Apply caching directly to a FluxTransformer2DModel
14+
apply_cache_on_pipe: Apply caching to a complete Flux pipeline
15+
16+
Caching Features:
17+
- Single first-block caching: Caches the first transformer block only
18+
- Double first-block caching: Caches both multi-head and single-head attention blocks
19+
- Dynamic threshold adjustment: Automatically adjusts similarity thresholds
20+
- Context management: Ensures proper cache setup and cleanup
21+
- Shallow patching: Optional lightweight patching for testing
22+
23+
Example:
24+
Apply caching to a Flux transformer::
25+
26+
from diffusers import FluxTransformer2DModel
27+
from nunchaku.caching.diffusers_adapters.flux import apply_cache_on_transformer
28+
29+
transformer = FluxTransformer2DModel.from_pretrained("model_name")
30+
cached_transformer = apply_cache_on_transformer(
31+
transformer,
32+
use_double_fb_cache=True,
33+
residual_diff_threshold_multi=0.12,
34+
residual_diff_threshold_single=0.09
35+
)
36+
37+
Apply caching to a complete pipeline::
38+
39+
from diffusers import FluxPipeline
40+
from nunchaku.caching.diffusers_adapters.flux import apply_cache_on_pipe
41+
42+
pipe = FluxPipeline.from_pretrained("black-forest-labs/FLUX.1-dev")
43+
cached_pipe = apply_cache_on_pipe(
44+
pipe,
45+
use_double_fb_cache=True,
46+
residual_diff_threshold=0.12
47+
)
48+
49+
Note:
50+
The caching is applied in-place and uses mock patching to temporarily replace
51+
transformer components during inference. The original functionality is preserved
52+
when not using caching context.
53+
"""
54+
155
import functools
256
import unittest
357

@@ -15,6 +69,51 @@ def apply_cache_on_transformer(
1569
residual_diff_threshold_multi: float | None = None,
1670
residual_diff_threshold_single: float = 0.1,
1771
):
72+
"""
73+
Apply caching to a Flux transformer model.
74+
75+
This function modifies a FluxTransformer2DModel to use cached transformer blocks
76+
for improved inference performance. It supports both single and double first-block
77+
caching strategies with configurable similarity thresholds.
78+
79+
Args:
80+
transformer (FluxTransformer2DModel): The Flux transformer model to apply caching to
81+
use_double_fb_cache (bool, optional): Whether to use double first-block caching.
82+
If True, caches both multi-head and single-head attention blocks. Defaults to False.
83+
residual_diff_threshold (float, optional): Default similarity threshold for caching.
84+
Used for residual_diff_threshold_multi if not explicitly provided. Defaults to 0.12.
85+
residual_diff_threshold_multi (float, optional): Similarity threshold for multi-head
86+
attention blocks. If None, uses residual_diff_threshold. Defaults to None.
87+
residual_diff_threshold_single (float, optional): Similarity threshold for single-head
88+
attention blocks. Defaults to 0.1.
89+
90+
Returns:
91+
FluxTransformer2DModel: The same transformer instance with caching applied
92+
93+
Example:
94+
Basic caching setup::
95+
96+
transformer = FluxTransformer2DModel.from_pretrained("model_name")
97+
cached_transformer = apply_cache_on_transformer(
98+
transformer,
99+
use_double_fb_cache=True,
100+
residual_diff_threshold=0.12
101+
)
102+
103+
Advanced configuration::
104+
105+
cached_transformer = apply_cache_on_transformer(
106+
transformer,
107+
use_double_fb_cache=True,
108+
residual_diff_threshold_multi=0.15,
109+
residual_diff_threshold_single=0.08
110+
)
111+
112+
Note:
113+
If the transformer is already cached, the function updates the thresholds
114+
instead of reapplying caching. The caching only activates when a cache
115+
context is present.
116+
"""
18117
if residual_diff_threshold_multi is None:
19118
residual_diff_threshold_multi = residual_diff_threshold
20119

@@ -60,6 +159,56 @@ def new_forward(self, *args, **kwargs):
60159

61160

62161
def apply_cache_on_pipe(pipe: DiffusionPipeline, *, shallow_patch: bool = False, **kwargs):
162+
"""
163+
Apply caching to a complete Flux diffusion pipeline.
164+
165+
This function modifies a Flux diffusion pipeline to use caching during inference.
166+
It wraps the pipeline's __call__ method to automatically create and manage cache
167+
contexts, and optionally applies transformer-level caching.
168+
169+
Args:
170+
pipe (DiffusionPipeline): The Flux diffusion pipeline to apply caching to
171+
shallow_patch (bool, optional): If True, only applies pipeline-level caching
172+
without modifying the transformer. Useful for testing. Defaults to False.
173+
**kwargs: Additional keyword arguments passed to apply_cache_on_transformer,
174+
including:
175+
- use_double_fb_cache (bool): Whether to use double first-block caching
176+
- residual_diff_threshold (float): Similarity threshold for caching
177+
- residual_diff_threshold_multi (float): Multi-head attention threshold
178+
- residual_diff_threshold_single (float): Single-head attention threshold
179+
180+
Returns:
181+
DiffusionPipeline: The same pipeline instance with caching applied
182+
183+
Example:
184+
Basic usage::
185+
186+
from diffusers import FluxPipeline
187+
pipe = FluxPipeline.from_pretrained("black-forest-labs/FLUX.1-dev")
188+
cached_pipe = apply_cache_on_pipe(pipe)
189+
190+
# Use normally - caching is transparent
191+
image = cached_pipe(prompt="A beautiful landscape")
192+
193+
Advanced configuration::
194+
195+
cached_pipe = apply_cache_on_pipe(
196+
pipe,
197+
use_double_fb_cache=True,
198+
residual_diff_threshold=0.1,
199+
residual_diff_threshold_single=0.05
200+
)
201+
202+
Shallow patching for testing::
203+
204+
cached_pipe = apply_cache_on_pipe(pipe, shallow_patch=True)
205+
206+
Note:
207+
The function modifies the pipeline class's __call__ method, affecting all
208+
instances of the same pipeline class. If the pipeline is already cached,
209+
it skips the pipeline-level patching but still applies transformer caching
210+
unless shallow_patch is True.
211+
"""
63212
if not getattr(pipe, "_is_cached", False):
64213
original_call = pipe.__class__.__call__
65214

nunchaku/caching/diffusers_adapters/sana.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,55 @@
1+
"""
2+
SANA Pipeline Caching Adapter.
3+
4+
This module provides caching adapters specifically for SANA diffusion pipelines.
5+
It implements single first-block caching for SANA models, enabling efficient
6+
inference through intelligent reuse of first transformer block computations.
7+
8+
The SANA adapter uses a simpler caching strategy compared to Flux, focusing
9+
on single first-block caching with configurable similarity thresholds. This
10+
approach is optimized for the specific architecture and usage patterns of
11+
SANA models.
12+
13+
Key Functions:
14+
apply_cache_on_transformer: Apply caching directly to a SanaTransformer2DModel
15+
apply_cache_on_pipe: Apply caching to a complete SANA pipeline
16+
17+
Caching Features:
18+
- Single first-block caching: Caches the first transformer block's output
19+
- Configurable similarity thresholds: Adjust caching sensitivity
20+
- Context management: Automatic cache setup and cleanup
21+
- Batch size limitations: Optimized for batch sizes <= 2 (CFG support)
22+
23+
Example:
24+
Apply caching to a SANA transformer::
25+
26+
from diffusers import SanaTransformer2DModel
27+
from nunchaku.caching.diffusers_adapters.sana import apply_cache_on_transformer
28+
29+
transformer = SanaTransformer2DModel.from_pretrained("model_name")
30+
cached_transformer = apply_cache_on_transformer(
31+
transformer,
32+
residual_diff_threshold=0.12
33+
)
34+
35+
Apply caching to a complete SANA pipeline::
36+
37+
from diffusers import SanaPipeline
38+
from nunchaku.caching.diffusers_adapters.sana import apply_cache_on_pipe
39+
40+
pipe = SanaPipeline.from_pretrained("Efficient-Large-Model/Sana_600M_512px")
41+
cached_pipe = apply_cache_on_pipe(
42+
pipe,
43+
residual_diff_threshold=0.1
44+
)
45+
46+
Note:
47+
SANA caching is specifically designed for the SANA architecture and uses
48+
mock patching to temporarily replace transformer blocks during inference.
49+
The caching is automatically disabled for batch sizes > 2 to ensure
50+
compatibility with classifier-free guidance.
51+
"""
52+
153
import functools
254
import unittest
355

0 commit comments

Comments
 (0)