Skip to content

Commit f0d286b

Browse files
committed
add flux mu shift
1 parent ee54a19 commit f0d286b

1 file changed

Lines changed: 49 additions & 23 deletions

File tree

src/diffusers/pipelines/hunyuan_video/pipeline_hunyuan_video_framepack.py

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import inspect
16+
import math
1617
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
1718

1819
import numpy as np
@@ -89,6 +90,20 @@
8990
}
9091

9192

93+
# Copied from diffusers.pipelines.flux.pipeline_flux.calculate_shift
94+
def calculate_shift(
95+
image_seq_len,
96+
base_seq_len: int = 256,
97+
max_seq_len: int = 4096,
98+
base_shift: float = 0.5,
99+
max_shift: float = 1.15,
100+
):
101+
m = (max_shift - base_shift) / (max_seq_len - base_seq_len)
102+
b = base_shift - m * base_seq_len
103+
mu = image_seq_len * m + b
104+
return mu
105+
106+
92107
# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.retrieve_timesteps
93108
def retrieve_timesteps(
94109
scheduler,
@@ -356,11 +371,11 @@ def encode_image(
356371
self, image: torch.Tensor, device: Optional[torch.device] = None, dtype: Optional[torch.dtype] = None
357372
):
358373
image = (image + 1) / 2.0 # [-1, 1] -> [0, 1]
359-
image = self.feature_extractor(images=image, return_tensors="pt").to(
374+
image = self.feature_extractor(images=image, return_tensors="pt", do_rescale=False).to(
360375
device=self.image_encoder.device, dtype=self.image_encoder.dtype
361376
)
362377
image_embeds = self.image_encoder(**image).last_hidden_state
363-
return image_embeds.to(dtype=dtype)
378+
return image_embeds.to(device=device, dtype=dtype)
364379

365380
def check_inputs(
366381
self,
@@ -722,6 +737,7 @@ def __call__(
722737
dtype=torch.float32,
723738
)
724739
history_video = None
740+
total_generated_latent_frames = 0
725741

726742
image_latents = self.prepare_image_latents(
727743
image, dtype=torch.float32, device=device, generator=generator, latents=image_latents
@@ -735,19 +751,10 @@ def __call__(
735751
guidance = torch.tensor([guidance_scale] * batch_size, dtype=transformer_dtype, device=device) * 1000.0
736752

737753
# 7. Denoising loop
738-
sigmas = np.linspace(1.0, 0.0, num_inference_steps + 1)[:-1] if sigmas is None else sigmas
739-
740754
for i in range(num_latent_sections):
741-
timesteps, num_inference_steps = retrieve_timesteps(
742-
self.scheduler, num_inference_steps, device, sigmas=sigmas
743-
)
744-
num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order
745-
self._num_timesteps = len(timesteps)
746-
747755
current_latent_padding = latent_paddings[i]
748756
is_last_section = current_latent_padding == 0
749757
latent_padding_size = current_latent_padding * latent_window_size
750-
total_generated_latent_frames = 0
751758

752759
indices = torch.arange(0, sum([1, latent_padding_size, latent_window_size, *history_sizes])).unsqueeze(0)
753760
(
@@ -779,6 +786,25 @@ def __call__(
779786
latents=latents,
780787
)
781788

789+
sigmas = np.linspace(1.0, 0.0, num_inference_steps + 1)[:-1] if sigmas is None else sigmas
790+
image_seq_len = (
791+
latents.shape[1] * latents.shape[2] * latents.shape[3] / self.transformer.config.patch_size**2
792+
)
793+
exp_max = 7.0
794+
mu = calculate_shift(
795+
image_seq_len,
796+
self.scheduler.config.get("base_image_seq_len", 256),
797+
self.scheduler.config.get("max_image_seq_len", 4096),
798+
self.scheduler.config.get("base_shift", 0.5),
799+
self.scheduler.config.get("max_shift", 1.15),
800+
)
801+
mu = min(mu, math.log(exp_max))
802+
timesteps, num_inference_steps = retrieve_timesteps(
803+
self.scheduler, num_inference_steps, device, sigmas=sigmas, mu=mu
804+
)
805+
num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order
806+
self._num_timesteps = len(timesteps)
807+
782808
with self.progress_bar(total=num_inference_steps) as progress_bar:
783809
for i, t in enumerate(timesteps):
784810
if self.interrupt:
@@ -847,7 +873,7 @@ def __call__(
847873
xm.mark_step()
848874

849875
if is_last_section:
850-
latents = torch.cat([latents_prefix, latents])
876+
latents = torch.cat([image_latents, latents], dim=2)
851877

852878
total_generated_latent_frames += latents.shape[2]
853879
history_latents = torch.cat([latents, history_latents], dim=2)
@@ -857,11 +883,11 @@ def __call__(
857883
if history_video is None:
858884
if not output_type == "latent":
859885
current_video = real_history_latents.to(vae_dtype) / self.vae.config.scaling_factor
860-
current_video = self.vae.decode(current_video, return_dict=False)[0]
886+
history_video = self.vae.decode(current_video, return_dict=False)[0]
861887
else:
862888
history_video = [real_history_latents]
863889
else:
864-
if not output_type == "latents":
890+
if not output_type == "latent":
865891
section_latent_frames = (
866892
(latent_window_size * 2 + 1) if is_last_section else (latent_window_size * 2)
867893
)
@@ -871,7 +897,7 @@ def __call__(
871897
/ self.vae.config.scaling_factor
872898
)
873899
current_video = self.vae.decode(current_video, return_dict=False)[0]
874-
current_video = self._soft_append(current_video, history_video, overlapped_frames)
900+
history_video = self._soft_append(current_video, history_video, overlapped_frames)
875901
else:
876902
history_video.append(real_history_latents)
877903

@@ -895,15 +921,15 @@ def __call__(
895921

896922
return HunyuanVideoFramepackPipelineOutput(frames=video)
897923

898-
def _soft_append(current: torch.Tensor, history: torch.Tensor, overlap: int = 0):
924+
def _soft_append(self, history: torch.Tensor, current: torch.Tensor, overlap: int = 0):
899925
if overlap <= 0:
900-
return torch.cat([current, history], dim=2)
926+
return torch.cat([history, current], dim=2)
901927

902-
assert current.shape[2] >= overlap, f"Current length ({current.shape[2]}) must be >= overlap ({overlap})"
903-
assert history.shape[2] >= overlap, f"History length ({history.shape[2]}) must be >= overlap ({overlap})"
928+
assert history.shape[2] >= overlap, f"Current length ({history.shape[2]}) must be >= overlap ({overlap})"
929+
assert current.shape[2] >= overlap, f"History length ({current.shape[2]}) must be >= overlap ({overlap})"
904930

905-
weights = torch.linspace(1, 0, overlap, dtype=current.dtype, device=current.device).view(1, 1, -1, 1, 1)
906-
blended = weights * current[:, :, -overlap:] + (1 - weights) * history[:, :, :overlap]
907-
output = torch.cat([current[:, :, :-overlap], blended, history[:, :, overlap:]], dim=2)
931+
weights = torch.linspace(1, 0, overlap, dtype=history.dtype, device=history.device).view(1, 1, -1, 1, 1)
932+
blended = weights * history[:, :, -overlap:] + (1 - weights) * current[:, :, :overlap]
933+
output = torch.cat([history[:, :, :-overlap], blended, current[:, :, overlap:]], dim=2)
908934

909-
return output.to(current)
935+
return output.to(history)

0 commit comments

Comments
 (0)