cache-dit 0.2.17__py3-none-any.whl → 0.2.19__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cache_dit/__init__.py CHANGED
@@ -11,6 +11,7 @@ from cache_dit.cache_factory import default_options
11
11
  from cache_dit.cache_factory import block_range
12
12
  from cache_dit.cache_factory import CacheType
13
13
  from cache_dit.compile import set_compile_configs
14
+ from cache_dit.utils import summary
14
15
  from cache_dit.logger import init_logger
15
16
 
16
17
  NONE = CacheType.NONE
cache_dit/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.2.17'
32
- __version_tuple__ = version_tuple = (0, 2, 17)
31
+ __version__ = version = '0.2.19'
32
+ __version_tuple__ = version_tuple = (0, 2, 19)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -11,22 +11,31 @@ logger = init_logger(__name__)
11
11
 
12
12
 
13
13
  def load_options(path: str):
14
- """cache_dit.load_options(cache_config.yaml)"""
15
14
  return load_cache_options_from_yaml(path)
16
15
 
17
16
 
18
- def cache_type(type_hint: "CacheType | str") -> CacheType:
17
+ def cache_type(
18
+ type_hint: "CacheType | str",
19
+ ) -> CacheType:
19
20
  return CacheType.type(cache_type=type_hint)
20
21
 
21
22
 
22
- def default_options(cache_type: CacheType = None) -> Dict:
23
- if cache_type is None:
24
- return CacheType.default_options(CacheType.DBCache)
23
+ def default_options(
24
+ cache_type: CacheType = CacheType.DBCache,
25
+ ) -> Dict:
25
26
  return CacheType.default_options(cache_type)
26
27
 
27
28
 
28
- def block_range(start: int, end: int, step: int = 1) -> List[int]:
29
- return CacheType.block_range(start, end, step)
29
+ def block_range(
30
+ start: int,
31
+ end: int,
32
+ step: int = 1,
33
+ ) -> List[int]:
34
+ return CacheType.block_range(
35
+ start,
36
+ end,
37
+ step,
38
+ )
30
39
 
31
40
 
