Skip to content

[diffusion] Skip zero blocks when hashing large conditioning inputs - #42748

Merged
mickqian merged 2 commits into
sgl-project:mainfrom
niehen6174:perf/conditioning-sparse-fingerprint
Oct 6, 2026
Merged

mickqian merged 2 commits into
sgl-project:mainfrom
niehen6174:perf/conditioning-sparse-fingerprint

Conversation

@niehen6174

@niehen6174 niehen6174 commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

Since the conditioning cache (#40470), every single-GPU image-to-video request spends 0.4–1 s hashing its VAE input, even when the cache misses. Diffusion CI shows this as a flaky stage check on longlive2_i2v.

ImageVAEEncodingStage passes vae.encode a video tensor made of the image followed by num_frames - 1 zero frames. For the longlive2_i2v CI case this is a 652 MB fp32 tensor ([1, 3, 61, 928, 960]). _fingerprint copied all of it to pageable host memory and ran sha256 over it:

CI H100 profile, LongLive2ImageVAEEncodingStage Time
D2H copy of 652 MB at 1.9 GB/s 337 ms
sha256 on host 373 ms
Stage total, cache on / --disable-conditioning-cache 1675 / 962 ms

In CI every request misses, so this is pure overhead. On a hit, the hash alone still costs about as much as the encode it saves on H100.

CI impact. The stage baseline is 920 ms and the PR limit is 1657 ms (80% + 120 ms pad).

Other CI cases were not affected. cached_vae_encode bypasses the cache when world size > 1, and the Wan I2V cases run on 2 GPUs. Single-GPU Wan I2V outside CI pays the same cost: +0.42 s at 480P and +0.96 s at 720P with 81 frames.

Modifications

  • _tensor_digest: for CUDA tensors of at least 16 MiB, find the nonzero 64 KiB blocks with one amax on the device. Hash the block bitmap plus the bytes of the nonzero blocks only.
  • Zero bytes are compared bit by bit, so -0.0 is not treated as 0.0. Together with dtype, shape and stride, the key still identifies every byte. Cache semantics are unchanged.
  • Smaller tensors and CPU tensors keep the existing path.
  • Test: equal content hits. A miss is required for a -0.0 in a zero frame, for a change in the last byte, and for a frame shift.

Validation

RTX 5090, real ConditioningCache, LongLive2 and Wan2.1 VAEs, a new image per request as in CI. Times are synced medians of 4 runs.

VAE encode, cache on − off Before After
LongLive2, 960x928x61 (CI shape) +703 ms +12 ms
Wan2.1 I2V, 832x480x81 +423 ms +6 ms
Wan2.1 I2V, 1280x720x81 +959 ms +13 ms
Cache hit, LongLive2 703 ms 10 ms
  • A dense 652 MB input with no zero blocks takes 679 ms before and 680 ms after, so there is no slowdown.
  • Tests: test_conditioning_cache.py 34 passed. test_text_encoding_cache.py, test_conditioning_model_boundaries.py and test_multi_output_grouping.py: 98 passed, 1 skipped.
  • The _fingerprint cost for the CI shape is the same on H100 CI (710 ms) and on the RTX 5090 (711 ms). I expect LongLive2ImageVAEEncodingStage on CI to return to about 930 ms, but this has not been measured on H100 yet.

CI States

Latest PR Test (Base): ✅ Run #37447684529
Latest PR Test (Extra): ❌ Run #37448281811
Latest PR Test (AMD ROCm 10): ⏳ Run #37447684513

@github-actions github-actions Bot added the diffusion SGLang Diffusion label Oct 6, 2026
@niehen6174 niehen6174 added the run-ci CI: run the baseline test suite on this PR label Oct 6, 2026
@niehen6174

Copy link
Copy Markdown
Collaborator Author

/tag-and-rerun-ci

@mickqian
mickqian merged commit 2a5f45d into sgl-project:main Oct 6, 2026
220 of 247 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

diffusion SGLang Diffusion run-ci CI: run the baseline test suite on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants