Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1866,16 +1866,19 @@ def denoising_value_valid(dnv):
if not output_type == "latent":
image = self.vae.decode(latents / self.vae.config.scaling_factor, return_dict=False)[0]
else:
return StableDiffusionXLPipelineOutput(images=latents)
image = latents

# apply watermark if available
if self.watermark is not None:
image = self.watermark.apply_watermark(image)
if not output_type == "latent":
# apply watermark if available
if self.watermark is not None:
image = self.watermark.apply_watermark(image)

image = self.image_processor.postprocess(image, output_type=output_type)
image = self.image_processor.postprocess(image, output_type=output_type)

if padding_mask_crop is not None:
image = [self.image_processor.apply_overlay(mask_image, original_image, i, crops_coords) for i in image]
if padding_mask_crop is not None:
image = [
self.image_processor.apply_overlay(mask_image, original_image, i, crops_coords) for i in image
]

# Offload all models
self.maybe_free_model_hooks()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1878,16 +1878,19 @@ def denoising_value_valid(dnv):
if not output_type == "latent":
image = self.vae.decode(latents / self.vae.config.scaling_factor, return_dict=False)[0]
else:
return StableDiffusionXLPipelineOutput(images=latents)
image = latents

# apply watermark if available
if self.watermark is not None:
image = self.watermark.apply_watermark(image)
if not output_type == "latent":
# apply watermark if available
if self.watermark is not None:
image = self.watermark.apply_watermark(image)

image = self.image_processor.postprocess(image, output_type=output_type)
image = self.image_processor.postprocess(image, output_type=output_type)

if padding_mask_crop is not None:
image = [self.image_processor.apply_overlay(mask_image, original_image, i, crops_coords) for i in image]
if padding_mask_crop is not None:
image = [
self.image_processor.apply_overlay(mask_image, original_image, i, crops_coords) for i in image
]

# Offload all models
self.maybe_free_model_hooks()
Expand Down
17 changes: 10 additions & 7 deletions src/diffusers/pipelines/pag/pipeline_pag_sd_xl_inpaint.py
Original file line number Diff line number Diff line change
Expand Up @@ -1752,16 +1752,19 @@ def denoising_value_valid(dnv):
if needs_upcasting:
self.vae.to(dtype=torch.float16)
else:
return StableDiffusionXLPipelineOutput(images=latents)
image = latents

# apply watermark if available
if self.watermark is not None:
image = self.watermark.apply_watermark(image)
if not output_type == "latent":
# apply watermark if available
if self.watermark is not None:
image = self.watermark.apply_watermark(image)

image = self.image_processor.postprocess(image, output_type=output_type)
image = self.image_processor.postprocess(image, output_type=output_type)

if padding_mask_crop is not None:
image = [self.image_processor.apply_overlay(mask_image, original_image, i, crops_coords) for i in image]
if padding_mask_crop is not None:
image = [
self.image_processor.apply_overlay(mask_image, original_image, i, crops_coords) for i in image
]

# Offload all models
self.maybe_free_model_hooks()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1714,16 +1714,19 @@ def denoising_value_valid(dnv):
if needs_upcasting:
self.vae.to(dtype=torch.float16)
else:
return StableDiffusionXLPipelineOutput(images=latents)
image = latents

# apply watermark if available
if self.watermark is not None:
image = self.watermark.apply_watermark(image)
if not output_type == "latent":
# apply watermark if available
if self.watermark is not None:
image = self.watermark.apply_watermark(image)

image = self.image_processor.postprocess(image, output_type=output_type)
image = self.image_processor.postprocess(image, output_type=output_type)

if padding_mask_crop is not None:
image = [self.image_processor.apply_overlay(mask_image, original_image, i, crops_coords) for i in image]
if padding_mask_crop is not None:
image = [
self.image_processor.apply_overlay(mask_image, original_image, i, crops_coords) for i in image
]

# Offload all models
self.maybe_free_model_hooks()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -960,13 +960,14 @@ def __call__(
if needs_upcasting:
self.vae.to(dtype=torch.float16)
else:
return StableDiffusionXLPipelineOutput(images=latents)
image = latents

# apply watermark if available
if self.watermark is not None:
image = self.watermark.apply_watermark(image)
if not output_type == "latent":
# apply watermark if available
if self.watermark is not None:
image = self.watermark.apply_watermark(image)

image = self.image_processor.postprocess(image, output_type=output_type)
image = self.image_processor.postprocess(image, output_type=output_type)

# Offload all models
self.maybe_free_model_hooks()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,25 @@ def test_stable_diffusion_xl_inpaint_2_images(self):
image_slice2 = images[1, -1, -3:, -3:]
assert (image_slice1 - image_slice2).abs().max() > 1e-2

def test_latent_output_runs_cleanup_and_honors_return_dict(self):
# Regression: `output_type="latent"` returned `StableDiffusionXLPipelineOutput(images=latents)`
# immediately, which skipped `maybe_free_model_hooks()` and ignored `return_dict=False`.
sd_pipe = self.get_pipeline()

called = {"cleanup": False}
sd_pipe.maybe_free_model_hooks = lambda: called.__setitem__("cleanup", True)

inputs = self.get_dummy_inputs()
inputs["output_type"] = "latent"
inputs["return_dict"] = False
output = sd_pipe(**inputs)

assert called["cleanup"], "`maybe_free_model_hooks()` should still run for latent output."
assert isinstance(output, tuple), "`return_dict=False` should return a tuple."
assert torch.is_tensor(output[0])
# Raw latents keep the VAE latent channel count; postprocess would have produced 3 channels.
assert output[0].shape[1] == sd_pipe.unet.config.in_channels

def test_pipeline_interrupt(self):
sd_pipe = self.get_pipeline().to(torch_device)

Expand Down
Loading