-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Add support of Xlabs Controlnets #9638
Conversation
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.
Just some minor comments that you can address/ignore based on what Sayak has to say
@@ -773,6 +773,17 @@ def __call__( | |||
control_mode = torch.tensor(control_mode).to(device, dtype=torch.long) | |||
control_mode = control_mode.view(-1, 1).expand(control_image.shape[0], 1) | |||
|
|||
elif isinstance(self.controlnet, FluxControlNetModel) and self.controlnet.is_xlabs_controlnet: |
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 these changes will have to be propagated to other pipeline files as well? Maybe you could rewrite this as:
if isinstance(self.controlnet):
control_image = self.prepare_image(...)
if self.controlnet.is_xlabs_controlnet:
# remaining mismatching logic
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.
Please check it now.
@Anghellia thanks so much for this <3 Could you supplement this PR with an example code snippet and some resultant images? Ccing @asomoza for doing a test drive, 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.
Beautiful PR.
@@ -55,6 +56,7 @@ def __init__( | |||
guidance_embeds: bool = False, | |||
axes_dims_rope: List[int] = [16, 56, 56], | |||
num_mode: int = None, | |||
is_xlabs_controlnet: bool = False, |
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.
Is it possible to determine if a ControlNet is of type xlabs? If not, then it's fine!
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.
Hmm, I am not sure. Actually, xlabs ControlNets are not so different from others. I see two main changes:
-
We use
num_layers=2
(the depth of ControlNet is 2). However, I don't think it's correct to rely solely on this, as one could also train a ControlNet with num_layers=2 using the diffusers script. -
We use
input_hint_block
, but we can specify this only if we check for a specific keyword in the model's state_dict. I think this may not apply in our case.
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.
Maybe both could be combined to create a condition to determine if it's an Xlabs ControlNet? @yiyixuxu would love to know your thoughts here.
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.
Nevermind I think #9638 (comment) should cut the deal for us unless there's some differences in the forward method.
Thank you! Updated the PR with examples 🤗 |
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.
thanks a lot for the PR! I left some suggestions, let me know if they would work!
@@ -55,6 +55,7 @@ def __init__( | |||
guidance_embeds: bool = False, | |||
axes_dims_rope: List[int] = [16, 56, 56], | |||
num_mode: int = None, | |||
is_xlabs_controlnet: bool = False, |
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.
is_xlabs_controlnet: bool = False, | |
conditioning_embedding_channels: int = None, |
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 can add a new config conditioning_embedding_channels
to the flux controlnet that defaults to None
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.
Thanks for your suggestion, it works!
I encountered an issue where the
After installation, I tried executing the following code: import torch
from diffusers.utils import load_image
from diffusers import FluxControlNetModel, FluxMultiControlNetModel
from diffusers.pipelines import FluxControlNetPipeline
generator = torch.Generator(device="cuda").manual_seed(87544357)
controlnet = FluxMultiControlNetModel([
FluxControlNetModel.from_pretrained(
"Xlabs-AI/flux-controlnet-canny-diffusers",
torch_dtype=torch.bfloat16,
use_safetensors=True,
),
FluxControlNetModel.from_pretrained(
"Xlabs-AI/flux-controlnet-canny-diffusers",
torch_dtype=torch.bfloat16,
use_safetensors=True,
),
])
pipe = FluxControlNetPipeline.from_pretrained(
'/mypath/to/FLUX.1-dev_official',
controlnet=controlnet,
torch_dtype=torch.bfloat16
)
pipe.to("cuda")
control_image = load_image("https://huggingface.co/Xlabs-AI/flux-controlnet-canny-diffusers/resolve/main/canny_example.png")
image = pipe(
"handsome girl with rainbow hair, anime",
control_image=[control_image, control_image],
controlnet_conditioning_scale=[0.7, 0.7],
num_inference_steps=25,
guidance_scale=3.5,
height=1024,
width=768,
generator=generator,
num_images_per_prompt=1,
).images[0]
image.save("output_test_controlnet.png") However, I encountered this error:
Could you please investigate this incompatibility? |
MultiControlNet compatibility can be incorporated after this initial PR is merged. |
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.
thanks, I left one more feedbacks
let's merge this soon!
@@ -508,7 +508,11 @@ def custom_forward(*inputs): | |||
if controlnet_block_samples is not None: | |||
interval_control = len(self.transformer_blocks) / len(controlnet_block_samples) | |||
interval_control = int(np.ceil(interval_control)) | |||
hidden_states = hidden_states + controlnet_block_samples[index_block // interval_control] | |||
# For Xlabs ControlNet. | |||
if len(controlnet_block_samples) == 2: |
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 would suggest passing a flag down here, controlnet_repeat_interleave = False
maybe?
This would break if someone trained a controlnet with 2 blocks but want to use the other indexing method
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.
Agree
Updated with controlnet_blocks_repeat
flag
Fixed |
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 this is look good to merge now after @yiyixuxu gives a final review!
For the failing style tests, could you run make style
and push? Thanks
We could add some tests in a follow-up PR. |
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. |
@a-r-r-o-w please launch tests |
* Add support of Xlabs Controlnets --------- Co-authored-by: Anzhella Pankratova <[email protected]>
hey thanks for the PR! |
closing the PR now since we already merged it! |
* Add support of Xlabs Controlnets --------- Co-authored-by: Anzhella Pankratova <[email protected]>
What does this PR do?
Hi!
This PR brings support of Xlabs Controlnets, so it can be used with Diffusers.
We converted checkpoints to the Diffusers format and it can be downloaded here:
The request: #9378
Who can review?
Anyone in the community is free to review the PR once the tests have passed.
@sayakpaul
How to use
Here is the example of code to launch Canny Controlnet.
Examples
"photo of village in the winter"
"it programmer sitting in the office"
"couple of man and woman in the water, dancing"
"photo of woman in the beach"
"futuristic bulding in the spain"
"2d art, girl in the magic city, sparkles, fantasy"