Skip to content

Separate Sigma Schedule - #10146

Closed
hlky wants to merge 21 commits into
huggingface:mainfrom
hlky:separate-sigma-schedule
Closed

Separate Sigma Schedule#10146
hlky wants to merge 21 commits into
huggingface:mainfrom
hlky:separate-sigma-schedule

Conversation

@hlky

@hlkyhlky commented Dec 7, 2024

Copy link
Copy Markdown
Contributor

What does this PR do?

This is not a finalised design, just a demonstration of how sigma/noise schedule can be moved out of schedulers, comments and feedback are encouraged.

Usage:

fromdiffusersimportHeunDiscreteSchedulerfromdiffusers.schedulers.sigmasimportBetaSigmas, ExponentialSigmas, KarrasSigmassigma_schedule=ExponentialSigmas()
scheduler=HeunDiscreteScheduler.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
subfolder="scheduler",
sigma_schedule=sigma_schedule,
)

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.

cc @yiyixuxu

@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

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.

@hlky
hlkyforce-pushed the separate-sigma-schedule branch from e4daabb to 8703cdcCompareDecember 18, 2024 13:32
from ..sigmas.exponential_sigmas import ExponentialSigmas
from ..sigmas.karras_sigmas import KarrasSigmas

class FlowMatchSD3:

@yiyixuxuyiyixuxuDec 18, 2024

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

is there any reason, the flow match sigmas are treated differently from beta/exponential/karras? they all generate a sigma schedule, no?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Beta/exponential/karras are more like a conversion of existing sigma schedule, the original functions are actually called _convert_to_*

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

FlowMatchEuler currently has what we're calling FlowMatchSD3 here by default, and for other models we pass in sigmas, I think the one for SANA is different again, so it seems these will tend to be model specific, compared to everything in BetaSchedule like timestep_spacing == "linspace"interpolation_type == "linear" which is shared and we rarely pass in sigmas, the exception is Align Your Steps schedules which I don't think is used often. We could inline these like timestep_spacing == "linspace" in BetaSchedule but like this the idea is that we can pass a custom class that just needs a call to return the sigmas if we wanted to in addition to the ones that are built-in, new models, custom schedules and experimentation can be supported easier. We could refactor BetaSchedule in a similar way like LinspaceLinear etc and allow the same level of experimentation, it just seems less likely to be used and the experimentation with this kind of scheduler will be done with conversion, there are a few more less popular from the community that we don't support but again the idea is that it can be passed in as a custom class.

@hlky

hlky commented Dec 19, 2024

Copy link
Copy Markdown
ContributorAuthor

I've added some notes, sana's schedule and combined scale_noise (from FlowMatchEuler) with add_noise, they're the same except 1 extra multiplication for FlowMatch and the signature order is different. Trying to cover most things that will need changing so it can be reviewed at the same time. I'll look at some other schedulers like DDIM in case there's anything specific in those.

deprecate("config-passed-as-path", "1.0.0", deprecation_message, standard_warn=False)
config, kwargs = cls.load_config(pretrained_model_name_or_path=config, return_unused_kwargs=True, **kwargs)

# Handle old scheduler configs

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This will need to be robust and probably kept for a while unless we can find a way to mass update configs on the Hub. It's working with some scheduler configs already, FlowMatch vs Beta is detected with shift and beta_schedule, I've already found an edge case in SANA's config because we integrated those scheduler changes into DPM so it has beta_schedule and no shift (it was called flow_shift instead).

@hlky

hlky commented Dec 20, 2024

Copy link
Copy Markdown
ContributorAuthor

image

Important to note here that we don't expect all combinations of sampler + noise schedule to work for all models, especially Flow Match models, above is a table of compatibility with Flux from community UIs (Code for sampling is almost 1:1 between forge, comfy etc.)

@hlky

hlky commented Jan 8, 2025

Copy link
Copy Markdown
ContributorAuthor

Some code to demonstrate how schedulers work at this stage in the refactor.

fromdiffusersimportEulerDiscreteScheduler, EulerAncestralDiscreteScheduler, HeunDiscreteSchedulerfromdiffusers.schedulers.schedules.beta_scheduleimportBetaSchedulefromdiffusers.schedulers.schedules.flow_scheduleimportFlowMatchSchedule, FlowMatchSD3, FlowMatchFlux, FlowMatchSANA, FlowMatchHunyuanVideo, FlowMatchLinearQuadraticfromdiffusers.schedulers.sigmas.beta_sigmasimportBetaSigmasfromdiffusers.schedulers.sigmas.exponential_sigmasimportExponentialSigmasfromdiffusers.schedulers.sigmas.karras_sigmasimportKarrasSigmasimportnumpyasnp# mapped from FlowMatchEulerDiscreteScheduler# Euler sampling with Flow Match scheduleeuler=EulerDiscreteScheduler.from_pretrained("black-forest-labs/FLUX.1-dev", subfolder="scheduler")
# Heun sampling with Flow Match scheduleheun=HeunDiscreteScheduler.from_config(euler.config)
# Euler Ancestral actually gives noisy output with Flow Matchancestral=EulerAncestralDiscreteScheduler.from_config(euler.config)
# currently, if this is used in Flux pipeline `base_schedule` is set to `FlowMatchFlux`# SD3 base scheduleeuler._schedule.base_schedule=FlowMatchSD3()
# SANA base scheduleeuler._schedule.base_schedule=FlowMatchSANA()
classFlowMatchCustom:
def__call__(self, num_inference_steps: int, **kwargs) ->np.ndarray:
sigmas=np.linspace(1.0, 1/num_inference_steps, num_inference_steps)
half=num_inference_steps//2sigmas[half:] =sigmas[half:] *1.2returnsigmaseuler._schedule.base_schedule=FlowMatchCustom()
# configs contain `base_schedule` as `str`flow_schedule=FlowMatchSchedule(
shift=13.0,
use_dynamic_shifting=False,
base_schedule="FlowMatchSD3"
)
# we can also use the class directlyflow_schedule=FlowMatchSchedule(
shift=13.0,
use_dynamic_shifting=False,
base_schedule=FlowMatchCustom()
)
# Euler sampling with Beta scheduleeuler=EulerDiscreteScheduler.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", subfolder="scheduler")
# Euler sampling with Beta schedule and Karras sigmaseuler=EulerDiscreteScheduler(
schedule_config=BetaSchedule(
beta_end=0.012,
beta_schedule="scaled_linear",
beta_start=0.00085,
timestep_spacing="leading",
),
sigma_schedule_config=KarrasSigmas(),
)
# Euler sampling with Beta schedule and Beta sigmaseuler._sigma_schedule=BetaSigmas()
# Euler sampling with Beta schedule and Exponential sigmaseuler._sigma_schedule=ExponentialSigmas()

Tests with black-forest-labs/FLUX.1-dev

Euler

BaseBetaExponentialKarras
EulerDiscreteSchedulerEulerDiscreteScheduler_BetaSigmasEulerDiscreteScheduler_ExponentialSigmasEulerDiscreteScheduler_KarrasSigmas

Euler Ancestral

BaseBetaExponentialKarras
EulerAncestralDiscreteSchedulerEulerAncestralDiscreteScheduler_BetaSigmasEulerAncestralDiscreteScheduler_ExponentialSigmasEulerAncestralDiscreteScheduler_KarrasSigmas

Heun

BetaExponential
HeunDiscreteScheduler_BetaSigmasHeunDiscreteScheduler_ExponentialSigmas

Note: Base Heun and with Karras were tested, just lost the files from when I ran the test.

@hlky

hlky commented Jan 12, 2025

Copy link
Copy Markdown
ContributorAuthor

Hi @ukaprch. Thanks for your interest in Flow Match scheduling support. We know this is highly anticipated and we appreciate your patience while we work on it 🤗

@yiyixuxu

yiyixuxu commented Jan 14, 2025

Copy link
Copy Markdown
Collaborator

I think the idea is to separate sigma class out from the schedulerclass, it will be separate part of pipeline (i.e. you can change scheduler without change sigma, e.g. we change it at run time etc) - is it possible?

the current scheduler already accept sigmas but it is still depends on the scheduler config to convert to k-sigmas etc

this API here it is still part of the scheduler, just make it more configurable I think

sigma_schedule = ExponentialSigmas()
scheduler = HeunDiscreteScheduler.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
subfolder="scheduler",
sigma_schedule=sigma_schedule,
)

the ideal design should not require much change to current scheduler class IMO

@hlky

hlky commented Jan 14, 2025

Copy link
Copy Markdown
ContributorAuthor

That is what I was looking at initially, while you've been working on Modular I've added a further experimental design.

We can make sigma as in Beta, Exponential, Karras a separate part of the pipeline, it has to passed into the scheduler though as these conversions run before concatenate final (zero, min).


These can be used if we add a ConfigMixin etc.

Afaik some scheduler configs do specify use_karras_sigmas=True so will need to find a way to set e.g. KarrasSigmas on pipeline.

We could also do the same for Flow Match base schedules, add a ConfigMixin etc., the class computes sigmas that are passed into scheduler instead of just code in the pipelines like now.

classFlowMatchFlux:
def__call__(self, num_inference_steps: int, **kwargs) ->np.ndarray:
returnnp.linspace(1.0, 1/num_inference_steps, num_inference_steps)

@github-actions

Copy link
Copy Markdown
Contributor

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.

@github-actionsgithub-actionsBot added the stale Issues that haven't received updates label Feb 8, 2025
@hlkyhlky closed this Apr 15, 2025
@hlky
hlky deleted the separate-sigma-schedule branch April 15, 2025 12:29
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

schedulerstaleIssues that haven't received updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@hlky@HuggingFaceDocBuilderDev@yiyixuxu