huggingface / huggingface/diffusers

Confusion about the use of from_config and its relation to _use_default_values

Abierto
#7,626 7 comentarios 1 reacción 1 asignado Reclamado por @yiyixuxu Ver en GitHub
bug stale
Lenguaje dominante
Python
Estrellas
34.5k
Forks
7.3k
Merge medio
3 d 3 h
PR fusionados (30 d)
91

Descripción

### 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_

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.