Repository navigation
[diffusion] keep Qwen-Image 2.1 prefix KV per layer under Cache-DiT - #40472
Merged
Merged
Conversation
UnifiedBlocks forwards the same extras to every layer, so call-site [cache[i]] after wrap reused caches[0] and wrote color noise.
Cover the native loop, the UnifiedBlocks same-args path, and the old first-slot broadcast that shared caches[0] across layers.
Cookbook the per-layer KV wrap and list 2.1 on the Cache-DiT supported-model table.
niehen6174
requested review from
AgainstEntropy,
BBuf,
HaiShaw,
JustinTong0323,
mickqian,
ping1jing2,
sogalin,
wisclmy0611,
yichiche and
zijiexia
as code owners
September 20, 2026 15:52
Collaborator
Author
|
/tag-and-rerun-ci |
Collaborator
Author
|
/tag-and-rerun-ci |
This was referenced Oct 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
#39983 registered Cache-DiT on 2.1 (
Pattern_3/transformer_blocks). The B200 check ran, butUnifiedBlocksstill forwards the same extras to every layer.2.1 prefix KV is per layer. The native loop sliced at the call site (
[cache[i] for cache in prefix_caches]). After the wrap that loop runs once withi == 0. Layer 0 fills the emptycaches[0]dict; layers 1–31 treat it as a hit and reuse layer 0's prefix. Same knobs, same denoise wall-clock: teapot at ~28–30 dB vs color noise at 8.02 dB. Wiring bug, not an aggressive residual.How to fix
Each block keeps a stable
_layer_idand slicesprefix_cachesitself. The outer loop always passes the full list, so Cache-DiT wrap and the native path share one contract (same idea as Hunyuan's_layer_id). Allocate fallback caches fromself.num_layers, notlen(transformer_blocks)after the wrap.Do not land the earlier
hasattr/ per-call_prefix_cachesbind: it fixed the noise but is a side-channel, and a missed bind silently shares layer 0 again. Sage / kitchen stay flag-only.Lossy stack on 1× RTX 4090 24GB (Ada)
T2I 1024×1024, 40-step, CFG=1, seed 42,
A red ceramic teapot on a wooden table. DiT layerwise (prefetch=1). Base = BF16 + SDPA, no Cache / Sage / quant. PSNR is vs that same-regime base PNG. Numbers are denoise only — Cache-DiT does not change encode.--attention-backend sage_attn)--quantization kitchen_int8)Fn=1,Bn=0,W=4,R=0.24,MC=3--enable-cache-dit)All successful rows are a clean red teapot. Hit count stays 13 full / 27 cached. Kitchen halves DiT H2D on full steps (~670 → ~343 ms). Sage is invisible alone (FA hidden behind copy); on Cache+kitchen it shaves another 0.85 s.
Layerwise 24GB Ada only. Do not cross-compare with resident H200/B200. Sage3 / SVDQ / NVFP4 / Spectrum / TeaCache / Distill stay paused here.
Recommend (this card): quality → base, or kitchen INT8 if lossy is OK (31.15 dB). Denoise speed → Cache + kitchen + Sage. Do not enable Sage by itself.
Cookbook
docs/cookbook/diffusion/Qwen-Image/Qwen-Image-2.1.mdxdocuments--enable-cache-ditand that each block slices by_layer_id(without that, color noise). It does not publish the 4090 speedup table — that is one-card layerwise evidence, not a picker recipe.cache_dit.mdxlists Qwen-Image 2.1.Test plan
python -m pytest sglang/multimodal_gen/test/unit/test_qwen_image21.py -k "prefix_kv or first_slot"--enable-cache-dit true40-step T2I on 4090: teapot, not color noise (28.24 dB vs same-run base)CI States
Latest PR Test (Base): ✅ Run #35520933028
Latest PR Test (Extra): ❌ Run #35520932843
Latest PR Test (AMD ROCm 10): ❌ Run #35520933042