Skip to content

Commit d8d3f90

Browse files
authored
fix(bria_fibo): fix guidance_embeds, prompt_embeds, tensor-image and multi-image crashes (huggingface#13981)
* fix(bria_fibo): fix guidance_embeds, prompt_embeds, tensor-image and multi-image crashes * remove unusable precomputed-embeds args and batch-decode output
1 parent eb0a900 commit d8d3f90

3 files changed

Lines changed: 51 additions & 173 deletions

File tree

src/diffusers/models/transformers/transformer_bria_fibo.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ def __init__(
469469
self.time_embed = BriaFiboTimestepProjEmbeddings(embedding_dim=self.inner_dim, time_theta=time_theta)
470470

471471
if guidance_embeds:
472-
self.guidance_embed = BriaFiboTimestepProjEmbeddings(embedding_dim=self.inner_dim)
472+
self.guidance_embed = BriaFiboTimestepProjEmbeddings(embedding_dim=self.inner_dim, time_theta=time_theta)
473473

474474
self.context_embedder = nn.Linear(self.config.joint_attention_dim, self.inner_dim)
475475
self.x_embedder = torch.nn.Linear(self.config.in_channels, self.inner_dim)
@@ -562,7 +562,7 @@ def forward(
562562

563563
temb = self.time_embed(timestep, dtype=hidden_states.dtype)
564564

565-
if guidance:
565+
if guidance is not None:
566566
temb += self.guidance_embed(guidance, dtype=hidden_states.dtype)
567567

568568
encoder_hidden_states = self.context_embedder(encoder_hidden_states)

src/diffusers/pipelines/bria_fibo/pipeline_bria_fibo.py

Lines changed: 24 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,6 @@ def encode_prompt(
205205
num_images_per_prompt: int = 1,
206206
guidance_scale: float = 5,
207207
negative_prompt: str | list[str] | None = None,
208-
prompt_embeds: torch.FloatTensor | None = None,
209-
negative_prompt_embeds: torch.FloatTensor | None = None,
210208
max_sequence_length: int = 3000,
211209
lora_scale: float | None = None,
212210
):
@@ -221,16 +219,8 @@ def encode_prompt(
221219
guidance_scale (`float`):
222220
Guidance scale for classifier free guidance.
223221
negative_prompt (`str` or `list[str]`, *optional*):
224-
The prompt or prompts not to guide the image generation. If not defined, one has to pass
225-
`negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is
226-
less than `1`).
227-
prompt_embeds (`torch.FloatTensor`, *optional*):
228-
Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not
229-
provided, text embeddings will be generated from `prompt` input argument.
230-
negative_prompt_embeds (`torch.FloatTensor`, *optional*):
231-
Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt
232-
weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input
233-
argument.
222+
The prompt or prompts not to guide the image generation. Ignored when not using guidance (i.e., ignored
223+
if `guidance_scale` is less than `1`).
234224
"""
235225
device = device or self._execution_device
236226

@@ -244,22 +234,19 @@ def encode_prompt(
244234
scale_lora_layers(self.text_encoder, lora_scale)
245235

246236
prompt = [prompt] if isinstance(prompt, str) else prompt
247-
if prompt is not None:
248-
batch_size = len(prompt)
249-
else:
250-
batch_size = prompt_embeds.shape[0]
237+
batch_size = len(prompt)
251238

252239
prompt_attention_mask = None
253240
negative_prompt_attention_mask = None
254-
if prompt_embeds is None:
255-
prompt_embeds, prompt_layers, prompt_attention_mask = self.get_prompt_embeds(
256-
prompt=prompt,
257-
num_images_per_prompt=num_images_per_prompt,
258-
max_sequence_length=max_sequence_length,
259-
device=device,
260-
)
261-
prompt_embeds = prompt_embeds.to(dtype=self.transformer.dtype)
262-
prompt_layers = [tensor.to(dtype=self.transformer.dtype) for tensor in prompt_layers]
241+
negative_prompt_embeds = None
242+
prompt_embeds, prompt_layers, prompt_attention_mask = self.get_prompt_embeds(
243+
prompt=prompt,
244+
num_images_per_prompt=num_images_per_prompt,
245+
max_sequence_length=max_sequence_length,
246+
device=device,
247+
)
248+
prompt_embeds = prompt_embeds.to(dtype=self.transformer.dtype)
249+
prompt_layers = [tensor.to(dtype=self.transformer.dtype) for tensor in prompt_layers]
263250

264251
if guidance_scale > 1:
265252
if isinstance(negative_prompt, list) and negative_prompt[0] is None:
@@ -469,8 +456,6 @@ def __call__(
469456
num_images_per_prompt: int | None = 1,
470457
generator: torch.Generator | list[torch.Generator] | None = None,
471458
latents: torch.FloatTensor | None = None,
472-
prompt_embeds: torch.FloatTensor | None = None,
473-
negative_prompt_embeds: torch.FloatTensor | None = None,
474459
output_type: str | None = "pil",
475460
return_dict: bool = True,
476461
joint_attention_kwargs: dict[str, Any] | None = None,
@@ -483,9 +468,8 @@ def __call__(
483468
Function invoked when calling the pipeline for generation.
484469
485470
Args:
486-
prompt (`str` or `list[str]`, *optional*):
487-
The prompt or prompts to guide the image generation. If not defined, one has to pass `prompt_embeds`.
488-
instead.
471+
prompt (`str` or `list[str]`):
472+
The prompt or prompts to guide the image generation.
489473
height (`int`, *optional*, defaults to self.unet.config.sample_size * self.vae_scale_factor):
490474
The height in pixels of the generated image. This is set to 1024 by default for the best results.
491475
width (`int`, *optional*, defaults to self.unet.config.sample_size * self.vae_scale_factor):
@@ -504,9 +488,8 @@ def __call__(
504488
`guidance_scale > 1`. Higher guidance scale encourages to generate images that are closely linked to
505489
the text `prompt`, usually at the expense of lower image quality.
506490
negative_prompt (`str` or `list[str]`, *optional*):
507-
The prompt or prompts not to guide the image generation. If not defined, one has to pass
508-
`negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is
509-
less than `1`).
491+
The prompt or prompts not to guide the image generation. Ignored when not using guidance (i.e., ignored
492+
if `guidance_scale` is less than `1`).
510493
num_images_per_prompt (`int`, *optional*, defaults to 1):
511494
The number of images to generate per prompt.
512495
generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
@@ -516,13 +499,6 @@ def __call__(
516499
Pre-generated noisy latents, sampled from a Gaussian distribution, to be used as inputs for image
517500
generation. Can be used to tweak the same generation with different prompts. If not provided, a latents
518501
tensor will ge generated by sampling using the supplied random `generator`.
519-
prompt_embeds (`torch.FloatTensor`, *optional*):
520-
Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not
521-
provided, text embeddings will be generated from `prompt` input argument.
522-
negative_prompt_embeds (`torch.FloatTensor`, *optional*):
523-
Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt
524-
weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input
525-
argument.
526502
output_type (`str`, *optional*, defaults to `"pil"`):
527503
The output format of the generate image. Choose between
528504
[PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`.
@@ -559,7 +535,6 @@ def __call__(
559535
prompt=prompt,
560536
height=height,
561537
width=width,
562-
prompt_embeds=prompt_embeds,
563538
callback_on_step_end_tensor_inputs=callback_on_step_end_tensor_inputs,
564539
max_sequence_length=max_sequence_length,
565540
)
@@ -569,12 +544,10 @@ def __call__(
569544
self._interrupt = False
570545

571546
# 2. Define call parameters
572-
if prompt is not None and isinstance(prompt, str):
547+
if isinstance(prompt, str):
573548
batch_size = 1
574-
elif prompt is not None and isinstance(prompt, list):
575-
batch_size = len(prompt)
576549
else:
577-
batch_size = prompt_embeds.shape[0]
550+
batch_size = len(prompt)
578551

579552
device = self._execution_device
580553

@@ -594,8 +567,6 @@ def __call__(
594567
prompt=prompt,
595568
negative_prompt=negative_prompt,
596569
guidance_scale=guidance_scale,
597-
prompt_embeds=prompt_embeds,
598-
negative_prompt_embeds=negative_prompt_embeds,
599570
device=device,
600571
max_sequence_length=max_sequence_length,
601572
num_images_per_prompt=num_images_per_prompt,
@@ -767,17 +738,9 @@ def __call__(
767738
latents_std = 1.0 / torch.tensor(self.vae.config.latents_std).view(1, self.vae.config.z_dim, 1, 1, 1).to(
768739
latents_device, latents_dtype
769740
)
770-
latents_scaled = [latent / latents_std + latents_mean for latent in latents]
771-
latents_scaled = torch.cat(latents_scaled, dim=0)
772-
image = []
773-
for scaled_latent in latents_scaled:
774-
curr_image = self.vae.decode(scaled_latent.unsqueeze(0), return_dict=False)[0]
775-
curr_image = self.image_processor.postprocess(curr_image.squeeze(dim=2), output_type=output_type)
776-
image.append(curr_image)
777-
if len(image) == 1:
778-
image = image[0]
779-
else:
780-
image = np.stack(image, axis=0)
741+
latents_scaled = torch.cat([latent / latents_std + latents_mean for latent in latents], dim=0)
742+
image = self.vae.decode(latents_scaled, return_dict=False)[0]
743+
image = self.image_processor.postprocess(image.squeeze(dim=2), output_type=output_type)
781744

782745
# Offload all models
783746
self.maybe_free_model_hooks()
@@ -792,9 +755,6 @@ def check_inputs(
792755
prompt,
793756
height,
794757
width,
795-
negative_prompt=None,
796-
prompt_embeds=None,
797-
negative_prompt_embeds=None,
798758
callback_on_step_end_tensor_inputs=None,
799759
max_sequence_length=None,
800760
):
@@ -808,31 +768,10 @@ def check_inputs(
808768
f"`callback_on_step_end_tensor_inputs` has to be in {self._callback_tensor_inputs}, but found {[k for k in callback_on_step_end_tensor_inputs if k not in self._callback_tensor_inputs]}"
809769
)
810770

811-
if prompt is not None and prompt_embeds is not None:
812-
raise ValueError(
813-
f"Cannot forward both `prompt`: {prompt} and `prompt_embeds`: {prompt_embeds}. Please make sure to"
814-
" only forward one of the two."
815-
)
816-
elif prompt is None and prompt_embeds is None:
817-
raise ValueError(
818-
"Provide either `prompt` or `prompt_embeds`. Cannot leave both `prompt` and `prompt_embeds` undefined."
819-
)
820-
elif prompt is not None and (not isinstance(prompt, str) and not isinstance(prompt, list)):
771+
if prompt is None:
772+
raise ValueError("`prompt` must be provided.")
773+
elif not isinstance(prompt, (str, list)):
821774
raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}")
822775

823-
if negative_prompt is not None and negative_prompt_embeds is not None:
824-
raise ValueError(
825-
f"Cannot forward both `negative_prompt`: {negative_prompt} and `negative_prompt_embeds`:"
826-
f" {negative_prompt_embeds}. Please make sure to only forward one of the two."
827-
)
828-
829-
if prompt_embeds is not None and negative_prompt_embeds is not None:
830-
if prompt_embeds.shape != negative_prompt_embeds.shape:
831-
raise ValueError(
832-
"`prompt_embeds` and `negative_prompt_embeds` must have the same shape when passed directly, but"
833-
f" got: `prompt_embeds` {prompt_embeds.shape} != `negative_prompt_embeds`"
834-
f" {negative_prompt_embeds.shape}."
835-
)
836-
837776
if max_sequence_length is not None and max_sequence_length > 3000:
838777
raise ValueError(f"`max_sequence_length` cannot be greater than 3000 but is {max_sequence_length}")

0 commit comments

Comments
 (0)