Skip to content

Fix self.vae reference in modular SDXL inpaint VAE encoder - #14679

Open
Devam0311 wants to merge 2 commits into
huggingface:mainfrom
Devam0311:sdxl-modular-inpaint-vae
Open

Fix self.vae reference in modular SDXL inpaint VAE encoder#14679
Devam0311 wants to merge 2 commits into
huggingface:mainfrom
Devam0311:sdxl-modular-inpaint-vae

Conversation

@Devam0311

@Devam0311 Devam0311 commented Sep 1, 2026

Copy link
Copy Markdown

Issue link: this addresses Issue 5 of #13610.
I have deliberately not used a Fixes keyword: #13610 tracks 7 separate findings, so a closing keyword would close it as soon as this one merges while the others are still open. Happy for the no-issue-needed label to be applied, or I can add a closing keyword if you would rather the review issue be closed and reopened.

What does this PR do?

Fixes Issue 5 of #13610 (stable_diffusion_xl model/pipeline review).

StableDiffusionXLInpaintVaeEncoderStep._encode_vae_image reads self.vae.config.scaling_factor, but self here is the block, not the components object:

if latents_mean is not None and latents_std is not None:
    ...
    image_latents = (image_latents - latents_mean) * self.vae.config.scaling_factor / latents_std
    #                                                ^^^^ block, not components
else:
    image_latents = components.vae.config.scaling_factor * image_latents   # correct, two lines below

Reproduced on main:

AttributeError: 'StableDiffusionXLInpaintVaeEncoderStep' object has no attribute 'vae'

So any inpaint modular pipeline whose VAE config defines latents_mean and latents_std fails outright. The equivalent non-inpaint encoder in the same file already uses components.vae.

Solution

One-word fix — self.vaecomponents.vae — matching the else branch directly below it and the non-inpaint encoder above it.

Testing

TestSDXLInpaintVaeEncoderStep::test_encode_vae_image_with_latents_mean_and_std drives the method with a stand-in VAE, as the issue's reproduction does. That is deliberate rather than lazy: the branch only executes for a VAE config carrying latents_mean / latents_std, which the SDXL VAE used elsewhere in that test file does not define, so the existing fixtures cannot reach it.

With latents_mean=0 and latents_std=1 the branch reduces to a plain scaling_factor multiply, so the test asserts the exact expected values rather than just the absence of an exception.

Verified it catches the bug: with the fix reverted it fails with the AttributeError above.

pytest tests/modular_pipelines/stable_diffusion_xl/   -> 47 passed, 16 skipped
ruff check / ruff format --check                      -> clean
git diff --check                                      -> clean

Before submitting

Self-review notes

Reviewed against .ai/references/review-rules.md, modular.md and testing.md. No blocking issues.

For the reviewer:

  1. The new test class subclasses nothing and holds no pipeline fixtures, unlike the rest of that file. That is intentional — it is a unit test of one method on one block, and building a full modular pipeline with a latents_mean/latents_std VAE just to reach one line seemed disproportionate. Happy to fold it into the existing tester config instead if you'd prefer consistency.
  2. This is a pure bug fix: the branch could not previously execute without raising, so there is no behaviour to preserve.
  3. Scope kept to Issue 5. Issues 2 and 4 of stable_diffusion_xl model/pipeline review #13610 are in Use negative crop coordinates when building SDXL negative time ids #14676 and Do not watermark or postprocess SDXL latent output #14678.

Who can review?

@yiyixuxu @asomoza @DN6

`StableDiffusionXLInpaintVaeEncoderStep._encode_vae_image` read
`self.vae.config.scaling_factor`, but `self` is the block, not the
components object. Any inpaint modular pipeline whose VAE config defines
`latents_mean` and `latents_std` therefore failed with
`AttributeError: 'StableDiffusionXLInpaintVaeEncoderStep' object has no
attribute 'vae'`.

Use `components.vae`, as the surrounding lines and the equivalent
non-inpaint encoder already do.

Add a regression test driving the method with a stand-in VAE, since the
branch only runs for a config carrying `latents_mean` / `latents_std`.

Ref huggingface#13610 (Issue 5)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XBYeq5vB4DNZDEaqUsroKR
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Hi @Devam0311, 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. Fixes #1234) to the PR description so the issue is linked. See the contribution guide for more details. If this PR intentionally does not fix a tracked issue, a maintainer can add the no-issue-needed label to silence this reminder.

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 no-issue-needed label), you can ignore this message — it stays here as a comment, but it no longer applies.

@adi-IL adi-IL left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Tested locally on Linux x86_64 with python 3.14 and torch 2.13.

Confirmed that StableDiffusionXLInpaintVaeEncoderStep._encode_vae_image raised AttributeError: 'StableDiffusionXLInpaintVaeEncoderStep' object has no attribute 'vae' on main whenever latents_mean and latents_std were present, because vae lives on components, not self.

With this fix to components.vae.config.scaling_factor, the normalization branch runs cleanly and matches the fallback in the else branch. The new unit test passes.

@Devam0311
Devam0311 requested a review from adi-IL September 3, 2026 05:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants