Fix Helios auto offload decode#14140
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes a device/dtype mismatch in HeliosDecodeStep that occurs when modular Helios pipelines run with component auto CPU offload enabled, by normalizing latents on the per-chunk latent tensor’s device/dtype before casting to the VAE decode dtype.
Changes:
- Move
latents_mean/latents_stdconstruction to use eachchunk_latentstensor’s device and dtype. - Normalize each chunk in-place on the chunk’s device/dtype, then cast to
vae.dtypeprior tovae.decode.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| latents_mean = ( | ||
| torch.tensor(vae.config.latents_mean).view(1, vae.config.z_dim, 1, 1, 1).to( | ||
| chunk_latents.device, chunk_latents.dtype | ||
| ) | ||
| ) |
There was a problem hiding this comment.
Can we just use this?
device = components._exeution_deviceThere was a problem hiding this comment.
I updated this to use components._execution_device in HeliosDecodeStep and moved the latents_mean / latents_std setup out of the chunk loop.
Using chunk_latents.device fixes the mismatch, but it also rebuilds those tensors for every chunk. Since the modular pipeline already uses components._execution_device as the execution source of truth in nearby Helios steps, that seemed like the cleaner fix here.
I also added a regression test for the offload case where vae.device is CPU but decode runs on the execution device.
I reran the full Helios modular test file after that:
DIFFUSERS_TEST_DEVICE=cpu .../test_modular_pipeline_helios.py-> 17 passed, 12 skippedDIFFUSERS_TEST_DEVICE=cuda .../test_modular_pipeline_helios.py-> 25 passed, 4 skipped
|
Hi @pzarzycki, thanks for the PR! It does not appear to link an issue it fixes. If this PR addresses an existing issue, please add a closing keyword (e.g. |
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
| pass | ||
|
|
||
|
|
||
| class DummyHeliosVAE: |
There was a problem hiding this comment.
can you remove the test? we already have offloading test https://github.com/huggingface/diffusers/blob/main/tests/modular_pipelines/test_modular_pipelines_common.py#L350
|
Removed the Helios-specific offload regression test as suggested. I kept the decoder fix and dropped the redundant test/helper block in I also fixed the pending formatter issue on Local validation:
|
Summary
Fixes
HeliosDecodeStepwhen modular Helios pipelines run with component auto CPU offload enabled.The decode step was normalizing chunk latents using
latents_mean/latents_stdtensors created on the VAE device, while the chunk latents themselves could remain on a different device under offload. That caused device mismatches during decode.This change aligns Helios with the working
Wandecoder pattern by normalizing each chunk on the chunk latent tensor's own device and dtype before converting to the VAE decode dtype.Repro
Before this change, the test failed in
src/diffusers/modular_pipelines/helios/decoders.pywith a device mismatch during decode under auto CPU offload.Implementation
HeliosDecodeStepinsrc/diffusers/modular_pipelines/helios/decoders.pylatents_mean/latents_stdon each chunk latent tensor's device and dtypeTests
Ran on accelerator-backed setup:
Results:
Also ran CPU-mode validation:
Result: