-
Notifications
You must be signed in to change notification settings - Fork 7.1k
[lavender-flow] use flow match euler scheduler #8799
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
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |
| import inspect | ||
| from typing import Callable, List, Optional, Tuple, Union | ||
|
|
||
| import numpy as np | ||
| import torch | ||
| from transformers import T5Tokenizer, UMT5EncoderModel | ||
|
|
||
|
|
@@ -428,13 +429,14 @@ def __call__( | |
| prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds], dim=0) | ||
|
|
||
| # 4. Prepare timesteps | ||
|
|
||
| sigmas = np.linspace(1.0, 1 / num_inference_steps, num_inference_steps) | ||
| timesteps, num_inference_steps = retrieve_timesteps( | ||
| self.scheduler, num_inference_steps, device, timesteps, sigmas | ||
| ) | ||
|
|
||
| # 5. Prepare latents. | ||
| latent_channels = self.transformer.config.in_channels | ||
| effective_batch_size = batch_size * num_images_per_prompt | ||
| latents = self.prepare_latents( | ||
| batch_size * num_images_per_prompt, | ||
| latent_channels, | ||
|
|
@@ -448,20 +450,15 @@ def __call__( | |
|
|
||
| # 6. Denoising loop | ||
| num_warmup_steps = max(len(timesteps) - num_inference_steps * self.scheduler.order, 0) | ||
| dt = 1.0 / num_inference_steps | ||
| dt = ( | ||
| torch.tensor([dt] * effective_batch_size) | ||
| .to(self.device) | ||
| .view([effective_batch_size, *([1] * len(latents.shape[1:]))]) | ||
| ) | ||
| with self.progress_bar(total=num_inference_steps) as progress_bar: | ||
| for i, t in enumerate(range(num_inference_steps, 0, -1)): | ||
| for i, t in enumerate(timesteps): | ||
| # expand the latents if we are doing classifier free guidance | ||
| latent_model_input = torch.cat([latents] * 2) if do_classifier_free_guidance else latents | ||
| # broadcast to batch dimension in a way that's compatible with ONNX/Core ML | ||
| t = t / num_inference_steps | ||
| timestep = ( | ||
| torch.tensor([t]).expand(latent_model_input.shape[0]).to(latents.device, dtype=latents.dtype) | ||
| torch.tensor([t / 1000]) | ||
| .expand(latent_model_input.shape[0]) | ||
| .to(latents.device, dtype=latents.dtype) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could unpack this code a bit and perhaps add a comment on why we're dividing by 1000. This is mainly because we're moving away from our normal pipeline implementations a bit which our users are used to reading and referring to.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done! feel free to merge into your PR now |
||
| ) | ||
|
|
||
| # predict noise model_output | ||
|
|
@@ -478,7 +475,7 @@ def __call__( | |
| noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond) | ||
|
|
||
| # compute the previous noisy sample x_t -> x_t-1 | ||
| latents = (latents - dt * noise_pred).to(latents.dtype) | ||
| latents = self.scheduler.step(noise_pred, t, latents, return_dict=False)[0] | ||
|
|
||
| # call the callback, if provided | ||
| if i == len(timesteps) - 1 or ((i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0): | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
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 added this just to get 1:1 with the original implementation, I don't think it's needed here, the difference should be very small, but I didn't test for smaller number of steps
cc @cloneofsimo
without this line

with this line
