You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
QwenImage21Pipeline: image editing ignores the instruction and returns a haloed near-copy at output_resolution=1024 (default); 512/768 edit correctly #14824
With QwenImage21Pipeline, image editing at the default output_resolution=1024 ignores the instruction and returns an over-sharpened, haloed, over-saturated near-copy of the input image. The same call with output_resolution=512 or 768 produces a correct, clean edit.
This does not depend on the prefix KV cache (use_kv_cache=False gives the same image), on guidance (true_cfg_scale=4.0 adds a red band where the scarf should be but keeps the halo), on the transformers version (5.14.1 and 5.17.0 produce bit-identical results), or on precision (fp32 end to end gives the same image as bf16 to 43 dB PSNR).
An independent re-implementation of this pipeline in another framework (Swift/MLX, block-level parity with the diffusers transformer at fp32) reproduces the 1024² output from the same noise to 36 dB (bf16) / 54 dB (fp32) PSNR, so the behaviour follows from the pipeline's math as written rather than from a backend. I have only tested on Apple silicon (MPS), so a CUDA confirmation would be useful.
Observed at output_resolution=1024 for two prompts ("Make the dog wear a red scarf", "Change the background to a sunset beach") on a natural photo generated by the pipeline itself, and for a synthetic image; at 320² and 512²/768² the same edits are correct.
Questions this raises, in case they help locate it:
Is 1024² (4,096 condition + 4,096 target tokens) inside the trained editing regime, or should output_resolution default lower / be capped for edits?
QwenImage21Rope advances the frame position by max(h, w) after each image block, so the condition→target frame offset grows with the grid (20 at 320², 64 at 1024²). Is that the training convention?
calculate_shift is fed latents.shape[1] (target tokens only) while the joint sequence is twice that for a 1-image edit. Intended?
Reproduction
importtorchfromdiffusersimportQwenImage21Pipelinepipe=QwenImage21Pipeline.from_pretrained("Qwen/Qwen-Image-2.1", torch_dtype=torch.bfloat16).to("mps") # or "cuda"# 1) a natural photo from the model itselfphoto=pipe(
prompt="A photo of a golden retriever sitting on a wooden dock by a calm lake, soft morning daylight, shallow depth of field",
width=1024, height=1024, num_inference_steps=40,
generator=torch.Generator("cpu").manual_seed(42),
).images[0]
photo.save("photo.png")
# 2) the same edit at three output resolutionsforresin (512, 768, 1024):
img=pipe(
prompt="Make the dog wear a red scarf",
image=photo, output_resolution=res, num_inference_steps=40,
generator=torch.Generator("cpu").manual_seed(42),
).images[0]
img.save(f"scarf_{res}.png")
# variants that do NOT change the 1024 result:# use_kv_cache=False# true_cfg_scale=4.0, negative_prompt=" " (partial: a red band appears, halo remains)# torch_dtype=torch.float32 end to end
Results (40 steps, seed 42, same inputs):
output_resolution
use_kv_cache
true_cfg_scale
dtype
result
512
True
1.0
bf16
correct: red scarf, photo otherwise intact
768
True
1.0
bf16
correct
1024 (default)
True
1.0
bf16
instruction ignored; haloed, over-sharpened near-copy of the input
1024
False
1.0
bf16
identical to the row above
1024
True
4.0
bf16
scarf-like red band, halo remains
1024
True
1.0
fp32
same halo (43.4 dB PSNR vs the bf16 render)
Text-to-image at 1024² and 2048² is fine with the same install; the text encoder output is unchanged between transformers 5.14.1 and 5.17.0 (bit-identical hidden states for text-only and image-conditioned prompts).
Logs
No errors or warnings are emitted; the pipeline completes normally in every configuration.
Describe the bug
With
QwenImage21Pipeline, image editing at the defaultoutput_resolution=1024ignores the instruction and returns an over-sharpened, haloed, over-saturated near-copy of the input image. The same call withoutput_resolution=512or768produces a correct, clean edit.This does not depend on the prefix KV cache (
use_kv_cache=Falsegives the same image), on guidance (true_cfg_scale=4.0adds a red band where the scarf should be but keeps the halo), on the transformers version (5.14.1 and 5.17.0 produce bit-identical results), or on precision (fp32 end to end gives the same image as bf16 to 43 dB PSNR).An independent re-implementation of this pipeline in another framework (Swift/MLX, block-level parity with the diffusers transformer at fp32) reproduces the 1024² output from the same noise to 36 dB (bf16) / 54 dB (fp32) PSNR, so the behaviour follows from the pipeline's math as written rather than from a backend. I have only tested on Apple silicon (MPS), so a CUDA confirmation would be useful.
Observed at
output_resolution=1024for two prompts ("Make the dog wear a red scarf", "Change the background to a sunset beach") on a natural photo generated by the pipeline itself, and for a synthetic image; at 320² and 512²/768² the same edits are correct.Questions this raises, in case they help locate it:
output_resolutiondefault lower / be capped for edits?QwenImage21Ropeadvances the frame position bymax(h, w)after each image block, so the condition→target frame offset grows with the grid (20 at 320², 64 at 1024²). Is that the training convention?calculate_shiftis fedlatents.shape[1](target tokens only) while the joint sequence is twice that for a 1-image edit. Intended?Reproduction
Results (40 steps, seed 42, same inputs):
Text-to-image at 1024² and 2048² is fine with the same install; the text encoder output is unchanged between transformers 5.14.1 and 5.17.0 (bit-identical hidden states for text-only and image-conditioned prompts).
Logs
System Info
Who can help?
@yiyixuxu @sayakpaul (authors of #14804)