32
41
  def enable_cache(
@@ -464,6 +464,7 @@ class UnifiedCacheAdapter:
464
464
 
465
465
  pipe.__class__.__call__ = new_call
466
466
  pipe.__class__._is_cached = True
467
+ pipe.__class__._cache_options = cache_kwargs
467
468
  return pipe
468
469
 
469
470
  @classmethod
@@ -630,7 +631,8 @@ class UnifiedCacheAdapter:
630
631
  pattern_id = list(unique_pattern_ids)[0]
631
632
  pattern = selected_patterns[pattern_id]
632
633
  logger.info(
633
- f"Match cache pattern: IN({pattern['IN']}, OUT({pattern['OUT']}))"
634
+ f"Match Block Forward Pattern: {transformer_blocks[0].__class__.__name__}"
635
+ f"\n IN({pattern['IN']}, \nOUT({pattern['OUT']}))"
634
636
  )
635
637
 
636
638
  return pattern_matched
@@ -230,7 +230,7 @@ def maybe_patch_flux_transformer(
230
230
  for block in blocks:
231
231
  if isinstance(block, FluxSingleTransformerBlock):
232
232
  forward_parameters = inspect.signature(
233
- blocks.forward
233
+ block.forward
234
234
  ).parameters.keys()
235
235
  if "encoder_hidden_states" not in forward_parameters:
236
236
  block.forward = __patch_single_forward__.__get__(block)
cache_dit/utils.py CHANGED
@@ -1,7 +1,132 @@
1
1
  import torch
2
+ import dataclasses
2
3
  import diffusers
4
+ import numpy as np
5
+ from pprint import pprint
6
+ from diffusers import DiffusionPipeline
7
+
8
+ from cache_dit.logger import init_logger
9
+
10
+ logger = init_logger(__name__)
3
11
 
4
12
 
5
13
  @torch.compiler.disable
6
14
  def is_diffusers_at_least_0_3_5() -> bool:
7
15
  return diffusers.__version__ >= "0.35.0"
16
+
17
+
18
+ @dataclasses.dataclass
19
+ class CacheStats:
20
+ cache_options: dict = dataclasses.field(default_factory=dict)
21
+ cached_steps: list[int] = dataclasses.field(default_factory=list)
22
+ residual_diffs: dict[str, float] = dataclasses.field(default_factory=dict)
23
+ cfg_cached_steps: list[int] = dataclasses.field(default_factory=list)
24
+ cfg_residual_diffs: dict[str, float] = dataclasses.field(
25
+ default_factory=dict
26
+ )
27
+
28
+
29
+ def summary(pipe: DiffusionPipeline, details: bool = False):
30
+ cache_stats = CacheStats()
31
+ pipe_cls_name = pipe.__class__.__name__
32
+
33
+ if hasattr(pipe, "_cache_options"):
34
+ cache_options = pipe._cache_options
35
+ cache_stats.cache_options = cache_options
36
+ print(f"\n🤗Cache Options: {pipe_cls_name}\n\n{cache_options}")
37
+
38
+ if hasattr(pipe.transformer, "_cached_steps"):
39
+ cached_steps: list[int] = pipe.transformer._cached_steps
40
+ residual_diffs: dict[str, float] = pipe.transformer._residual_diffs
41
+ cache_stats.cached_steps = cached_steps
42
+ cache_stats.residual_diffs = residual_diffs
43
+
44
+ if residual_diffs:
45
+ diffs_values = list(residual_diffs.values())
46
+ q0 = np.percentile(diffs_values, 0)
47
+ q1 = np.percentile(diffs_values, 25)
48
+ q2 = np.percentile(diffs_values, 50)
49
+ q3 = np.percentile(diffs_values, 75)
50
+ q4 = np.percentile(diffs_values, 95)
51
+
52
+ print(
53
+ f"\n⚡️Cache Steps and Residual Diffs Statistics: {pipe_cls_name}\n"
54
+ )
55
+
56
+ print(
57
+ "| Cache Steps | Diffs P00 | Diffs P25 | Diffs P50 | Diffs P75 | Diffs P95 |"
58
+ )
59
+ print(
60
+ "|-------------|-----------|-----------|-----------|-----------|-----------|"
61
+ )
62
+ print(
63
+ f"| {len(cached_steps):<11} | {round(q0, 3):<9} | {round(q1, 3):<9} "
64
+ f"| {round(q2, 3):<9} | {round(q3, 3):<9} | {round(q4, 3):<9} |"
65
+ )
66
+ print("")
67
+
68
+ if details:
69
+ print(
70
+ f"📚Cache Steps and Residual Diffs Details: {pipe_cls_name}\n"
71
+ )
72
+ print("-" * 200)
73
+ pprint(
74
+ f"Cache Steps: {len(cached_steps)}, {cached_steps}",
75
+ width=200,
76
+ )
77
+ pprint(
78
+ f"Residual Diffs: {len(residual_diffs)}, {residual_diffs}",
79
+ compact=True,
80
+ width=200,
81
+ )
82
+ print("-" * 200)
83
+
84
+ if hasattr(pipe.transformer, "_cfg_cached_steps"):
85
+ cfg_cached_steps: list[int] = pipe.transformer._cfg_cached_steps
86
+ cfg_residual_diffs: dict[str, float] = (
87
+ pipe.transformer._cfg_residual_diffs
88
+ )
89
+ cache_stats.cfg_cached_steps = cfg_cached_steps
90
+ cache_stats.cfg_residual_diffs = cfg_residual_diffs
91
+
92
+ if cfg_residual_diffs:
93
+ cfg_diffs_values = list(cfg_residual_diffs.values())
94
+ q0 = np.percentile(cfg_diffs_values, 0)
95
+ q1 = np.percentile(cfg_diffs_values, 25)
96
+ q2 = np.percentile(cfg_diffs_values, 50)
97
+ q3 = np.percentile(cfg_diffs_values, 75)
98
+ q4 = np.percentile(cfg_diffs_values, 95)
99
+
100
+ print(
101
+ f"\n⚡️CFG Cache Steps and Residual Diffs Statistics: {pipe_cls_name}\n"
102
+ )
103
+
104
+ print(
105
+ "| CFG Cache Steps | Diffs P00 | Diffs P25 | Diffs P50 | Diffs P75 | Diffs P95 |"
106
+ )
107
+ print(
108
+ "|-----------------|-----------|-----------|-----------|-----------|-----------|"
109
+ )
110
+ print(
111
+ f"| {len(cfg_cached_steps):<15} | {round(q0, 3):<9} | {round(q1, 3):<9} "
112
+ f"| {round(q2, 3):<9} | {round(q3, 3):<9} | {round(q4, 3):<9} |"
113
+ )
114
+ print("")
115
+
116
+ if details:
117
+ print(
118
+ f"📚CFG Cache Steps and Residual Diffs Details: {pipe_cls_name}\n"
119
+ )
120
+ print("-" * 200)
121
+ pprint(
122
+ f"CFG Cache Steps: {len(cfg_cached_steps)}, {cfg_cached_steps}",
123
+ width=200,
124
+ )
125
+ pprint(
126
+ f"CFG Residual Diffs: {len(cfg_residual_diffs)}, {cfg_residual_diffs}",
127
+ compact=True,
128
+ width=200,
129
+ )
130
+ print("-" * 200)
131
+
132
+ return cache_stats
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cache_dit
3
- Version: 0.2.17
3
+ Version: 0.2.19
4
4
  Summary: 🤗 CacheDiT: An Unified and Training-free Cache Acceleration Toolbox for Diffusion Transformers
5
5
  Author: DefTruth, vipshop.com, etc.
6
6
  Maintainer: DefTruth, vipshop.com, etc
@@ -61,15 +61,15 @@ Dynamic: requires-python
61
61
  </p>
62
62
  </div>
63
63
 
64
-
65
64
  ## 🔥News
66
65
 
66
+ - [2025-08-19] 🔥[**Qwen-Image-Edit**](https://github.com/QwenLM/Qwen-Image) **2x⚡️** speedup! Check example [run_qwen_image_edit.py](./examples/run_qwen_image_edit.py).
67
67
  - [2025-08-18] 🎉Early **[Unified Cache APIs](#unified)** released! Check [Qwen-Image w/ UAPI](./examples/run_qwen_image_uapi.py) as an example.
68
68
  - [2025-08-12] 🎉First caching mechanism in [QwenLM/Qwen-Image](https://github.com/QwenLM/Qwen-Image) with **[cache-dit](https://github.com/vipshop/cache-dit)**, check the [PR](https://github.com/QwenLM/Qwen-Image/pull/61).
69
- - [2025-08-11] 🔥[Qwen-Image](https://github.com/QwenLM/Qwen-Image) is supported now! Please refer [run_qwen_image.py](./examples/run_qwen_image.py) as an example.
70
- - [2025-08-10] 🔥[FLUX.1-Kontext-dev](https://huggingface.co/black-forest-labs/FLUX.1-Kontext-dev) is supported! Please refer [run_flux_kontext.py](./examples/run_flux_kontext.py) as an example.
69
+ - [2025-08-11] 🔥[**Qwen-Image**](https://github.com/QwenLM/Qwen-Image) **1.8x⚡️** speedup! Please refer [run_qwen_image.py](./examples/run_qwen_image.py) as an example.
70
+ - [2025-08-10] 🔥[**FLUX.1-Kontext-dev**](https://huggingface.co/black-forest-labs/FLUX.1-Kontext-dev) is supported! Please refer [run_flux_kontext.py](./examples/run_flux_kontext.py) as an example.
71
71
  - [2025-07-18] 🎉First caching mechanism in [🤗huggingface/flux-fast](https://github.com/huggingface/flux-fast) with **[cache-dit](https://github.com/vipshop/cache-dit)**, check the [PR](https://github.com/huggingface/flux-fast/pull/13).
72
- - [2025-07-13] **[🤗flux-faster](https://github.com/xlite-dev/flux-faster)** is released! **3.3x** speedup for FLUX.1 on NVIDIA L20 with `cache-dit`.
72
+ - [2025-07-13] **[🤗flux-faster](https://github.com/xlite-dev/flux-faster)** is released! **3.3x** speedup for FLUX.1 on NVIDIA L20 with **[cache-dit](https://github.com/vipshop/cache-dit)**.
73
73
 
74
74
  ## 📖Contents
75
75
 
@@ -105,6 +105,7 @@ pip3 install git+https://github.com/vipshop/cache-dit.git
105
105
 
106
106
  Currently, **cache-dit** library supports almost **Any** Diffusion Transformers (with **Transformer Blocks** that match the specific Input and Output **patterns**). Please check [🎉Unified Cache APIs](#unified) for more details. Here are just some of the tested models listed:
107
107
 
108
+ - [🚀Qwen-Image-Edit](https://github.com/vipshop/cache-dit/raw/main/examples)
108
109
  - [🚀Qwen-Image](https://github.com/vipshop/cache-dit/raw/main/examples)
109
110
  - [🚀FLUX.1-dev](https://github.com/vipshop/cache-dit/raw/main/examples)
110
111
  - [🚀FLUX.1-Fill-dev](https://github.com/vipshop/cache-dit/raw/main/examples)
@@ -128,34 +129,51 @@ Currently, **cache-dit** library supports almost **Any** Diffusion Transformers
128
129
 
129
130
  <div id="unified"></div>
130
131
 
132
+ Currently, for any **Diffusion** models with **Transformer Blocks** that match the specific **Input/Output patterns**, we can use the **Unified Cache APIs** from **cache-dit**, namely, the `cache_dit.enable_cache(...)` API. The supported patterns are listed as follows:
131
133
 
132
- Currently, for any **Diffusion** models with **Transformer Blocks** that match the specific **Input/Output pattern**, we can use the **Unified Cache APIs** from **cache-dit**. The supported patterns are listed as follows:
133
-
134
- ```bash
134
+ ```python
135
135
  (IN: hidden_states, encoder_hidden_states, ...) -> (OUT: hidden_states, encoder_hidden_states)
136
136
  (IN: hidden_states, encoder_hidden_states, ...) -> (OUT: encoder_hidden_states, hidden_states)
137
137
  (IN: hidden_states, encoder_hidden_states, ...) -> (OUT: hidden_states)
138
138
  (IN: hidden_states, ...) -> (OUT: hidden_states) # TODO, DiT, Lumina2, etc.
139
139
  ```
140
140
 
141
- Please refer to [Qwen-Image w/ UAPI](./examples/run_qwen_image_uapi.py) as an example. The `pipe` parameter can be **Any** Diffusion Pipelines. The **Unified Cache APIs** are currently in the experimental phase, please stay tuned for updates.
141
+ After the `cache_dit.enable_cache(...)` API is called, you just need to call the pipe as normal. The `pipe` param can be **any** Diffusion Pipeline. Please refer to [Qwen-Image](./examples/run_qwen_image_uapi.py) as an example. The **Unified Cache APIs** are currently in the experimental phase; please stay tuned for updates.
142
142
 
143
143
  ```python
144
144
  import cache_dit
145
- from diffusers import DiffusionPipeline # Can be [Any] Diffusion Pipeline
145
+ from diffusers import DiffusionPipeline
146
146
 
147
+ # can be any diffusion pipeline
147
148
  pipe = DiffusionPipeline.from_pretrained("Qwen/Qwen-Image")
148
149
 
149
- # Just use the one line code with default cache options.
150
+ # one line code with default cache options.
150
151
  cache_dit.enable_cache(pipe)
151
152
 
152
- # Or, enable cache with custom setting according to your models.
153
+ # or, enable cache with custom settings.
153
154
  cache_dit.enable_cache(
154
155
  pipe, transformer=pipe.transformer,
155
156
  blocks=pipe.transformer.transformer_blocks,
156
157
  return_hidden_states_first=False,
157
158
  **cache_dit.default_options(),
158
159
  )
160
+
161
+ # just call the pipe as normal.
162
+ output = pipe(...)
163
+
164
+ # then, summary the cache stats.
165
+ stats = cache_dit.summary(pipe)
166
+ ```
167
+
168
+ After finishing each inference of `pipe(...)`, you can call the `cache_dit.summary(...)` API on pipe to get the details of the cache stats for the current inference (markdown table format). You can set `details` param as `True` to show more details of cache stats.
169
+
170
+ ```python
171
+ ⚡️Cache Steps and Residual Diffs Statistics: QwenImagePipeline
172
+
173
+ | Cache Steps | Diffs P00 | Diffs P25 | Diffs P50 | Diffs P75 | Diffs P95 |
174
+ |-------------|-----------|-----------|-----------|-----------|-----------|
175
+ | 23 | 0.04 | 0.082 | 0.115 | 0.152 | 0.245 |
176
+ ...
159
177
  ```
160
178
 
161
179
  ## ⚡️DBCache: Dual Block Cache
@@ -1,17 +1,17 @@
1
- cache_dit/__init__.py,sha256=gRJrSVrj-700qjgjwHfcHkiIHKbGm2cutP1TybxQZk4,605
2
- cache_dit/_version.py,sha256=sRnPbdnyLakHrE7uBPRC_AQNPiFphtVIa4BPaftkqk4,706
1
+ cache_dit/__init__.py,sha256=TvZI861ipGnYaOEHJA0Og-ksRUGNCld-PGy_NgjcKZE,641
2
+ cache_dit/_version.py,sha256=32XF9c5EeiOUdyiWeKcwkXTWZQBgtvbmKx8wZoDEW0o,706
3
3
  cache_dit/logger.py,sha256=0zsu42hN-3-rgGC_C29ms1IvVpV4_b4_SwJCKSenxBE,4304
4
4
  cache_dit/primitives.py,sha256=A2iG9YLot3gOsZSPp-_gyjqjLgJvWQRx8aitD4JQ23Y,3877
5
- cache_dit/utils.py,sha256=4cFNh0asch6Zgsixq0bS1ElfwBu_6BG5ZSmaa1khjyg,144
5
+ cache_dit/utils.py,sha256=yybhUTGPfeCoIVZzpoefZ2ypvH8de-10UhPls81ceG4,4800
6
6
  cache_dit/cache_factory/.gitignore,sha256=5Cb-qT9wsTUoMJ7vACDF7ZcLpAXhi5v-xdcWSRit988,23
7
- cache_dit/cache_factory/__init__.py,sha256=2td8ivq0DDzu00Kq1oPvq0Bh5C76w_gwsMfyUo2xW9U,1652
8
- cache_dit/cache_factory/cache_adapters.py,sha256=ECYRvgx6ePX6Jd6sqUXmXi6kbWaqlOdvm6aZLhpedW0,23455
7
+ cache_dit/cache_factory/__init__.py,sha256=f4IUOgEALTEBb9UOHtXoGwqKrDb2ZhI_dHkiIrni1Xc,1586
8
+ cache_dit/cache_factory/cache_adapters.py,sha256=-bFMOfIPdfWKTAfF533PuLYaDl1wq8RNUAXJn--Rm7I,23587
9
9
  cache_dit/cache_factory/cache_blocks.py,sha256=9jgK2IT0Y_AlbhJLnhgA47lOxQNwNizDgHve45818gg,18390
10
10
  cache_dit/cache_factory/cache_context.py,sha256=f-ihx14NXIZNakN2b_dduegRpJr5SwcPtc2PqnpDdUY,39818
11
11
  cache_dit/cache_factory/taylorseer.py,sha256=LKSNo2ode69EVo9xrxjxAMEjz0yDGiGADeDYnEqddA8,3987
12
12
  cache_dit/cache_factory/utils.py,sha256=iQg3dqBfQTGkvMdKeO5-YmzkQO5LBSoZ8sYKwQA_7_I,1805
13
13
  cache_dit/cache_factory/patch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- cache_dit/cache_factory/patch/flux.py,sha256=eTdq-3limKHgwtVCILkZTwt9FwYUhH7_VlhKnfu55BU,8999
14
+ cache_dit/cache_factory/patch/flux.py,sha256=iNQ-1RlOgXupZ4uPiEvJ__Ro6vKT_fOKja9JrpMrO78,8998
15
15
  cache_dit/compile/__init__.py,sha256=FcTVzCeyypl-mxlc59_ehHL3lBNiDAFsXuRoJ-5Cfi0,56
16
16
  cache_dit/compile/utils.py,sha256=ugHrv3QRieG1xKwcg_pi3yVZF6EpSOEJjRmbnfa7VG0,3779
17
17
  cache_dit/custom_ops/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -22,9 +22,9 @@ cache_dit/metrics/fid.py,sha256=9Ivtazl6mW0Bon2VXa-Ia5Xj2ewxRD3V1Qkd69zYM3Y,1706
22
22
  cache_dit/metrics/inception.py,sha256=pBVe2X6ylLPIXTG4-GWDM9DWnCviMJbJ45R3ulhktR0,12759
23
23
  cache_dit/metrics/lpips.py,sha256=I2qCNi6qJh5TRsaIsdxO0WoRX1DN7U_H3zS0oCSahYM,1032
24
24
  cache_dit/metrics/metrics.py,sha256=8jvM1sF-nDxUuwCRy44QEoo4dYVLCQVh1QyAMs4eaQY,27840
25
- cache_dit-0.2.17.dist-info/licenses/LICENSE,sha256=Dqb07Ik2dV41s9nIdMUbiRWEfDqo7-dQeRiY7kPO8PE,3769
26
- cache_dit-0.2.17.dist-info/METADATA,sha256=HqEAEr08N7whWcxOMOVJKThQPglCW_GAj-LcynXmIDI,19804
27
- cache_dit-0.2.17.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
28
- cache_dit-0.2.17.dist-info/entry_points.txt,sha256=FX2gysXaZx6NeK1iCLMcIdP8Q4_qikkIHtEmi3oWn8o,65
29
- cache_dit-0.2.17.dist-info/top_level.txt,sha256=ZJDydonLEhujzz0FOkVbO-BqfzO9d_VqRHmZU-3MOZo,10
30
- cache_dit-0.2.17.dist-info/RECORD,,
25
+ cache_dit-0.2.19.dist-info/licenses/LICENSE,sha256=Dqb07Ik2dV41s9nIdMUbiRWEfDqo7-dQeRiY7kPO8PE,3769
26
+ cache_dit-0.2.19.dist-info/METADATA,sha256=cCnv_b_F06xdttqdHhnbmPDpF_xRgz-O03tYfvzGGrI,20910
27
+ cache_dit-0.2.19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
28
+ cache_dit-0.2.19.dist-info/entry_points.txt,sha256=FX2gysXaZx6NeK1iCLMcIdP8Q4_qikkIHtEmi3oWn8o,65
29
+ cache_dit-0.2.19.dist-info/top_level.txt,sha256=ZJDydonLEhujzz0FOkVbO-BqfzO9d_VqRHmZU-3MOZo,10
30
+ cache_dit-0.2.19.dist-info/RECORD,,