Skip to content

Commit 0608d73

Browse files
committed
resolve conflicts
2 parents 9c163c6 + 45b32f4 commit 0608d73

96 files changed

Lines changed: 4936 additions & 9577 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.ai/references/testing.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Follow the style introduced in [#14113](https://github.com/huggingface/diffusers
3434
- `torch.nn.MultiheadAttention` is the common instance: it passes `self.out_proj.weight` straight to `torch.nn.functional.multi_head_attention_forward` instead of calling `self.out_proj`, so the hook on `out_proj` never fires. `SiglipVisionModel`'s attention pooling head wraps one — see `tests/pipelines/hunyuan_video/test_hunyuan_video_framepack.py`, whose `image_encoder` is excluded for this reason.
3535
- `HunyuanDiTAttentionPool` (`src/diffusers/models/embeddings.py`) shows the same failure without an MHA module: a plain `nn.Module` that hands its `q_proj` / `k_proj` / `v_proj` / `c_proj` weights to `torch.nn.functional.multi_head_attention_forward`, so all four projections stay offloaded rather than just one. `HunyuanDiT2DModel` opts out of group offloading entirely with `_supports_group_offloading = False`.
3636
- Before adding a skip or an exclusion, confirm the failure still reproduces — several existing skips are stale, having outlived the upstream cause.
37+
- **`encode_prompt` reading a component that isn't a text encoder or tokenizer?** `test_encode_prompt_works_in_isolation` rebuilds the pipeline with only the components whose names contain `text` or `tokenizer`. When `encode_prompt` also needs another one — a `processor` used for chat templating, say — list it in `text_stack_component_names` on the config class rather than re-implementing the test.
3738
- **IP-Adapter tests** live in their own class decorated with `@is_ip_adapter`, subclassing only the config (not `PipelineTesterMixin`). UNet pipelines that load adapters through the standard `IPAdapterMixin` API compose the shared `IPAdapterTesterMixin` (`tests/pipelines/testing_utils/ip_adapter.py`, exported from `..testing_utils`); pipelines whose IP-Adapter API differs (Flux, for example) keep a bespoke mixin next to their own tests.
3839

3940
#### LoRA tests

src/diffusers/models/transformers/transformer_skyreels_v2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ class SkyReelsV2Transformer3DModel(
563563
_supports_gradient_checkpointing = True
564564
_skip_layerwise_casting_patterns = ["patch_embedding", "condition_embedder", "norm"]
565565
_no_split_modules = ["SkyReelsV2TransformerBlock"]
566-
_keep_in_fp32_modules = ["time_embedder", "scale_shift_table", "norm1", "norm2", "norm3"]
566+
_keep_in_fp32_modules = ["rope", "time_embedder", "scale_shift_table", "norm1", "norm2", "norm3"]
567567
_keys_to_ignore_on_load_unexpected = ["norm_added_q"]
568568
_repeated_blocks = ["SkyReelsV2TransformerBlock"]
569569

src/diffusers/pipelines/latent_diffusion/pipeline_latent_diffusion.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ def __call__(
113113
generation. Can be used to tweak the same generation with different prompts. If not provided, a latents
114114
tensor is generated by sampling using the supplied random `generator`.
115115
output_type (`str`, *optional*, defaults to `"pil"`):
116-
The output format of the generated image. Choose between `PIL.Image` or `np.array`.
116+
The output format of the generated image. Choose between `"pil"` (`PIL.Image`), `"np"` (`np.array`) or
117+
`"pt"` (`torch.Tensor`).
117118
return_dict (`bool`, *optional*, defaults to `True`):
118119
Whether or not to return a [`ImagePipelineOutput`] instead of a plain tuple.
119120
@@ -220,9 +221,12 @@ def __call__(
220221
image = self.vqvae.decode(latents).sample
221222

222223
image = (image / 2 + 0.5).clamp(0, 1)
223-
image = image.cpu().permute(0, 2, 3, 1).numpy()
224-
if output_type == "pil":
225-
image = self.numpy_to_pil(image)
224+
225+
if output_type != "pt":
226+
image = image.cpu().permute(0, 2, 3, 1).numpy()
227+
228+
if output_type == "pil":
229+
image = self.numpy_to_pil(image)
226230

227231
if not return_dict:
228232
return (image,)

src/diffusers/pipelines/latent_diffusion/pipeline_latent_diffusion_superresolution.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ def __call__(
9797
A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make
9898
generation deterministic.
9999
output_type (`str`, *optional*, defaults to `"pil"`):
100-
The output format of the generated image. Choose between `PIL.Image` or `np.array`.
100+
The output format of the generated image. Choose between `"pil"` (`PIL.Image`), `"np"` (`np.array`) or
101+
`"pt"` (`torch.Tensor`).
101102
return_dict (`bool`, *optional*, defaults to `True`):
102103
Whether or not to return a [`ImagePipelineOutput`] instead of a plain tuple.
103104
@@ -185,10 +186,12 @@ def __call__(
185186
image = self.vqvae.decode(latents).sample
186187
image = torch.clamp(image, -1.0, 1.0)
187188
image = image / 2 + 0.5
188-
image = image.cpu().permute(0, 2, 3, 1).numpy()
189189

190-
if output_type == "pil":
191-
image = self.numpy_to_pil(image)
190+
if output_type != "pt":
191+
image = image.cpu().permute(0, 2, 3, 1).numpy()
192+
193+
if output_type == "pil":
194+
image = self.numpy_to_pil(image)
192195

193196
if not return_dict:
194197
return (image,)

src/diffusers/pipelines/skyreels_v2/pipeline_skyreels_v2_diffusion_forcing_i2v.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,8 @@ def __call__(
10351035
# Final decoding step - convert latents to pixels
10361036
if not output_type == "latent":
10371037
if last_image is not None:
1038-
latents = latents[:, :, :-prefix_video_latents_frames, :, :].to(self.vae.dtype)
1038+
latents = latents[:, :, :-prefix_video_latents_frames, :, :]
1039+
latents = latents.to(self.vae.dtype)
10391040
latents_mean = (
10401041
torch.tensor(self.vae.config.latents_mean)
10411042
.view(1, self.vae.config.z_dim, 1, 1, 1)

src/diffusers/pipelines/skyreels_v2/pipeline_skyreels_v2_diffusion_forcing_v2v.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,8 @@ def prepare_latents(
441441
latent_width = width // self.vae_scale_factor_spatial
442442

443443
if long_video_iter == 0:
444+
# `video` is preprocessed in float32; the VAE may be running in another dtype (fp16/bf16).
445+
video = video.to(self.vae.dtype)
444446
prefix_video_latents = [
445447
retrieve_latents(
446448
self.vae.encode(
@@ -1049,7 +1051,9 @@ def __call__(
10491051
)
10501052
latents = latents / latents_std + latents_mean
10511053
video_generated = self.vae.decode(latents, return_dict=False)[0]
1052-
video = torch.cat([video_original, video_generated], dim=2)
1054+
# `video_original` is kept in float32 by `preprocess_video`; promote the decoded frames to match it
1055+
# so the two halves can be concatenated when the VAE runs in fp16/bf16.
1056+
video = torch.cat([video_original, video_generated.to(video_original.dtype)], dim=2)
10531057
video = self.video_processor.postprocess_video(video, output_type=output_type)
10541058
else:
10551059
video = latents

src/diffusers/pipelines/visualcloze/pipeline_visualcloze_combined.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ def __init__(
146146
transformer=transformer,
147147
scheduler=scheduler,
148148
)
149+
# `resolution` is not a module, so it has to be registered explicitly to survive a
150+
# `save_pretrained` / `from_pretrained` round-trip.
151+
self.register_to_config(resolution=resolution)
149152

150153
self.generation_pipe = VisualClozeGenerationPipeline(
151154
vae=vae,
@@ -376,6 +379,10 @@ def __call__(
376379
output_type=output_type if upsampling_strength == 0 else "pil",
377380
)
378381
if upsampling_strength == 0:
382+
# Offload all models. The inner pipelines free their own (empty) hooks, so the ones installed on this
383+
# pipeline by `enable_model_cpu_offload` have to be freed here.
384+
self.maybe_free_model_hooks()
385+
379386
if not return_dict:
380387
return (generation_output,)
381388

@@ -434,6 +441,9 @@ def __call__(
434441
else:
435442
output = image
436443

444+
# Offload all models
445+
self.maybe_free_model_hooks()
446+
437447
if not return_dict:
438448
return (output,)
439449

src/diffusers/pipelines/visualcloze/pipeline_visualcloze_generation.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ def __init__(
175175
transformer=transformer,
176176
scheduler=scheduler,
177177
)
178+
# `resolution` is not a module, so it has to be registered explicitly to survive a
179+
# `save_pretrained` / `from_pretrained` round-trip.
180+
self.register_to_config(resolution=resolution)
178181
self.resolution = resolution
179182
self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1) if getattr(self, "vae", None) else 8
180183
# Flux latents are turned into 2x2 patches and packed. This means the latent width and height has to be divisible
@@ -715,8 +718,9 @@ def __call__(
715718
Pre-generated pooled text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting.
716719
If not provided, pooled text embeddings will be generated from `prompt` input argument.
717720
output_type (`str`, *optional*, defaults to `"pil"`):
718-
The output format of the generate image. Choose between
719-
[PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`.
721+
The output format of the generate image. Choose between `"pil"`
722+
([PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image`), `"np"` (`np.array`) or `"pt"`
723+
(`torch.Tensor`).
720724
return_dict (`bool`, *optional*, defaults to `True`):
721725
Whether or not to return a [`~pipelines.flux.FluxPipelineOutput`] instead of a plain tuple.
722726
joint_attention_kwargs (`dict`, *optional*):
@@ -907,11 +911,17 @@ def __call__(
907911
if cur_target_position[i]:
908912
if output_type == "pil":
909913
cropped.append(cur_image.crop((start, 0, start + size[1], size[0])))
914+
elif output_type == "pt":
915+
# `"pt"` images are `(channels, height, width)`, unlike the `(height, width, channels)`
916+
# layout of `"np"`, so the spatial crop applies to the last two axes.
917+
cropped.append(cur_image[:, 0 : size[0], start : start + size[1]])
910918
else:
911919
cropped.append(cur_image[0 : size[0], start : start + size[1]])
912920
start += size[1]
913921
image.append(cropped)
914-
if output_type != "pil":
922+
if output_type == "pt":
923+
image = torch.stack([arr for sub_image in image for arr in sub_image], dim=0)
924+
elif output_type != "pil":
915925
image = np.concatenate([arr[None] for sub_image in image for arr in sub_image], axis=0)
916926

917927
# Offload all models

tests/modular_pipelines/test_modular_pipelines_custom_blocks.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
)
3737
from diffusers.utils import logging
3838

39-
from ..testing_utils import CaptureLogger, nightly, require_torch, require_torch_accelerator, slow, torch_device
39+
from ..testing_utils import CaptureLogger, nightly, require_torch_accelerator, require_torch_gpu, slow, torch_device
4040

4141

4242
def _create_tiny_model_dir(model_dir):
@@ -722,7 +722,7 @@ def test_kwargs_type_input_in_pipeline_call_params(self):
722722

723723
@slow
724724
@nightly
725-
@require_torch
725+
@require_torch_gpu
726726
class TestKreaCustomBlocksIntegration:
727727
repo_id = "krea/krea-realtime-video"
728728

0 commit comments

Comments
 (0)