Skip to content
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 TCD Scheduler #7174

Merged
merged 15 commits into from
Mar 5, 2024
Merged

add TCD Scheduler #7174

merged 15 commits into from
Mar 5, 2024

Conversation

mhh0318
Copy link
Contributor

@mhh0318 mhh0318 commented Mar 1, 2024

What does this PR do?

Add a new scheduler for trajectory consistency distillation: Paper and Official Implement.

Before submitting

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.

@yiyixuxu
Copy link
Collaborator

yiyixuxu commented Mar 1, 2024

hi!
thanks for your PR :)
does this scheduler with SD and SDXL? can we see some examples?

@mhh0318
Copy link
Contributor Author

mhh0318 commented Mar 1, 2024

Yes, it suits with SD and XL. Currently we only release SDXL LoRA. Here is a demo Space: https://huggingface.co/spaces/h1t/TCD ,
And one example can be:

import torch
from diffusers import StableDiffusionXLPipeline

+ from diffusers import TCDScheduler 

device = "cuda"
base_model_id = "stabilityai/stable-diffusion-xl-base-1.0"
tcd_lora_id = "h1t/TCD-SDXL-LoRA"

pipe = StableDiffusionXLPipeline.from_pretrained(base_model_id, torch_dtype=torch.float16, variant="fp16").to(device)
pipe.scheduler = TCDScheduler.from_config(pipe.scheduler.config)

pipe.load_lora_weights(tcd_lora_id)
pipe.fuse_lora()

prompt = "Beautiful woman, bubblegum pink, lemon yellow, minty blue, futuristic, high-detail, epic composition, watercolor."

image = pipe(
    prompt=prompt,
    num_inference_steps=4,
    guidance_scale=0,
    # Eta (referred to as `gamma` in the paper) is used to control the stochasticity in every step.
    # A value of 0.3 often yields good results.
    # We recommend using a higher eta when increasing the number of inference steps.
    eta=0.3, 
    generator=torch.Generator(device=device).manual_seed(0),
).images[0]

@HuggingFaceDocBuilderDev

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.

@yiyixuxu
Copy link
Collaborator

yiyixuxu commented Mar 3, 2024

is this ready for a review?

@mhh0318
Copy link
Contributor Author

mhh0318 commented Mar 3, 2024

Yup. at least looks good for me now.

Copy link
Collaborator

@yiyixuxu yiyixuxu left a comment

Choose a reason for hiding this comment

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

hey thank you for the PR!
looks great and I think we can merge this soon

I left a few nits,
additionally, we introduced begin_index in PR very recently adcbe67#diff-98c53466d792a8faefb0045d29513a1c4bcd6b8144b8c06f66b697d4117039d7 - can you apply the same changes here? this will ensure your scheduler working properly with img2img pipelines

src/diffusers/schedulers/scheduling_tcd.py Show resolved Hide resolved
src/diffusers/schedulers/scheduling_tcd.py Show resolved Hide resolved
src/diffusers/schedulers/scheduling_tcd.py Show resolved Hide resolved
src/diffusers/schedulers/scheduling_tcd.py Show resolved Hide resolved
raise ValueError("Can only pass one of `num_inference_steps` or `custom_timesteps`.")

# 1. Calculate the TCD original training/distillation timestep schedule.
original_steps = (
Copy link
Collaborator

Choose a reason for hiding this comment

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

it seems like we are handling the case when original_steps = None

but this code here will default original_steps to config.original_inference_steps when user pass the None value - is this intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is an option for setting the range of t from a) ~ [0, 999] or b)~[9, 19, ... 999] whenconfig.original_inference_steps=50.

Copy link
Collaborator

Choose a reason for hiding this comment

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

ok, got it
so I think there might be an error in the below code then, if user pass original_inference_steps = None, orignal_steps will be set to config.original_inference_steps , so orignal_steps won't be None and the else part won't get evaluated

        if original_steps is not None:
            if original_steps > self.config.num_train_timesteps:
                raise ValueError(
                    f"`original_steps`: {original_steps} cannot be larger than `self.config.train_timesteps`:"
                    f" {self.config.num_train_timesteps} as the unet model trained with this scheduler can only handle"
                    f" maximal {self.config.num_train_timesteps} timesteps."
                )
            # TCD Timesteps Setting
            # The skipping step parameter k from the paper.
            k = self.config.num_train_timesteps // original_steps
            # TCD Training/Distillation Steps Schedule
            tcd_origin_timesteps = np.asarray(list(range(1, int(original_steps * strength) + 1))) * k - 1
        else:
            tcd_origin_timesteps = np.asarray(list(range(0, int(self.config.num_train_timesteps * strength))))

src/diffusers/schedulers/scheduling_tcd.py Show resolved Hide resolved
tests/schedulers/test_scheduler_tcd.py Outdated Show resolved Hide resolved
tests/schedulers/test_scheduler_tcd.py Outdated Show resolved Hide resolved
tests/schedulers/test_scheduler_tcd.py Outdated Show resolved Hide resolved
Copy link
Collaborator

@yiyixuxu yiyixuxu left a comment

Choose a reason for hiding this comment

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

left one question
let me know, if it is not an error

PR looks ready to merge for me. thanks for the great work!

@yiyixuxu yiyixuxu requested a review from sayakpaul March 4, 2024 17:14
original_inference_steps if original_inference_steps is not None else self.config.original_inference_steps
)

if original_steps is not None:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if original_steps is not None:
if original_inference_steps is not None:

maybe this? not sure..
see https://github.com/huggingface/diffusers/pull/7174/files#r1511499565

Copy link
Contributor Author

Choose a reason for hiding this comment

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

else should only be evaluated with customised training steps or some special situation. I think following would be better:

# default option
if original_inference_steps is None: 
  tcd_origin_timesteps align with discrete inference steps
# customised 
else:
  tcd_origin_timesteps truly randomised

Copy link
Member

@sayakpaul sayakpaul left a comment

Choose a reason for hiding this comment

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

Nice!

I think there also needs to a guide in our docs for the users to know how to best use TCD just like we have https://huggingface.co/docs/diffusers/main/en/using-diffusers/inference_with_lcm_lora.

@yiyixuxu WDYT?

@yiyixuxu
Copy link
Collaborator

yiyixuxu commented Mar 5, 2024

I think there also needs to a guide in our docs for the users to know how to best use TCD just like we have https://huggingface.co/docs/diffusers/main/en/using-diffusers/inference_with_lcm_lora.

sure!

@yiyixuxu
Copy link
Collaborator

yiyixuxu commented Mar 5, 2024

let us know when it's ready to merge

I think there also needs to a guide in our docs for the users to know how to best use TCD just like we have https://huggingface.co/docs/diffusers/main/en/using-diffusers/inference_with_lcm_lora.

what @sayakpaul suggested here is a great way to help promote this scheduler, feel free to add a guide either in this PR or a separate one

@mhh0318
Copy link
Contributor Author

mhh0318 commented Mar 5, 2024

let us know when it's ready to merge

I think there also needs to a guide in our docs for the users to know how to best use TCD just like we have https://huggingface.co/docs/diffusers/main/en/using-diffusers/inference_with_lcm_lora.

what @sayakpaul suggested here is a great way to help promote this scheduler, feel free to add a guide either in this PR or a separate one

I think it is ready to merge for TCD scheduler now. I would open a new PR for the guideline.

@yiyixuxu yiyixuxu merged commit 687bc27 into huggingface:main Mar 5, 2024
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants