a seeded request drew its noise on the card the pipeline was not using
Z-Image-Turbo, measured 2026-11-01:
Cannot generate a cpu tensor from a generator of type cuda.
generator_device() followed _execution_device, which diffusers documents as
the device an offloaded pipeline COMPUTES on -- not the one it allocates its
initial latents on. randn_tensor is asymmetric about the difference:
if gen_device_type != device.type and gen_device_type == "cpu":
rand_device = "cpu" # draw on the host, copy over. Fine.
elif gen_device_type != device.type and gen_device_type == "cuda":
raise ValueError(f"Cannot generate a {device} tensor from a "
f"generator of type {gen_device_type}.")
So a CPU generator is portable and a CUDA one is a bet that the pipeline wants
CUDA tensors. An offloaded pipeline does not, and only SEEDED requests lost the
bet -- the same shape of failure this function was written for, one layer down:
the first version crashed on a meta device, following _execution_device fixed
that and left this.
Draw on the host unconditionally. It costs one copy of a few MB per request and
buys reproducibility the old behaviour never had: the same seed now gives the
same image whether the model is resident, offloaded or sharded, because the RNG
stream no longer depends on placement. Seeds from before this change produce
different images, which is the price of them working at all.
test_the_execution_device_wins_when_diffusers_offers_one still PASSED after the
change, by coincidence, while asserting a rule that no longer exists; it is now
the offloaded case, and the guarantee that would actually catch a regression --
a CUDA pipeline still gets a host generator -- is tested beside it.
Co-Authored-By:
Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014T3rZozi1Ehk96NG1WesgC
Showing
Please
register
or
sign in
to comment