Uh oh!
There was an error while loading. Please reload this page.
Synchronize the compute stream before offloading to disk - #14657
Synchronize the compute stream before offloading to disk#14657jiqing-feng wants to merge 2 commits into
Conversation
`_offload_to_disk` releases the onloaded tensors at the end, returning their device memory to the allocator while the compute stream may still be reading them. The memory is then reused by the next onload, so the in-flight kernel reads foreign data and the output becomes NaN. `_offload_to_memory` already synchronizes for this reason, do the same on the disk path. Reproducer: tests/models/autoencoders/test_models_autoencoder_vidtok.py::TestAutoencoderVidTokMemory::test_group_offloading_with_disk[leaf_level-False]
Hi @jiqing-feng, 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. Please note that PRs without a linked issue are likely to be automatically closed 10 days after this notice. Once the PR links an issue (or gets the |
jiqing-feng
commented
Sep 2, 2026
Hi @sayakpaul . Would you please review this pr if you have bandwidth? Thanks! |
sayakpaul
commented
Sep 2, 2026
/diffusers-bot pytest tests/models -k "test_group_offloading_with_disk" |
|
sayakpaul
commented
Sep 2, 2026
@jiqing-feng thanks for the PR. I just triggered the respective CI for this. Let's see how it pans out. |
jiqing-feng
commented
Sep 2, 2026
The job seems been cancelled. |
sayakpaul
commented
Sep 2, 2026
/diffusers-bot pytest tests/models -k "test_group_offloading_with_disk" |
✅ |
What is fixed
Group offloading to disk produces all-NaN output with
offload_type="leaf_level",use_stream=Trueandrecord_stream=False.Reproducer on
main:Why
_offload_to_diskends withtensor_obj.data = torch.empty_like(tensor_obj.data, device=self.offload_device), which returns the on-device weight memory to the allocator. It runs on the host thread frompost_forward, while kernels on the compute stream may still be reading those weights. The allocator hands the block to the next group's onload, so the in-flight kernel reads foreign data and the result becomes NaN._offload_to_memoryalready guards this withcurrent_stream().synchronize(); the disk path did not, so this PR adds the same guard.Only that one combination fails because every other one removes the race:
record_stream=Truemakes the allocator aware that the compute stream still owns the block, the memory path already synchronizes, andblock_levelgroups are coarse enough that the offload never overlaps the next onload. Nothing here is device specific, the CUDA allocator just happens to pick a different block.Validation
All eight
offload_typexoffload_to_diskxrecord_streamcombinations of the VidTok autoencoder now match the non-offloaded output atatol=1e-5, andtests/hooks/test_group_offloading.pyplustests/models/autoencoders/test_models_autoencoder_vidtok.pypass (50 passed, 3 skipped for the memory tests, 38 passed for the hook tests). Tested on Intel Arc Pro B60 withtorch 2.13.0+xpu.