huggingface / huggingface/diffusers
Pipeline properties that read attributes __call__ never sets (SD3 skip_guidance_layers, LEdits++ XL guidance_scale)
- Dominant language
- Python
- Stars
- 34.5k
- Forks
- 7.3k
- Avg merge
- 3d 3h
- Merged PRs (30d)
- 91
Description
### Describe the bug
A few pipeline properties return `self._`, but nothing ever assigns that attribute, so reading them raises `AttributeError`. I checked every `@property` under `src/diffusers` that returns a `self._x` which is never assigned in the class or its bases, and went through the hits by hand (mixins whose subclasses set the value, and helper methods, were false positives). Two real cases are left:
1. `StableDiffusion3Pipeline.skip_guidance_layers`. `__call__` sets `_guidance_scale`, `_skip_layer_guidance_scale`, `_clip_skip`, `_joint_attention_kwargs` and `_interrupt`, but not `_skip_guidance_layers`. Only the property is broken, skip layer guidance itself works. I already opened #14731 with the one line fix, before I had read the updated contribution guide, sorry about the order.
2. `LEditsPPPipelineStableDiffusionXL.guidance_scale` and `do_classifier_free_guidance`. Both read `self._guidance_scale`, which is never set, and `__call__` has no `guidance_scale` argument. `__call__` uses them in two places:
* step 9, when `unet.config.time_cond_proj_dim` is set (an LCM style UNet): `torch.tensor(self.guidance_scale - 1)`
* the `ip_adapter_image` branch: `if self.do_classifier_free_guidance:`. That branch already has a `# TODO: fix image encoding` and fails earlier in `encode_image`, so this one is mostly moot.
The first one means LEdits++ XL cannot run with an LCM style UNet at all. I did not want to guess a fix, since LEdits++ has no regular guidance scale in `__call__`. It could take a new argument, reuse `source_guidance_scale` from `invert()`, or reject such UNets up front. Happy to send a PR for whichever you prefer.
### Reproduction
LEdits++ XL, using the dummy components from the existing test file with only `time_cond_proj_dim` set. Run from the repo root:
```python
from tests.pipelines.ledits_pp.test_ledits_pp_stable_diffusion_xl import TestLEditsPPPipelineStableDiffusionXL
t = TestLEditsPPPipelineStableDiffusionXL()
# an LCM style UNet, i.e. unet.config.time_cond_proj_dim is set
pipe = t.pipeline_class(**t.get_dummy_components(time_cond_proj_dim=32))
pipe.set_progress_bar_config(disable=True)
inversion_inputs = t.get_dummy_inversion_inputs()
inversion_inputs["image"] = inversion_inputs["image"][0]
pipe.invert(**inversion_inputs)
pipe(**t.get_dummy_inputs())
```
With the default components (`time_cond_proj_dim=None`) the same script runs fine.
For SD3, `test_skip_guidance_layers` in #14731 reads the property back and fails on `main`.
### Logs
```shell
Traceback (most recent call last):
File "/tmp/diffusers/repro_ledits.py", line 11, in
pipe(**t.get_dummy_inputs())
~~~~^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/diffusers/src/diffusers/pipelines/ledits_pp/pipeline_leditspp_stable_diffusion_xl.py", line 1092, in __call__
guidance_scale_tensor = torch.tensor(self.guidance_scale - 1).repeat(batch_size * num_images_per_prompt)
^^^^^^^^^^^^^^^^^^^
File "/tmp/diffusers/src/diffusers/configuration_utils.py", line 175, in __getattr__
raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'")
AttributeError: 'LEditsPPPipelineStableDiffusionXL' object has no attribute 'guidance_scale'. Did you mean: 'guidance_rescale'?
```
(the torch `decorate_context` frame between the first two is left out)
### System Info
- diffusers `0.41.0.dev0`, `main` at `c419dac`
- PyTorch 2.11.0+cu130, Transformers 5.9.0, Python 3.13.15
- Linux, CPU
The reproduction builds tiny random components; the only download is the `hf-internal-testing/tiny-random-clip` tokenizer.
### Who can help?
@yiyixuxu @sayakpaul
Contributor guide
Research direction
Start with src/diffusers/pipelines/ledits_pp/pipeline_leditspp_stable_diffusion_xl.py around __call__, then run the provided LEdits++ XL reproduction with time_cond_proj_dim=32. Compare it with tests/pipelines/ledits_pp/test_ledits_pp_stable_diffusion_xl.py and the test_skip_guidance_layers work in #14731; done means both reported property accesses behave correctly and the LCM-style reproduction no longer raises AttributeError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, pytorch
- Domain
- machine-learning, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100