From 5c249ebada2e182d3e00353d7fb8e8698b8fe7d6 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Mon, 6 Jul 2026 09:31:10 +0000 Subject: [PATCH] video: use the quantized FBCache threshold when the transformer is quantized apply_step_cache on the video load path omitted quant_active, so a quantized video transformer (an engaged dense transformer_quant, or a GGUF checkpoint) that also enabled First-Block-Cache without an explicit threshold used the dense bf16 threshold (0.08) instead of the higher quantized threshold (0.12) the cache helper documents as needed for quantized transformers to trigger. The advertised quant plus FBCache path therefore cached far less than intended. Thread quant_active through exactly as the image path (diffusion.py) does: an engaged transformer_quant or a GGUF transformer both count as quant-active here. --- studio/backend/core/inference/video.py | 5 +++ studio/backend/tests/test_video_backend.py | 41 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/studio/backend/core/inference/video.py b/studio/backend/core/inference/video.py index 9a3a1d82e0..6c4edf523d 100644 --- a/studio/backend/core/inference/video.py +++ b/studio/backend/core/inference/video.py @@ -964,6 +964,11 @@ class VideoBackend: view, mode = normalize_transformer_cache(transformer_cache), threshold = transformer_cache_threshold, + # A quantized transformer's block residuals are larger, so it needs the + # higher FBCache trigger threshold to cache at all. Mirror the image path + # (diffusion.py): both an engaged transformer_quant AND a GGUF checkpoint + # (quantized weights) count as quant-active here. + quant_active = transformer_quant_engaged is not None or kind == "gguf", logger = logger, ) if view is pipe: diff --git a/studio/backend/tests/test_video_backend.py b/studio/backend/tests/test_video_backend.py index 80cc2a43fb..70aea4c725 100644 --- a/studio/backend/tests/test_video_backend.py +++ b/studio/backend/tests/test_video_backend.py @@ -778,6 +778,47 @@ def test_wan_ti2v_single_dit_only_touches_one(fake_runtime): assert pipe.transformer.cache_config is not None +def test_video_quant_load_raises_fbcache_threshold(fake_runtime, monkeypatch): + # Regression: a quantized video transformer's block residuals are larger, so it needs + # the higher FBCache trigger threshold to cache at all. The load must thread quant_active + # into apply_step_cache like the image path does. With transformer_quant engaged and no + # explicit threshold the engaged config must carry QUANT_FBCACHE_THRESHOLD (0.12); a plain + # bf16 load uses the dense default (0.08), proving the discrimination. + import core.inference.video as video_mod + from core.inference.diffusion_cache import ( + DEFAULT_FBCACHE_THRESHOLD, + QUANT_FBCACHE_THRESHOLD, + ) + + monkeypatch.setattr(video_mod, "dense_transformer_supported", lambda target: True) + monkeypatch.setattr( + video_mod, + "quantize_transformer", + lambda view, target, *, mode, family, logger = None: "int8", + ) + + quant = VideoBackend() + quant.load_pipeline( + "Wan-AI/Wan2.2-TI2V-5B-Diffusers", + model_kind = "pipeline", + transformer_quant = "int8", + transformer_cache = "fbcache", + ) + quant_cfg = quant._state.pipe.transformer.cache_config + assert quant_cfg is not None + assert quant_cfg[1] == QUANT_FBCACHE_THRESHOLD + + dense = VideoBackend() + dense.load_pipeline( + "Wan-AI/Wan2.2-TI2V-5B-Diffusers", + model_kind = "pipeline", + transformer_cache = "fbcache", + ) + dense_cfg = dense._state.pipe.transformer.cache_config + assert dense_cfg is not None + assert dense_cfg[1] == DEFAULT_FBCACHE_THRESHOLD + + def test_wan_a14b_dense_quant_applies_to_both_dits(fake_runtime, monkeypatch): # transformer_quant on a pipeline load quantises the dense DiT(s). On CPU the real # dense path is unsupported, so stub the two quant seams to record which pipe view