diff --git a/recipes/MiniMaxAI/MiniMax-H3.md b/recipes/MiniMaxAI/MiniMax-H3.md index 96e67d1ae5d..3facd0a0198 100644 --- a/recipes/MiniMaxAI/MiniMax-H3.md +++ b/recipes/MiniMaxAI/MiniMax-H3.md @@ -1061,6 +1061,42 @@ balanced switch order. > workload. The values above apply to this deployment and are not universal > guarantees. `lossless` remains the exact reference path. +## Cache-DiT and TaylorSeer + +A server-level Cache-DiT profile is selected with `--cache-backend cache_dit` +plus `--cache-config '{...}'`. The optional TaylorSeer calibrator extrapolates +the steps Cache-DiT skips; its state grows with the extrapolation order and +with the number of consecutive cached steps. + +The validated profile is `taylorseer_order=2` with +`max_continuous_cached_steps=4` (the MiniMax-H3-NPU recipe's cache config): +an independent controlled run on 910B3 (v0.30.0) kept it clean at 5/10/15 s +outputs (SSIM 0.848/0.861/0.781), while raising `max_continuous_cached_steps` +to 6 with the same order produced the artifact (SSIM 0.798), and a probe of +the same calibrator measured order-2 extrapolation error growing +quadratically with consecutive cached steps +([comment](https://github.com/vllm-project/vllm-omni/issues/8805#issuecomment-6340466984)). +On Ref2VA videos of 10 s and longer this combination shows up as a localized +translucent dark artifact on the subject (same seed, prompt, references, and +dense attention; `main@9778e52bd`, 910C): with +`Fn_compute_blocks=1, Bn_compute_blocks=0, max_warmup_steps=4, +residual_diff_threshold=0.4, max_continuous_cached_steps=6`, the order-2 run +showed a dark shoulder-region smear and a second-half mean-luminance drop +(78.1 → 73.2), while the identical run with `enable_taylorseer=false` stayed +clean and brightened (78.8 → 81.5). The server logs a warning when a profile +leaves this envelope — order 2 with `max_continuous_cached_steps` above 4, or +any order above 2, which has no validated window; for such profiles disable +`enable_taylorseer`. The same report measured no +meaningful end-to-end speedup from TaylorSeer on H3 (122.0 s vs 121.9 s per +video), so treat it as optional. See #8805 for the reproduction data. + +On 64 GB-class NPU dies with distributed layerwise offload, Cache-DiT and DLO +together leave under 1 GiB of device headroom (the offload weight pool holds +the full model at sequence-parallel `tp=1`), so cached requests can fail with +an NPU OOM at an arbitrary step. Prefer the uncached path on such +deployments, or reduce `max_continuous_cached_steps`, and track #7618 for the +request-boundary memory release work. + ## Exact AdaLN reuse H3 enables exact AdaLN projection reuse by default, independently of the task, diff --git a/tests/diffusion/cache/test_cache_dit.py b/tests/diffusion/cache/test_cache_dit.py index 8c5915e9216..d90e0314462 100644 --- a/tests/diffusion/cache/test_cache_dit.py +++ b/tests/diffusion/cache/test_cache_dit.py @@ -6,6 +6,7 @@ """ import ast +import logging from contextlib import contextmanager from pathlib import Path from types import SimpleNamespace @@ -19,6 +20,9 @@ import vllm_omni.diffusion.cache.cachedit as cd_backend import vllm_omni.diffusion.cache.cachedit.model_specific as cd_model_specific from vllm_omni.diffusion.cache.cachedit import CacheDiTAdapterConfig, CacheDiTBackend, cache_summary +from vllm_omni.diffusion.cache.cachedit.config import ( + VALIDATED_TAYLORSEER_MAX_CONTINUOUS_CACHED_STEPS, +) from vllm_omni.diffusion.config import set_current_diffusion_config from vllm_omni.diffusion.data import AttentionConfig, DiffusionCacheConfig from vllm_omni.diffusion.models.cosmos3.transformer_cosmos3 import Cosmos3VFMTransformer @@ -451,3 +455,58 @@ def test_mammothmoda2_cache_dit_runs_end_to_end_on_tiny_model(init_fake_tp_group assert latents.shape == (1, 4, 8, 8) assert torch.isfinite(latents).all() + + +def _taylorseer_warning_logged(caplog) -> bool: + return any( + "validated cache window" in record.getMessage() + for record in caplog.records + if record.levelno >= logging.WARNING + ) + + +def test_taylorseer_order_two_long_window_warns(caplog): + config = cd_backend.CacheDiTConfig( + enable_taylorseer=True, + taylorseer_order=2, + max_continuous_cached_steps=VALIDATED_TAYLORSEER_MAX_CONTINUOUS_CACHED_STEPS + 2, + ) + with caplog.at_level("WARNING"): + calibrator = config.to_calibrator_config() + + assert calibrator is not None + assert _taylorseer_warning_logged(caplog) + + +def test_taylorseer_order_two_validated_window_does_not_warn(caplog): + config = cd_backend.CacheDiTConfig( + enable_taylorseer=True, + taylorseer_order=2, + max_continuous_cached_steps=VALIDATED_TAYLORSEER_MAX_CONTINUOUS_CACHED_STEPS, + ) + with caplog.at_level("WARNING"): + calibrator = config.to_calibrator_config() + + assert calibrator is not None + assert not _taylorseer_warning_logged(caplog) + + +def test_taylorseer_order_above_two_warns_without_validated_window(caplog): + config = cd_backend.CacheDiTConfig( + enable_taylorseer=True, + taylorseer_order=3, + max_continuous_cached_steps=VALIDATED_TAYLORSEER_MAX_CONTINUOUS_CACHED_STEPS, + ) + with caplog.at_level("WARNING"): + calibrator = config.to_calibrator_config() + + assert calibrator is not None + assert _taylorseer_warning_logged(caplog) + + +def test_taylorseer_order_one_does_not_warn(caplog): + config = cd_backend.CacheDiTConfig(enable_taylorseer=True, taylorseer_order=1) + with caplog.at_level("WARNING"): + config.to_calibrator_config() + + assert not _taylorseer_warning_logged(caplog) diff --git a/vllm_omni/diffusion/cache/cachedit/config.py b/vllm_omni/diffusion/cache/cachedit/config.py index 8fcaa517be3..b00d4ce22bf 100644 --- a/vllm_omni/diffusion/cache/cachedit/config.py +++ b/vllm_omni/diffusion/cache/cachedit/config.py @@ -20,6 +20,9 @@ logger = init_logger(__name__) +# Cache window validated for TaylorSeer order 2 on MiniMax-H3 Ref2VA (#8805). +VALIDATED_TAYLORSEER_MAX_CONTINUOUS_CACHED_STEPS = 4 + @dataclass class CacheDiTAdapterConfig: @@ -90,7 +93,34 @@ def to_calibrator_config(self) -> CalibratorConfig | None: return None logger.info("TaylorSeer enabled with order=%s", self.taylorseer_order) + if self.taylorseer_order > 2: + logger.warning( + "TaylorSeer order=%s has no validated cache window (#8805 " + "validated order 2 with max_continuous_cached_steps<=%s); " + "disable enable_taylorseer unless this configuration has " + "been validated.", + self.taylorseer_order, + VALIDATED_TAYLORSEER_MAX_CONTINUOUS_CACHED_STEPS, + ) + elif ( + self.taylorseer_order == 2 + and self.max_continuous_cached_steps > VALIDATED_TAYLORSEER_MAX_CONTINUOUS_CACHED_STEPS + ): + logger.warning( + "TaylorSeer order=2 with max_continuous_cached_steps=%s " + "exceeds the validated cache window (order=2 with " + "max_continuous_cached_steps=%s): order-2 extrapolation error " + "grows quadratically with consecutive cached steps and can " + "produce localized artifacts on Ref2VA videos (#8805). " + "Disable enable_taylorseer for longer cache windows.", + self.max_continuous_cached_steps, + VALIDATED_TAYLORSEER_MAX_CONTINUOUS_CACHED_STEPS, + ) return TaylorSeerCalibratorConfig(taylorseer_order=self.taylorseer_order) -__all__ = ["CacheDiTAdapterConfig", "CacheDiTConfig"] +__all__ = [ + "CacheDiTAdapterConfig", + "CacheDiTConfig", + "VALIDATED_TAYLORSEER_MAX_CONTINUOUS_CACHED_STEPS", +]