Skip to content

Fix NameError in ZImageOmniPipeline when guidance_scale=0#13527

Open
Ricardo-M-L wants to merge 1 commit intohuggingface:mainfrom
Ricardo-M-L:fix-z-image-omni-nameerror-guidance-zero
Open

Fix NameError in ZImageOmniPipeline when guidance_scale=0#13527
Ricardo-M-L wants to merge 1 commit intohuggingface:mainfrom
Ricardo-M-L:fix-z-image-omni-nameerror-guidance-zero

Conversation

@Ricardo-M-L
Copy link
Copy Markdown
Contributor

What this PR does

ZImageOmniPipeline.__call__ defines negative_condition_siglip_embeds only inside the CFG guard:

https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/z_image/pipeline_z_image_omni.py#L581-L582

if self.do_classifier_free_guidance:
    negative_condition_siglip_embeds = [[se.clone() for se in batch] for batch in condition_siglip_embeds]

but a few lines later reads the same name unconditionally:

https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/z_image/pipeline_z_image_omni.py#L590-L593

condition_siglip_embeds = [None if sels == [] else sels + [None] for sels in condition_siglip_embeds]
negative_condition_siglip_embeds = [
    None if sels == [] else sels + [None] for sels in negative_condition_siglip_embeds
]

Why this is a real bug

do_classifier_free_guidance is self._guidance_scale > 0 (line 342), so any call with guidance_scale=0.0 leaves negative_condition_siglip_embeds unbound → NameError: name 'negative_condition_siglip_embeds' is not defined.

This is the exact configuration the pipeline's own EXAMPLE_DOC_STRING uses:

https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/z_image/pipeline_z_image_omni.py#L51-L58

>>> image = pipe(
...     prompt,
...     height=1024,
...     width=1024,
...     num_inference_steps=9,
...     guidance_scale=0.0,
...     generator=torch.Generator("cuda").manual_seed(42),
... ).images[0]

i.e. running the documented Z-Image-Turbo snippet crashes. The downstream consumption (line 648) is already guarded by if apply_cfg:, so the negative reshape only needs to fire when CFG is on.

Fix

Wrap the negative reshape in the same do_classifier_free_guidance check — matching the symmetric treatment of negative_condition_latents, which is only defined and only consumed when CFG is on.

 condition_siglip_embeds = [None if sels == [] else sels + [None] for sels in condition_siglip_embeds]
-negative_condition_siglip_embeds = [
-    None if sels == [] else sels + [None] for sels in negative_condition_siglip_embeds
-]
+if self.do_classifier_free_guidance:
+    negative_condition_siglip_embeds = [
+        None if sels == [] else sels + [None] for sels in negative_condition_siglip_embeds
+    ]

Before submitting

  • Did you read the contributor guideline?
  • Was this discussed/approved via a Github issue or the forum? N/A — crashes the pipeline's own doc example.
  • Did you make sure to update the documentation with your changes? N/A.
  • Did you write any new necessary tests? N/A — restores behavior matching the doc example.

Who can review?

@yiyixuxu @sayakpaul

@github-actions github-actions Bot added pipelines size/S PR with diff < 50 LOC labels Apr 21, 2026
Copy link
Copy Markdown
Collaborator

@yiyixuxu yiyixuxu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

@HuggingFaceDocBuilderDev
Copy link
Copy Markdown

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.

@Ricardo-M-L
Copy link
Copy Markdown
Contributor Author

Friendly ping — this PR has been approved. Is there anything else needed before merging? Happy to make any requested changes.

`ZImageOmniPipeline.__call__` only defines `negative_condition_siglip_embeds`
inside a `if self.do_classifier_free_guidance:` block:

    if self.do_classifier_free_guidance:
        negative_condition_siglip_embeds = [
            [se.clone() for se in batch] for batch in condition_siglip_embeds
        ]

but later reads the name unconditionally when reshaping:

    condition_siglip_embeds = [None if sels == [] else sels + [None] for sels in condition_siglip_embeds]
    negative_condition_siglip_embeds = [
        None if sels == [] else sels + [None] for sels in negative_condition_siglip_embeds
    ]

`do_classifier_free_guidance` is defined as `self._guidance_scale > 0`,
so any call with `guidance_scale=0.0` raises `NameError`. This is the
exact configuration the pipeline's own `EXAMPLE_DOC_STRING` uses
(`guidance_scale=0.0` for the Z-Image-Turbo distilled checkpoint),
so running the documented snippet crashes.

The downstream consumption at

    condition_siglip_embeds_model_input = condition_siglip_embeds + negative_condition_siglip_embeds

is already guarded by `if apply_cfg:`, so we only need to guard the
reshape step to match. Wrap the negative-branch list comprehension in
the same CFG check, matching the symmetric treatment of
`negative_condition_latents` (which is already only defined when
`do_classifier_free_guidance` is true and used only in the CFG branch
of the denoise loop).
@Ricardo-M-L Ricardo-M-L force-pushed the fix-z-image-omni-nameerror-guidance-zero branch from e93f057 to 56a6219 Compare April 27, 2026 14:52
@github-actions github-actions Bot added size/S PR with diff < 50 LOC and removed size/S PR with diff < 50 LOC labels Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pipelines size/S PR with diff < 50 LOC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants