|
66 | 66 | """ |
67 | 67 |
|
68 | 68 |
|
| 69 | +# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.retrieve_timesteps |
69 | 70 | def retrieve_timesteps( |
70 | 71 | scheduler, |
71 | 72 | num_inference_steps: int | None = None, |
@@ -98,24 +99,30 @@ def retrieve_timesteps( |
98 | 99 | second element is the number of inference steps. |
99 | 100 | """ |
100 | 101 | 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") |
103 | 103 | 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 | + ) |
106 | 110 | scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs) |
107 | 111 | timesteps = scheduler.timesteps |
108 | 112 | num_inference_steps = len(timesteps) |
109 | 113 | 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 | + ) |
112 | 120 | scheduler.set_timesteps(sigmas=sigmas, device=device, **kwargs) |
113 | 121 | timesteps = scheduler.timesteps |
114 | 122 | num_inference_steps = len(timesteps) |
115 | 123 | else: |
116 | 124 | scheduler.set_timesteps(num_inference_steps, device=device, **kwargs) |
117 | 125 | timesteps = scheduler.timesteps |
118 | | - |
119 | 126 | return timesteps, num_inference_steps |
120 | 127 |
|
121 | 128 |
|
@@ -390,6 +397,47 @@ def interrupt(self) -> bool: |
390 | 397 | # Forward pass |
391 | 398 | # ------------------------------------------------------------------ |
392 | 399 |
|
| 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 | + |
393 | 441 | @torch.no_grad() |
394 | 442 | @replace_example_docstring(EXAMPLE_DOC_STRING) |
395 | 443 | def __call__( |
@@ -483,6 +531,16 @@ def __call__( |
483 | 531 | if isinstance(images[0], Image.Image): |
484 | 532 | images = [images] # single sample |
485 | 533 |
|
| 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 | + |
486 | 544 | self._guidance_scale = guidance_scale |
487 | 545 | self._interrupt = False |
488 | 546 |
|
|
0 commit comments