-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Fix config prints and save, load of pipelines #2849
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The documentation is not available anymore as the PR was closed or merged. |
@@ -109,13 +109,6 @@ def register_to_config(self, **kwargs): | |||
# TODO: remove this when we remove the deprecation warning, and the `kwargs` argument, | |||
# or solve in a more general way. | |||
kwargs.pop("kwargs", None) | |||
for key, value in kwargs.items(): | |||
try: | |||
setattr(self, key, value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should delete this, I don't know why I added it back then, but it's not a good design looking at it now.
In short currently, we have the following logic:
All diffusers models and pipelines shall inherit from ConfigMixin
which gives some nice config utils:
- the
.config
property` - automatic saving of arguments pass to the class contstructor
- load / save config
- from_config
The API is designed to allow the following
class MyModel(ConfigMixin):
@register_to_config
def __init__(self, attr1, attr2):
super().__init__()
This currently does two things:
a) it automatically saves attr1
and attr2
as self.config.attr1
and self.config.attr2
b) However, it also saves attr1
and attr2
as self.attr1
and self.attr2
I'm not sure why I thought b) is a good idea back then, but I think it's a pretty bad design choice now as it's not intuitive and also prone to errors (see raise error statement here). Also it doesn't really help as every attribute can be accessed with self.config
. Also it badly entangles object members such as pipe.unet
with configs which are not models.
=> Long story short, I think we should remove option b). This will clearly be a breaking change, but I don't think anybody really used b) much before as it's quite weird to assume that config attributes are direct members of the class instance.
@pcuenca @sayakpaul @patil-suraj @williamberman @yiyixuxu ok for you if I remove this with a big 🚨 headear?
As you can see many tests are failing, but they are all easy to fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+100 to your reasoning. I am okay with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This way, we also encourage our users to access configuration variables from .config
which reduces the cognitive burdens and helps establish a clean and uniform design philosophy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't remember why this was added in the first place, but I'm all for simplifying the API. Thanks for revisiting!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changes broke this pipeline
I think it could break many more, instead of not setting attributes anymore we should set getters that tell the user these properties are deprecated, should i open a PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fair. I think it should be nice. Cc @patrickvonplaten
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too many breaking changes because of this PR, will try to fix and make a patch release
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR should work for the patch release: #3129
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@remorses sorry about the breaking change, we just made a patch release for it
@@ -109,13 +109,6 @@ def register_to_config(self, **kwargs): | |||
# TODO: remove this when we remove the deprecation warning, and the `kwargs` argument, | |||
# or solve in a more general way. | |||
kwargs.pop("kwargs", None) | |||
for key, value in kwargs.items(): | |||
try: | |||
setattr(self, key, value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't remember why this was added in the first place, but I'm all for simplifying the API. Thanks for revisiting!
4075111
to
cdb58ef
Compare
@@ -109,13 +109,6 @@ def register_to_config(self, **kwargs): | |||
# TODO: remove this when we remove the deprecation warning, and the `kwargs` argument, | |||
# or solve in a more general way. | |||
kwargs.pop("kwargs", None) | |||
for key, value in kwargs.items(): | |||
try: | |||
setattr(self, key, value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative to minimize breaking changes would be to implement __getattr__
and return the property if it's in the config
. It's not so strange to think that, i.e., in_channels
could be an attribute of unet
.
@property | ||
def in_channels(self): | ||
deprecate( | ||
"in_channels", | ||
"1.0.0", | ||
"Accessing `in_channels` directly via unet.in_channels is deprecated. Please use `unet.config.in_channels` instead", | ||
standard_warn=False, | ||
) | ||
return self.config.in_channels | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing this via __getattr__
we could deprecate all properties, not just in_channels
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah good idea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok played around with it a bit and don't feel super comfortable overwriting __getattr__
actually. Many Python methods such as hasattr(...)
rely on __getattr__
and I don't manage to escape infinite recursions and have nice standard error messages here.
Added deprecation properties for all the important direct accesses, think that should be good enough.
@@ -68,9 +68,9 @@ def __call__( | |||
""" | |||
# Sample gaussian noise to begin loop | |||
if isinstance(self.unet.sample_size, int): | |||
image_shape = (batch_size, self.unet.in_channels, self.unet.sample_size, self.unet.sample_size) | |||
image_shape = (batch_size, self.unet.config.in_channels, self.unet.sample_size, self.unet.sample_size) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is sample_size
not accessed through the config
too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah sample_size
is defined separately by the unet so that's fine, but probably better to use config anyways.
Using lpw custom pipeline, now running this error after this PR File "/workspace/server/tasks.py", line 325, in txt2img |
Hey @adhikjoshi, Could you maybe open a new issue for this with a reproducible code snippet? :-) |
* [Config] Fix config prints and save, load * Only use potential nn.Modules for dtype and device * Correct vae image processor * make sure in_channels is not accessed directly * make sure in channels is only accessed via config * Make sure schedulers only access config attributes * Make sure to access config in SAG * Fix vae processor and make style * add tests * uP * make style * Fix more naming issues * Final fix with vae config * change more
Link to PR in diffusers repository: huggingface/diffusers#2691 Imports: `diffusers.models.cross_attention -> diffusers.models.attention_processor` Unions: `AttnProcessor -> AttentionProcessor` Classes: | Old name | New name | | --- | --- | | CrossAttention | Attention | | CrossAttnProcessor | AttnProcessor | | XFormersCrossAttnProcessor | XFormersAttnProcessor | | CrossAttnAddedKVProcessor | AttnAddedKVProcessor | | LoRACrossAttnProcessor | LoRAAttnProcessor | | LoRAXFormersCrossAttnProcessor | LoRAXFormersAttnProcessor | | FlaxCrossAttention | FlaxAttention | | AttendExciteCrossAttnProcessor | AttendExciteAttnProcessor | | Pix2PixZeroCrossAttnProcessor | Pix2PixZeroAttnProcessor | Also config values no longer sets as attributes of object: huggingface/diffusers#2849
* [Config] Fix config prints and save, load * Only use potential nn.Modules for dtype and device * Correct vae image processor * make sure in_channels is not accessed directly * make sure in channels is only accessed via config * Make sure schedulers only access config attributes * Make sure to access config in SAG * Fix vae processor and make style * add tests * uP * make style * Fix more naming issues * Final fix with vae config * change more
* [Config] Fix config prints and save, load * Only use potential nn.Modules for dtype and device * Correct vae image processor * make sure in_channels is not accessed directly * make sure in channels is only accessed via config * Make sure schedulers only access config attributes * Make sure to access config in SAG * Fix vae processor and make style * add tests * uP * make style * Fix more naming issues * Final fix with vae config * change more
* [Config] Fix config prints and save, load * Only use potential nn.Modules for dtype and device * Correct vae image processor * make sure in_channels is not accessed directly * make sure in channels is only accessed via config * Make sure schedulers only access config attributes * Make sure to access config in SAG * Fix vae processor and make style * add tests * uP * make style * Fix more naming issues * Final fix with vae config * change more
As noticed in ##2806 the pipeline currently does not take changes of its components into account. This PR make sure that when changing the scheduler or vae the changes are correctly reflected when saving the pipeline afterwards.
🚨🚨 Also, after this PR config attributes are not changed as instance attributes anymore. This was incorrectly implemented before and is removed as explained here: #2849 (comment) . This can for some edge cases be a breaking change. In this case please make sure to access directly the config variable. The most prominent examples are added as deprecated properties to limit the breaking changes to a minimum. 🚨🚨