-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Fix custom_diffusion with PEFT installed issue#7261 #7272
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
base: main
Are you sure you want to change the base?
Conversation
src/diffusers/loaders/unet.py
Outdated
| elif is_custom_diffusion: | ||
| #Load custom diffusion cross attention weight with PEFT installed in environment | ||
| self.set_attn_processor(attn_processors) | ||
|
|
||
| self.to(dtype=self.dtype, device=self.device) |
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.
We're already doing this here no?
Perhaps, guarding this code block with if not is_custom_diffusion would be more helpful?
diffusers/src/diffusers/loaders/unet.py
Line 365 in a1cb106
| # set lora layers |
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.
diffusers/src/diffusers/loaders/unet.py
Line 363 in a1cb106
| self.set_attn_processor(attn_processors) |
will be executed only when people don't install PEFT. If PEFT is installed, the bug described in issue #7261 will appear, as
diffusers/src/diffusers/loaders/unet.py
Line 349 in a1cb106
| if not USE_PEFT_BACKEND: |
will be false and skip the execution of
diffusers/src/diffusers/loaders/unet.py
Line 363 in a1cb106
| self.set_attn_processor(attn_processors) |
I hope I give a clear response to your question. :)
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.
Oh thanks so much. In that case, could we maybe simply move
diffusers/src/diffusers/loaders/unet.py
Line 362 in a1cb106
| if is_custom_diffusion: |
out of
diffusers/src/diffusers/loaders/unet.py
Line 349 in a1cb106
| if not USE_PEFT_BACKEND: |
?
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 have tried this solution, but it failed. The reason is
diffusers/src/diffusers/loaders/unet.py
Line 369 in a1cb106
| self.to(dtype=self.dtype, device=self.device) |
will not be executed.
It will cause the bug "not same device" when you use GPU to train. (As the self is not been moved to GPU)
In addition I think
diffusers/src/diffusers/loaders/unet.py
Line 369 in a1cb106
| self.to(dtype=self.dtype, device=self.device) |
can not be simply moved out of
diffusers/src/diffusers/loaders/unet.py
Line 349 in a1cb106
| if not USE_PEFT_BACKEND: |
since when PEFT is uninstalled, it should between
diffusers/src/diffusers/loaders/unet.py
Lines 350 to 359 in a1cb106
| if _pipeline is not None: | |
| for _, component in _pipeline.components.items(): | |
| if isinstance(component, nn.Module) and hasattr(component, "_hf_hook"): | |
| is_model_cpu_offload = isinstance(getattr(component, "_hf_hook"), CpuOffload) | |
| is_sequential_cpu_offload = isinstance(getattr(component, "_hf_hook"), AlignDevicesHook) | |
| logger.info( | |
| "Accelerate hooks detected. Since you have called `load_lora_weights()`, the previous hooks will be first removed. Then the LoRA parameters will be loaded and the hooks will be applied again." | |
| ) | |
| remove_hook_from_module(component, recurse=is_sequential_cpu_offload) |
and
diffusers/src/diffusers/loaders/unet.py
Lines 371 to 375 in a1cb106
| # Offload back. | |
| if is_model_cpu_offload: | |
| _pipeline.enable_model_cpu_offload() | |
| elif is_sequential_cpu_offload: | |
| _pipeline.enable_sequential_cpu_offload() |
Hope to help:)
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 see. I understand now.
I think the existing
diffusers/src/diffusers/loaders/unet.py
Line 362 in a1cb106
| if is_custom_diffusion: |
needs to be deleted no?
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.
Then it feels redundant. Because why would we want to add add the same piece of code twice? 😱
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.
Let's make this question clear.
Our target is to let the weights of cross-attention in custom diffusion load successfully whether PEFT is installed since
- PEFT is commonly installed for Lora
- but people who want to use custom_diffusion only don't need PEFT
In my opinion, we need to keep both pieces of code for
- PEFT offload UNet before
diffusers/src/diffusers/loaders/unet.py
Line 349 in a1cb106
| if not USE_PEFT_BACKEND: |
so we don't need to offload UNet when PEFT is installed.
- If we delete it. This code may result in unsafety when PEFT is not installed since UNet is not offloaded
diffusers/src/diffusers/loaders/unet.py
Lines 362 to 363 in a1cb106
| if is_custom_diffusion: | |
| self.set_attn_processor(attn_processors) |
Or maybe we can change this piece of code to:
if not USE_PEFT_BACKEND:
if _pipeline is not None:
for _, component in _pipeline.components.items():
if isinstance(component, nn.Module) and hasattr(component, "_hf_hook"):
is_model_cpu_offload = isinstance(getattr(component, "_hf_hook"), CpuOffload)
is_sequential_cpu_offload = isinstance(getattr(component, "_hf_hook"), AlignDevicesHook)
logger.info(
"Accelerate hooks detected. Since you have called `load_lora_weights()`, the previous hooks will be first removed. Then the LoRA parameters will be loaded and the hooks will be applied again."
)
remove_hook_from_module(component, recurse=is_sequential_cpu_offload)
# only custom diffusion needs to set attn processors
if is_custom_diffusion:
#Load custom diffusion cross attention weight with PEFT installed in environment
self.set_attn_processor(attn_processors)
# set lora layers
for target_module, lora_layer in lora_layers_list:
target_module.set_lora_layer(lora_layer)
self.to(dtype=self.dtype, device=self.device)
if not USE_PEFT_BACKEND:
# Offload back.
if is_model_cpu_offload:
_pipeline.enable_model_cpu_offload()
elif is_sequential_cpu_offload:
_pipeline.enable_sequential_cpu_offload()
# Unsafe code />
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.
Can't we leverage these two variables more systematically to process the logic you mentioned? is_custom_diffusion and USE_PEFT_BACKEND. I am uncomfortable keeping the same exact line of code like this as it makes the code confusing for us, maintainers.
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.
Your proposal looks good to me.
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.
Glad to see that, I will update my PR. It's nice to discuss with you, your idea about code inspires me a lot.
sayakpaul
left a comment
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.
Looks much cleaner to me!
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
|
LGTM! @yiyixuxu WDYT? |
…/diffusers into custom_diffusion_peft_fix
|
Hey Saya, need a review for the new commit, I reformat this file @sayakpaul |
|
It's Sayak not "Saya" 😅 Will trigger the CI now. |
|
I am sorry for that.😂 What happens to this commit? Should I do something to help it pass the CI? |
|
This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread. Please note that issues that do not follow the contributing guidelines are likely to be ignored. |
|
This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread. Please note that issues that do not follow the contributing guidelines are likely to be ignored. |
|
can you update the quality dependency and then |
|
This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread. Please note that issues that do not follow the contributing guidelines are likely to be ignored. |
What does this PR do?
This PR fixes the loading of cross-attention weights in custom diffusion models when PEFT is installed. This bug has been discussed in issue #7261
Fixes #7261(issue)
Before submitting
documentation guidelines, and
here are tips on formatting docstrings.
Who can review?
Anyone in the community is free to review the PR once the tests have passed. Feel free to tag
members/contributors who may be interested in your PR.
@sayakpaul