huggingface / huggingface/diffusers

Confusion about the use of from_config and its relation to _use_default_values

Aperta
#7,626 7 commenti 1 reazione 1 assegnatario Rivendicata da @yiyixuxu Vedi su GitHub
bug stale
Lingua principale
Python
Stelle
34.5k
Fork
7.3k
Merge medio
3g 3h
PR unite (30g)
91

Descrizione

### Describe the bug

I'm not sure if this qualifies as a bug because it depends on what the intent is behind the code. At the very least, I would classify it as peculiar behaviour. Suppose I instantiate some scheduler (doesn't matter which one) and extract (a copy of) its config to modify after:

```
sched = EulerDiscreteScheduler()
config = dict(sched.config)
```

If I modify `config` to have different key/vals, e.g `config['beta_end'] = 0.5`, and then instantiate a new scheduler from that config:

```
sched2 = EulerDiscreteScheduler.from_config(config)
```

`sched2` is identical to `sched`, and this is also reflected by looking at the string repr of the object (i.e. `beta_end` is still the default value). I didn't understand why any changes in `config` weren't being reflected in `sched2` until I realised that `config` contains an extra list called `_use_default_values`, which appears to track what kwargs were _not_ passed into the constructor. In our case it's everything since we just used `sched = EulerDiscreteScheduler()`:

`['beta_end', 'sigma_max', 'timestep_spacing', 'interpolation_type', 'steps_offset', 'timestep_type', 'trained_betas', 'beta_start', 'sigma_min', 'beta_schedule', 'use_karras_sigmas', 'num_train_timesteps', 'prediction_type']`

which means that `beta_end` gets ignored as per the behaviour in `extract_init_dict` (class `ConfigMixin`).

Ok so that means if we do the following:

```
# pass in explicit kwarg, beta_end=0.4
sched = EulerDiscreteScheduler(beta_end=0.4)
config = dict(sched.config)
config['beta_end'] = 0.5
sched2 = EulerDiscreteScheduler.from_config(config)
# this will be 0.5
print(sched2.beta_end)
```

then things work just fine.

I don't quite understand the intent behind this. Sure, I could work around the issue by actually instantiating the scheduler like `sched2 = EulerDiscreteScheduler(**config)` and that works, but I am still confused about the above because the docs describe `from_config` as "Instantiate a Python class from a config dictionary.", almost as if using `.from_config` is synonymous with instantiating a class via its constructor with `(**kwargs)`. However, the way it works now is that `config` acts like a quasi-immutable dictionary (from the pov of the new scheduler object, assuming `_use_default_values` is inside).

Can we discuss what the intent is here? Thanks.

### Reproduction

See above.

### Logs

```shell
See above.
```

### System Info

Latest version as of now.

### Who can help?

_No response_

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.