huggingface / huggingface/diffusers

`register_to_config` mislabels positional `__init__` args as `_use_default_values`, so `from_config` round trips silently revert them to defaults

Offen Anfängerfreundlich
#14,460 3 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
bug models
Vorherrschende Sprache
Python
Sterne
34.5k
Forks
7.3k
Ø Merge
3 T. 3 Std.
Gemergte PRs (30 T.)
91

Beschreibung

### Describe the bug

`@register_to_config` computes `_use_default_values` as `set(new_kwargs) - set(init_kwargs)`, but `init_kwargs` only contains *keyword* arguments (`src/diffusers/configuration_utils.py:725-726`). Any constructor argument passed **positionally** is mislabeled as "used default value", and `extract_init_dict` then strips it on every `from_config` round trip (`configuration_utils.py:500-501`).

- Expected: per the comment at `configuration_utils.py:499` ("Skip keys that were *not present* in the original config, so default `__init__` values were used") and the design intent in https://github.com/huggingface/diffusers/pull/3929#issuecomment-1618919655, `_use_default_values` should only contain parameters the caller did not provide — positional and keyword calls should round-trip identically.
- Actual: the config *displays* the explicitly-set value, but `from_config(obj.config)` (the documented scheduler-swap pattern) silently reverts it to the class default. Affects every `ConfigMixin` subclass.

I'd be happy to open a PR: exclude positionally-bound parameter names from the `_use_default_values` computation in `inner_init` (a two-line change), plus a regression test in `tests/others/test_config.py` — once a maintainer acks, per the AI-assisted contributions guidelines.

### Reproduction

```python
from diffusers import DDIMScheduler, EulerDiscreteScheduler

s = DDIMScheduler(500) # positional, explicit non-default value
print(s.config.num_train_timesteps) # 500
print("num_train_timesteps" in s.config["_use_default_values"]) # True <-- mislabeled

print(DDIMScheduler.from_config(s.config).config.num_train_timesteps) # 1000, expected 500
print(EulerDiscreteScheduler.from_config(s.config).config.num_train_timesteps) # 1000, expected 500

k = DDIMScheduler(num_train_timesteps=500) # keyword control group
print(DDIMScheduler.from_config(k.config).config.num_train_timesteps) # 500, correct
```

### Logs

```shell
(no traceback — the failure mode is a silently wrong value)
```

### System Info

- 🤗 Diffusers version: 0.40.0.dev0 (`main` @ 614ae4b)
- Platform: macOS-26.5.2-arm64-arm-64bit-Mach-O
- Python version: 3.13.3
- PyTorch version (GPU?): 2.13.0 (False)
- Huggingface_hub version: 1.27.0
- Transformers version: 5.15.0
- Safetensors version: 0.8.0
- Using GPU in script?: No

### Who can help?

_No response_

---

Disclosure: this report was prepared with AI assistance; I reproduced the issue locally and reviewed every claim myself.

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne in src/diffusers/configuration_utils.py bei inner_init in den Zeilen 725–726 und untersuche extract_init_dict in den Zeilen 499–501. Führe die Reproduktion aus und füge die Regressionstestabdeckung in tests/others/test_config.py hinzu. Erledigt ist die Aufgabe, wenn sowohl positionale als auch Schlüsselwort-Konstruktorargumente ihre expliziten Werte über from_config-Roundtrips hinweg beibehalten.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
developer-experience
Issue-Typ
Bug
Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Aktivitätsstatus
Ruhig
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
78/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.