Skip to content

Commit 967a4ba

Browse files
author
tangyanfei.8
committed
refactor: address dg845 second-round review comments
- Fix vae_image_processor -> image_processor in docs - Remove empty __init__ from AttnProcessor - Restore # Copied from on retrieve_timesteps and sync with source - Add check_inputs method for basic input validation - Remove unnecessary test skip for test_from_save_pretrained_dtype_inference
1 parent 8822e45 commit 967a4ba

4 files changed

Lines changed: 67 additions & 14 deletions

File tree

docs/source/en/api/pipelines/joyimage_edit_plus.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ images = [
3535
Image.open("reference_1.png").convert("RGB"),
3636
]
3737

38-
target_h, target_w = pipeline.vae_image_processor.get_default_height_width(images[-1])
38+
target_h, target_w = pipeline.image_processor.get_default_height_width(images[-1])
3939

4040
output = pipeline(
4141
images=images,

src/diffusers/models/transformers/transformer_joyimage_edit_plus.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,6 @@ class JoyImageEditPlusAttnProcessor:
8080
_attention_backend = None
8181
_parallel_config = None
8282

83-
def __init__(self):
84-
pass
85-
8683
def __call__(
8784
self,
8885
attn: "JoyImageEditPlusAttention",

src/diffusers/pipelines/joyimage/pipeline_joyimage_edit_plus.py

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"""
6767

6868

69+
# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.retrieve_timesteps
6970
def retrieve_timesteps(
7071
scheduler,
7172
num_inference_steps: int | None = None,
@@ -98,24 +99,30 @@ def retrieve_timesteps(
9899
second element is the number of inference steps.
99100
"""
100101
if timesteps is not None and sigmas is not None:
101-
raise ValueError("Only one of `timesteps` or `sigmas` can be passed.")
102-
102+
raise ValueError("Only one of `timesteps` or `sigmas` can be passed. Please choose one to set custom values")
103103
if timesteps is not None:
104-
if "timesteps" not in set(inspect.signature(scheduler.set_timesteps).parameters.keys()):
105-
raise ValueError(f"{scheduler.__class__} does not support custom timesteps.")
104+
accepts_timesteps = "timesteps" in set(inspect.signature(scheduler.set_timesteps).parameters.keys())
105+
if not accepts_timesteps:
106+
raise ValueError(
107+
f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom"
108+
f" timestep schedules. Please check whether you are using the correct scheduler."
109+
)
106110
scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs)
107111
timesteps = scheduler.timesteps
108112
num_inference_steps = len(timesteps)
109113
elif sigmas is not None:
110-
if "sigmas" not in set(inspect.signature(scheduler.set_timesteps).parameters.keys()):
111-
raise ValueError(f"{scheduler.__class__} does not support custom sigmas.")
114+
accept_sigmas = "sigmas" in set(inspect.signature(scheduler.set_timesteps).parameters.keys())
115+
if not accept_sigmas:
116+
raise ValueError(
117+
f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom"
118+
f" sigmas schedules. Please check whether you are using the correct scheduler."
119+
)
112120
scheduler.set_timesteps(sigmas=sigmas, device=device, **kwargs)
113121
timesteps = scheduler.timesteps
114122
num_inference_steps = len(timesteps)
115123
else:
116124
scheduler.set_timesteps(num_inference_steps, device=device, **kwargs)
117125
timesteps = scheduler.timesteps
118-
119126
return timesteps, num_inference_steps
120127

121128

@@ -390,6 +397,47 @@ def interrupt(self) -> bool:
390397
# Forward pass
391398
# ------------------------------------------------------------------
392399

400+
def check_inputs(
401+
self,
402+
prompt,
403+
height,
404+
width,
405+
negative_prompt=None,
406+
prompt_embeds=None,
407+
negative_prompt_embeds=None,
408+
callback_on_step_end_tensor_inputs=None,
409+
):
410+
if height is not None and height % self.vae_scale_factor_spatial != 0:
411+
raise ValueError(f"`height` must be divisible by {self.vae_scale_factor_spatial} but is {height}.")
412+
if width is not None and width % self.vae_scale_factor_spatial != 0:
413+
raise ValueError(f"`width` must be divisible by {self.vae_scale_factor_spatial} but is {width}.")
414+
415+
if callback_on_step_end_tensor_inputs is not None and not all(
416+
k in self._callback_tensor_inputs for k in callback_on_step_end_tensor_inputs
417+
):
418+
raise ValueError(
419+
f"`callback_on_step_end_tensor_inputs` has to be in {self._callback_tensor_inputs}, but found"
420+
f" {[k for k in callback_on_step_end_tensor_inputs if k not in self._callback_tensor_inputs]}"
421+
)
422+
423+
if prompt is not None and prompt_embeds is not None:
424+
raise ValueError(
425+
f"Cannot forward both `prompt`: {prompt} and `prompt_embeds`: {prompt_embeds}. Please make sure to"
426+
" only forward one of the two."
427+
)
428+
elif prompt is None and prompt_embeds is None:
429+
raise ValueError(
430+
"Provide either `prompt` or `prompt_embeds`. Cannot leave both `prompt` and `prompt_embeds` undefined."
431+
)
432+
elif prompt is not None and (not isinstance(prompt, str) and not isinstance(prompt, list)):
433+
raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}")
434+
435+
if negative_prompt is not None and negative_prompt_embeds is not None:
436+
raise ValueError(
437+
f"Cannot forward both `negative_prompt`: {negative_prompt} and `negative_prompt_embeds`:"
438+
f" {negative_prompt_embeds}. Please make sure to only forward one of the two."
439+
)
440+
393441
@torch.no_grad()
394442
@replace_example_docstring(EXAMPLE_DOC_STRING)
395443
def __call__(
@@ -483,6 +531,16 @@ def __call__(
483531
if isinstance(images[0], Image.Image):
484532
images = [images] # single sample
485533

534+
self.check_inputs(
535+
prompt=prompt,
536+
height=height,
537+
width=width,
538+
negative_prompt=negative_prompt,
539+
prompt_embeds=prompt_embeds,
540+
negative_prompt_embeds=negative_prompt_embeds,
541+
callback_on_step_end_tensor_inputs=callback_on_step_end_tensor_inputs,
542+
)
543+
486544
self._guidance_scale = guidance_scale
487545
self._interrupt = False
488546

tests/models/transformers/test_models_transformer_joyimage_edit_plus.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,7 @@ def get_dummy_inputs(self) -> dict[str, torch.Tensor]:
9191

9292

9393
class TestJoyImageEditPlusTransformer(JoyImageEditPlusTransformerTesterConfig, ModelTesterMixin):
94-
@pytest.mark.parametrize("dtype", [torch.float16, torch.bfloat16], ids=["fp16", "bf16"])
95-
def test_from_save_pretrained_dtype_inference(self, tmp_path, dtype):
96-
pytest.skip("Tolerance requirements too high for meaningful test")
94+
pass
9795

9896

9997
class TestJoyImageEditPlusTransformerMemory(JoyImageEditPlusTransformerTesterConfig, MemoryTesterMixin):

0 commit comments

Comments
 (0)