-
Notifications
You must be signed in to change notification settings - Fork 0
[Enhancement] Add cache-dit force_refresh support for Helios and GLM-Image #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 20 commits
26a4e8d
b3b70a8
104d71c
bf2ddb0
735b2ca
dd4468c
ff62a1e
870963e
5414a42
e3dec54
2cd9f9f
172040a
0a86fc5
9b9c597
bda0f2d
3452ad3
9ab7c55
c32a78a
5fcf302
a05183c
2ba9814
c36e4b4
c9e7f43
833ce12
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,6 +61,8 @@ def _build_db_cache_config(cache_config: Any) -> DBCacheConfig: | |
| max_cached_steps=cache_config.max_cached_steps, | ||
| max_continuous_cached_steps=cache_config.max_continuous_cached_steps, | ||
| residual_diff_threshold=cache_config.residual_diff_threshold, | ||
| force_refresh_step_hint=cache_config.force_refresh_step_hint, | ||
| force_refresh_step_policy=cache_config.force_refresh_step_policy, | ||
| ) | ||
|
|
||
|
|
||
|
|
@@ -984,6 +986,125 @@ def refresh_cache_context(pipeline: Any, num_inference_steps: int, verbose: bool | |
| return refresh_cache_context | ||
|
|
||
|
|
||
| def enable_cache_for_helios(pipeline: Any, cache_config: Any) -> Callable[[int], None]: | ||
| """Enable cache-dit for Helios pipeline (multi-chunk denoise loop). | ||
|
|
||
| Helios splits num_frames into multiple chunks and runs multiple passes of the | ||
| transformer denoise loop. The cache context must be refreshed at the end of each | ||
| loop to prevent stale cache from the previous chunk leaking into the next one. | ||
| This is achieved by setting force_refresh_step_hint = num_inference_steps with | ||
| force_refresh_step_policy = "repeat". | ||
| """ | ||
| db_cache_config = _build_db_cache_config(cache_config) | ||
|
|
||
| calibrator_config = None | ||
| if cache_config.enable_taylorseer: | ||
| calibrator_config = TaylorSeerCalibratorConfig(taylorseer_order=cache_config.taylorseer_order) | ||
| logger.info(f"TaylorSeer enabled with order={cache_config.taylorseer_order}") | ||
|
|
||
| logger.info( | ||
| f"Enabling cache-dit on Helios transformer: " | ||
| f"Fn={db_cache_config.Fn_compute_blocks}, " | ||
| f"Bn={db_cache_config.Bn_compute_blocks}, " | ||
| f"W={db_cache_config.max_warmup_steps}, " | ||
| f"force_refresh_step_policy={db_cache_config.force_refresh_step_policy}, " | ||
| ) | ||
|
|
||
| cache_dit.enable_cache( | ||
| pipeline.transformer, | ||
| cache_config=db_cache_config, | ||
| calibrator_config=calibrator_config, | ||
| ) | ||
|
|
||
| def refresh_cache_context(pipeline: Any, num_inference_steps: int, verbose: bool = True) -> None: | ||
| hint = cache_config.force_refresh_step_hint | ||
| if hint is None: | ||
| hint = num_inference_steps | ||
| policy = cache_config.force_refresh_step_policy | ||
| if policy == "once": | ||
| policy = "repeat" | ||
| if cache_config.scm_steps_mask_policy is None: | ||
| cache_dit.refresh_context( | ||
| pipeline.transformer, | ||
| cache_config=DBCacheConfig().reset( | ||
| num_inference_steps=num_inference_steps, | ||
| force_refresh_step_hint=hint, | ||
| force_refresh_step_policy=policy, | ||
| ), | ||
| verbose=verbose, | ||
| ) | ||
| else: | ||
| cache_dit.refresh_context( | ||
| pipeline.transformer, | ||
| cache_config=DBCacheConfig().reset( | ||
| num_inference_steps=num_inference_steps, | ||
| force_refresh_step_hint=hint, | ||
| force_refresh_step_policy=policy, | ||
| steps_computation_mask=cache_dit.steps_mask( | ||
| mask_policy=cache_config.scm_steps_mask_policy, | ||
| total_steps=num_inference_steps, | ||
| ), | ||
| steps_computation_policy=cache_config.scm_steps_policy, | ||
| ), | ||
| verbose=verbose, | ||
| ) | ||
|
|
||
| return refresh_cache_context | ||
|
|
||
|
|
||
| def enable_cache_for_glm_image(pipeline: Any, cache_config: Any) -> Callable[[int], None]: | ||
| """Enable cache-dit for GLM-Image pipeline. | ||
|
|
||
| GLM-Image processes prompt and image by calling the transformer before the | ||
| denoising loop. When an input image is provided (editing mode), the cache must | ||
| be force-refreshed after the preprocessing step so stale hidden states are | ||
| discarded. Set force_refresh_step_hint = 1 for editing, None for text-to-image. | ||
| """ | ||
| db_cache_config = _build_db_cache_config(cache_config) | ||
|
|
||
| calibrator_config = None | ||
| if cache_config.enable_taylorseer: | ||
| calibrator_config = TaylorSeerCalibratorConfig(taylorseer_order=cache_config.taylorseer_order) | ||
| logger.info(f"TaylorSeer enabled with order={cache_config.taylorseer_order}") | ||
|
|
||
| logger.info( | ||
| f"Enabling cache-dit on GLM-Image transformer: " | ||
| f"Fn={db_cache_config.Fn_compute_blocks}, " | ||
| f"Bn={db_cache_config.Bn_compute_blocks}, " | ||
| f"W={db_cache_config.max_warmup_steps}, " | ||
| f"force_refresh_step_hint={db_cache_config.force_refresh_step_hint}, " | ||
| ) | ||
|
|
||
| cache_dit.enable_cache( | ||
| pipeline.transformer, | ||
| cache_config=db_cache_config, | ||
| calibrator_config=calibrator_config, | ||
| ) | ||
|
|
||
| def refresh_cache_context(pipeline: Any, num_inference_steps: int, verbose: bool = True) -> None: | ||
| if cache_config.scm_steps_mask_policy is None: | ||
| cache_dit.refresh_context( | ||
| pipeline.transformer, | ||
| num_inference_steps=num_inference_steps, | ||
| verbose=verbose, | ||
| ) | ||
| else: | ||
| cache_dit.refresh_context( | ||
| pipeline.transformer, | ||
| cache_config=DBCacheConfig().reset( | ||
| num_inference_steps=num_inference_steps, | ||
| steps_computation_mask=cache_dit.steps_mask( | ||
| mask_policy=cache_config.scm_steps_mask_policy, | ||
| total_steps=num_inference_steps, | ||
| ), | ||
| steps_computation_policy=cache_config.scm_steps_policy, | ||
| ), | ||
| verbose=verbose, | ||
| ) | ||
|
Comment on lines
+1184
to
+1195
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to the issue in the Helios enabler, this The fix is to base the refreshed configuration on the existing else:
# Use db_cache_config.reset to preserve original settings
refreshed_config = db_cache_config.reset(
num_inference_steps=num_inference_steps,
steps_computation_mask=cache_dit.steps_mask(
mask_policy=cache_config.scm_steps_mask_policy,
total_steps=num_inference_steps,
),
steps_computation_policy=cache_config.scm_steps_policy,
)
cache_dit.refresh_context(
pipeline.transformer,
cache_config=refreshed_config,
verbose=verbose,
) |
||
|
|
||
| return refresh_cache_context | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is significant code duplication between To improve maintainability and reduce redundancy, consider extracting this common setup logic into a shared helper function. This would make the code easier to manage and prevent potential inconsistencies in the future. |
||
|
|
||
| # Register custom cache-dit enablers after function definitions | ||
| CUSTOM_DIT_ENABLERS.update( | ||
| { | ||
|
|
@@ -998,6 +1119,9 @@ def refresh_cache_context(pipeline: Any, num_inference_steps: int, verbose: bool | |
| "LTX2Pipeline": enable_cache_for_ltx2, | ||
| "LTX2ImageToVideoPipeline": enable_cache_for_ltx2, | ||
| "BagelPipeline": enable_cache_for_bagel, | ||
| "HeliosPipeline": enable_cache_for_helios, | ||
| "HeliosPyramidPipeline": enable_cache_for_helios, | ||
| "GlmImagePipeline": enable_cache_for_glm_image, | ||
| } | ||
| ) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a critical issue in
refresh_cache_context. UsingDBCacheConfig().reset(...)creates a new configuration from defaults, which causes all the original cache settings (likeFn_compute_blocks,max_warmup_steps, etc.) fromdb_cache_configto be lost. This will lead to incorrect and inefficient caching behavior.The fix is to use
db_cache_config.reset(...)to ensure the refreshed configuration is based on the original settings. I've also refactored the logic slightly to remove duplication within the function.