Allow controlnets to be loaded (from ckpt) in a parallel thread with a SD model (ckpt), and speed it up slightly by cmdr2 · Pull Request #4298 · huggingface/diffusers · GitHub
Skip to content

Allow controlnets to be loaded (from ckpt) in a parallel thread with a SD model (ckpt), and speed it up slightly - #4298

Merged
patrickvonplaten merged 1 commit into
huggingface:mainfrom
cmdr2:cn_meta
Aug 3, 2023
Merged

patrickvonplaten merged 1 commit into
huggingface:mainfrom
cmdr2:cn_meta

Conversation

@cmdr2

@cmdr2 cmdr2 commented Jul 26, 2023 •

Copy link
Copy Markdown
Contributor

Avoids meta tensor errors (due to a race condition described in #4296).

This allows a controlnet model to be loaded in parallel with an SD model (in two separate threads). As a side-effect, it slightly speeds up the controlnet model instantiation, by following the pattern used for unet and other sub-modules.

While this isn't a broader fix for the race-condition mentioned in #4296, it fixes the problem for Controlnet.

If there's a different way to address this issue, I'd be happy to alter the PR! :)

Thanks!

@patrickvonplaten @sayakpaul

…aded (from ckpt) in a parallel thread with a SD model (ckpt) without tensor errors (race condition)
@HuggingFaceDocBuilderDev

HuggingFaceDocBuilderDev commented Jul 26, 2023 •

Copy link
Copy Markdown

@sayakpaul sayakpaul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix!

I think we purposefully avoid multi-threading for these conversion scripts to promote simplicity. So, not sure if there's much we can do here.

Seeking advice from @yiyixuxu, @williamberman, and @patrickvonplaten.

@cmdr2

cmdr2 commented Jul 27, 2023 •

Copy link
Copy Markdown
Contributor Author

Hi @sayakpaul I understand. In this PR I'm just repeating what we do for unet, vae and other modules during the ckpt conversion.

For unet:
https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/stable_diffusion/convert_from_ckpt.py#L1364-L1372

ctx = init_empty_weights if is_accelerate_available() else nullcontext
with ctx():
    unet = UNet2DConditionModel(**unet_config)

if is_accelerate_available():
    for param_name, param in converted_unet_checkpoint.items():
        set_module_tensor_to_device(unet, param_name, "cpu", value=param)
else:
    unet.load_state_dict(converted_unet_checkpoint)

For vae:
https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/stable_diffusion/convert_from_ckpt.py#L1390-L1398

ctx = init_empty_weights if is_accelerate_available() else nullcontext
with ctx():
    vae = AutoencoderKL(**vae_config)

if is_accelerate_available():
    for param_name, param in converted_vae_checkpoint.items():
        set_module_tensor_to_device(vae, param_name, "cpu", value=param)
else:
    vae.load_state_dict(converted_vae_checkpoint)

It's not a different multi-threaded solution, but it just follows the pattern used for unet, vae etc, of initializing the model class quickly, and then loading the tensors using the set_module_tensor_to_device() utility.

So maybe you could consider this PR as just a code-consistency + performance boost for Controlnet loading, with an added side benefit of allowing Controlnet models to be loaded in another thread. :) Controlnet's unet is pretty hefty as well.

This PR isn't a broader fix for multi-threading. That's in the other issue (#4296).

Thanks!

@cmdr2

cmdr2 commented Jul 27, 2023 •

Copy link
Copy Markdown
Contributor Author

This PR will also unblock Easy Diffusion, since I'm currently monkey-patching the controlnet loader function to allow our multi-GPU users to use controlnet.

@sayakpaul

sayakpaul commented Jul 27, 2023 •

Copy link
Copy Markdown
Member

Makes sense thanks for explaining. Then I see no problems in this PR.

@cmdr2

cmdr2 commented Jul 27, 2023

Copy link
Copy Markdown
Contributor Author

Thanks! Training in ED - not yet. Really keen to get to it soon.

@williamberman williamberman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine because they should be equivalent ways of loading weights, not because we say this code can be multi threaded :)

@cmdr2

cmdr2 commented Jul 30, 2023

Copy link
Copy Markdown
Contributor Author

Thanks! Please let me know if anything else is needed from my end.

@sayakpaul

Copy link
Copy Markdown
Member

@patrickvonplaten
patrickvonplaten merged commit 380bfd8 into huggingface:main Aug 3, 2023
yoonseokjin pushed a commit to yoonseokjin/diffusers that referenced this pull request Dec 25, 2023
…a SD model (ckpt), and speed it up slightly (huggingface#4298)

Faster controlnet model instantiation, and allow controlnets to be loaded (from ckpt) in a parallel thread with a SD model (ckpt) without  tensor errors (race condition)
AmericanPresidentJimmyCarter pushed a commit to AmericanPresidentJimmyCarter/diffusers that referenced this pull request Apr 26, 2024
…a SD model (ckpt), and speed it up slightly (huggingface#4298)

Faster controlnet model instantiation, and allow controlnets to be loaded (from ckpt) in a parallel thread with a SD model (ckpt) without  tensor errors (race condition)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants