Path: blob/main/examples/community/lpw_stable_diffusion.py
1448 views
import inspect1import re2from typing import Callable, List, Optional, Union34import numpy as np5import PIL6import torch7from packaging import version8from transformers import CLIPImageProcessor, CLIPTextModel, CLIPTokenizer910import diffusers11from diffusers import SchedulerMixin, StableDiffusionPipeline12from diffusers.models import AutoencoderKL, UNet2DConditionModel13from diffusers.pipelines.stable_diffusion import StableDiffusionPipelineOutput, StableDiffusionSafetyChecker14from diffusers.utils import logging151617try:18from diffusers.utils import PIL_INTERPOLATION19except ImportError:20if version.parse(version.parse(PIL.__version__).base_version) >= version.parse("9.1.0"):21PIL_INTERPOLATION = {22"linear": PIL.Image.Resampling.BILINEAR,23"bilinear": PIL.Image.Resampling.BILINEAR,24"bicubic": PIL.Image.Resampling.BICUBIC,25"lanczos": PIL.Image.Resampling.LANCZOS,26"nearest": PIL.Image.Resampling.NEAREST,27}28else:29PIL_INTERPOLATION = {30"linear": PIL.Image.LINEAR,31"bilinear": PIL.Image.BILINEAR,32"bicubic": PIL.Image.BICUBIC,33"lanczos": PIL.Image.LANCZOS,34"nearest": PIL.Image.NEAREST,35}36# ------------------------------------------------------------------------------3738logger = logging.get_logger(__name__) # pylint: disable=invalid-name3940re_attention = re.compile(41r"""42\\\(|43\\\)|44\\\[|45\\]|46\\\\|47\\|48\(|49\[|50:([+-]?[.\d]+)\)|51\)|52]|53[^\\()\[\]:]+|54:55""",56re.X,57)585960def parse_prompt_attention(text):61"""62Parses a string with attention tokens and returns a list of pairs: text and its associated weight.63Accepted tokens are:64(abc) - increases attention to abc by a multiplier of 1.165(abc:3.12) - increases attention to abc by a multiplier of 3.1266[abc] - decreases attention to abc by a multiplier of 1.167\( - literal character '('68\[ - literal character '['69\) - literal character ')'70\] - literal character ']'71\\ - literal character '\'72anything else - just text73>>> parse_prompt_attention('normal text')74[['normal text', 1.0]]75>>> parse_prompt_attention('an (important) word')76[['an ', 1.0], ['important', 1.1], [' word', 1.0]]77>>> parse_prompt_attention('(unbalanced')78[['unbalanced', 1.1]]79>>> parse_prompt_attention('\(literal\]')80[['(literal]', 1.0]]81>>> parse_prompt_attention('(unnecessary)(parens)')82[['unnecessaryparens', 1.1]]83>>> parse_prompt_attention('a (((house:1.3)) [on] a (hill:0.5), sun, (((sky))).')84[['a ', 1.0],85['house', 1.5730000000000004],86[' ', 1.1],87['on', 1.0],88[' a ', 1.1],89['hill', 0.55],90[', sun, ', 1.1],91['sky', 1.4641000000000006],92['.', 1.1]]93"""9495res = []96round_brackets = []97square_brackets = []9899round_bracket_multiplier = 1.1100square_bracket_multiplier = 1 / 1.1101102def multiply_range(start_position, multiplier):103for p in range(start_position, len(res)):104res[p][1] *= multiplier105106for m in re_attention.finditer(text):107text = m.group(0)108weight = m.group(1)109110if text.startswith("\\"):111res.append([text[1:], 1.0])112elif text == "(":113round_brackets.append(len(res))114elif text == "[":115square_brackets.append(len(res))116elif weight is not None and len(round_brackets) > 0:117multiply_range(round_brackets.pop(), float(weight))118elif text == ")" and len(round_brackets) > 0:119multiply_range(round_brackets.pop(), round_bracket_multiplier)120elif text == "]" and len(square_brackets) > 0:121multiply_range(square_brackets.pop(), square_bracket_multiplier)122else:123res.append([text, 1.0])124125for pos in round_brackets:126multiply_range(pos, round_bracket_multiplier)127128for pos in square_brackets:129multiply_range(pos, square_bracket_multiplier)130131if len(res) == 0:132res = [["", 1.0]]133134# merge runs of identical weights135i = 0136while i + 1 < len(res):137if res[i][1] == res[i + 1][1]:138res[i][0] += res[i + 1][0]139res.pop(i + 1)140else:141i += 1142143return res144145146def get_prompts_with_weights(pipe: StableDiffusionPipeline, prompt: List[str], max_length: int):147r"""148Tokenize a list of prompts and return its tokens with weights of each token.149150No padding, starting or ending token is included.151"""152tokens = []153weights = []154truncated = False155for text in prompt:156texts_and_weights = parse_prompt_attention(text)157text_token = []158text_weight = []159for word, weight in texts_and_weights:160# tokenize and discard the starting and the ending token161token = pipe.tokenizer(word).input_ids[1:-1]162text_token += token163# copy the weight by length of token164text_weight += [weight] * len(token)165# stop if the text is too long (longer than truncation limit)166if len(text_token) > max_length:167truncated = True168break169# truncate170if len(text_token) > max_length:171truncated = True172text_token = text_token[:max_length]173text_weight = text_weight[:max_length]174tokens.append(text_token)175weights.append(text_weight)176if truncated:177logger.warning("Prompt was truncated. Try to shorten the prompt or increase max_embeddings_multiples")178return tokens, weights179180181def pad_tokens_and_weights(tokens, weights, max_length, bos, eos, no_boseos_middle=True, chunk_length=77):182r"""183Pad the tokens (with starting and ending tokens) and weights (with 1.0) to max_length.184"""185max_embeddings_multiples = (max_length - 2) // (chunk_length - 2)186weights_length = max_length if no_boseos_middle else max_embeddings_multiples * chunk_length187for i in range(len(tokens)):188tokens[i] = [bos] + tokens[i] + [eos] * (max_length - 1 - len(tokens[i]))189if no_boseos_middle:190weights[i] = [1.0] + weights[i] + [1.0] * (max_length - 1 - len(weights[i]))191else:192w = []193if len(weights[i]) == 0:194w = [1.0] * weights_length195else:196for j in range(max_embeddings_multiples):197w.append(1.0) # weight for starting token in this chunk198w += weights[i][j * (chunk_length - 2) : min(len(weights[i]), (j + 1) * (chunk_length - 2))]199w.append(1.0) # weight for ending token in this chunk200w += [1.0] * (weights_length - len(w))201weights[i] = w[:]202203return tokens, weights204205206def get_unweighted_text_embeddings(207pipe: StableDiffusionPipeline,208text_input: torch.Tensor,209chunk_length: int,210no_boseos_middle: Optional[bool] = True,211):212"""213When the length of tokens is a multiple of the capacity of the text encoder,214it should be split into chunks and sent to the text encoder individually.215"""216max_embeddings_multiples = (text_input.shape[1] - 2) // (chunk_length - 2)217if max_embeddings_multiples > 1:218text_embeddings = []219for i in range(max_embeddings_multiples):220# extract the i-th chunk221text_input_chunk = text_input[:, i * (chunk_length - 2) : (i + 1) * (chunk_length - 2) + 2].clone()222223# cover the head and the tail by the starting and the ending tokens224text_input_chunk[:, 0] = text_input[0, 0]225text_input_chunk[:, -1] = text_input[0, -1]226text_embedding = pipe.text_encoder(text_input_chunk)[0]227228if no_boseos_middle:229if i == 0:230# discard the ending token231text_embedding = text_embedding[:, :-1]232elif i == max_embeddings_multiples - 1:233# discard the starting token234text_embedding = text_embedding[:, 1:]235else:236# discard both starting and ending tokens237text_embedding = text_embedding[:, 1:-1]238239text_embeddings.append(text_embedding)240text_embeddings = torch.concat(text_embeddings, axis=1)241else:242text_embeddings = pipe.text_encoder(text_input)[0]243return text_embeddings244245246def get_weighted_text_embeddings(247pipe: StableDiffusionPipeline,248prompt: Union[str, List[str]],249uncond_prompt: Optional[Union[str, List[str]]] = None,250max_embeddings_multiples: Optional[int] = 3,251no_boseos_middle: Optional[bool] = False,252skip_parsing: Optional[bool] = False,253skip_weighting: Optional[bool] = False,254):255r"""256Prompts can be assigned with local weights using brackets. For example,257prompt 'A (very beautiful) masterpiece' highlights the words 'very beautiful',258and the embedding tokens corresponding to the words get multiplied by a constant, 1.1.259260Also, to regularize of the embedding, the weighted embedding would be scaled to preserve the original mean.261262Args:263pipe (`StableDiffusionPipeline`):264Pipe to provide access to the tokenizer and the text encoder.265prompt (`str` or `List[str]`):266The prompt or prompts to guide the image generation.267uncond_prompt (`str` or `List[str]`):268The unconditional prompt or prompts for guide the image generation. If unconditional prompt269is provided, the embeddings of prompt and uncond_prompt are concatenated.270max_embeddings_multiples (`int`, *optional*, defaults to `3`):271The max multiple length of prompt embeddings compared to the max output length of text encoder.272no_boseos_middle (`bool`, *optional*, defaults to `False`):273If the length of text token is multiples of the capacity of text encoder, whether reserve the starting and274ending token in each of the chunk in the middle.275skip_parsing (`bool`, *optional*, defaults to `False`):276Skip the parsing of brackets.277skip_weighting (`bool`, *optional*, defaults to `False`):278Skip the weighting. When the parsing is skipped, it is forced True.279"""280max_length = (pipe.tokenizer.model_max_length - 2) * max_embeddings_multiples + 2281if isinstance(prompt, str):282prompt = [prompt]283284if not skip_parsing:285prompt_tokens, prompt_weights = get_prompts_with_weights(pipe, prompt, max_length - 2)286if uncond_prompt is not None:287if isinstance(uncond_prompt, str):288uncond_prompt = [uncond_prompt]289uncond_tokens, uncond_weights = get_prompts_with_weights(pipe, uncond_prompt, max_length - 2)290else:291prompt_tokens = [292token[1:-1] for token in pipe.tokenizer(prompt, max_length=max_length, truncation=True).input_ids293]294prompt_weights = [[1.0] * len(token) for token in prompt_tokens]295if uncond_prompt is not None:296if isinstance(uncond_prompt, str):297uncond_prompt = [uncond_prompt]298uncond_tokens = [299token[1:-1]300for token in pipe.tokenizer(uncond_prompt, max_length=max_length, truncation=True).input_ids301]302uncond_weights = [[1.0] * len(token) for token in uncond_tokens]303304# round up the longest length of tokens to a multiple of (model_max_length - 2)305max_length = max([len(token) for token in prompt_tokens])306if uncond_prompt is not None:307max_length = max(max_length, max([len(token) for token in uncond_tokens]))308309max_embeddings_multiples = min(310max_embeddings_multiples,311(max_length - 1) // (pipe.tokenizer.model_max_length - 2) + 1,312)313max_embeddings_multiples = max(1, max_embeddings_multiples)314max_length = (pipe.tokenizer.model_max_length - 2) * max_embeddings_multiples + 2315316# pad the length of tokens and weights317bos = pipe.tokenizer.bos_token_id318eos = pipe.tokenizer.eos_token_id319prompt_tokens, prompt_weights = pad_tokens_and_weights(320prompt_tokens,321prompt_weights,322max_length,323bos,324eos,325no_boseos_middle=no_boseos_middle,326chunk_length=pipe.tokenizer.model_max_length,327)328prompt_tokens = torch.tensor(prompt_tokens, dtype=torch.long, device=pipe.device)329if uncond_prompt is not None:330uncond_tokens, uncond_weights = pad_tokens_and_weights(331uncond_tokens,332uncond_weights,333max_length,334bos,335eos,336no_boseos_middle=no_boseos_middle,337chunk_length=pipe.tokenizer.model_max_length,338)339uncond_tokens = torch.tensor(uncond_tokens, dtype=torch.long, device=pipe.device)340341# get the embeddings342text_embeddings = get_unweighted_text_embeddings(343pipe,344prompt_tokens,345pipe.tokenizer.model_max_length,346no_boseos_middle=no_boseos_middle,347)348prompt_weights = torch.tensor(prompt_weights, dtype=text_embeddings.dtype, device=pipe.device)349if uncond_prompt is not None:350uncond_embeddings = get_unweighted_text_embeddings(351pipe,352uncond_tokens,353pipe.tokenizer.model_max_length,354no_boseos_middle=no_boseos_middle,355)356uncond_weights = torch.tensor(uncond_weights, dtype=uncond_embeddings.dtype, device=pipe.device)357358# assign weights to the prompts and normalize in the sense of mean359# TODO: should we normalize by chunk or in a whole (current implementation)?360if (not skip_parsing) and (not skip_weighting):361previous_mean = text_embeddings.float().mean(axis=[-2, -1]).to(text_embeddings.dtype)362text_embeddings *= prompt_weights.unsqueeze(-1)363current_mean = text_embeddings.float().mean(axis=[-2, -1]).to(text_embeddings.dtype)364text_embeddings *= (previous_mean / current_mean).unsqueeze(-1).unsqueeze(-1)365if uncond_prompt is not None:366previous_mean = uncond_embeddings.float().mean(axis=[-2, -1]).to(uncond_embeddings.dtype)367uncond_embeddings *= uncond_weights.unsqueeze(-1)368current_mean = uncond_embeddings.float().mean(axis=[-2, -1]).to(uncond_embeddings.dtype)369uncond_embeddings *= (previous_mean / current_mean).unsqueeze(-1).unsqueeze(-1)370371if uncond_prompt is not None:372return text_embeddings, uncond_embeddings373return text_embeddings, None374375376def preprocess_image(image):377w, h = image.size378w, h = map(lambda x: x - x % 32, (w, h)) # resize to integer multiple of 32379image = image.resize((w, h), resample=PIL_INTERPOLATION["lanczos"])380image = np.array(image).astype(np.float32) / 255.0381image = image[None].transpose(0, 3, 1, 2)382image = torch.from_numpy(image)383return 2.0 * image - 1.0384385386def preprocess_mask(mask, scale_factor=8):387mask = mask.convert("L")388w, h = mask.size389w, h = map(lambda x: x - x % 32, (w, h)) # resize to integer multiple of 32390mask = mask.resize((w // scale_factor, h // scale_factor), resample=PIL_INTERPOLATION["nearest"])391mask = np.array(mask).astype(np.float32) / 255.0392mask = np.tile(mask, (4, 1, 1))393mask = mask[None].transpose(0, 1, 2, 3) # what does this step do?394mask = 1 - mask # repaint white, keep black395mask = torch.from_numpy(mask)396return mask397398399class StableDiffusionLongPromptWeightingPipeline(StableDiffusionPipeline):400r"""401Pipeline for text-to-image generation using Stable Diffusion without tokens length limit, and support parsing402weighting in prompt.403404This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods the405library implements for all the pipelines (such as downloading or saving, running on a particular device, etc.)406407Args:408vae ([`AutoencoderKL`]):409Variational Auto-Encoder (VAE) Model to encode and decode images to and from latent representations.410text_encoder ([`CLIPTextModel`]):411Frozen text-encoder. Stable Diffusion uses the text portion of412[CLIP](https://huggingface.co/docs/transformers/model_doc/clip#transformers.CLIPTextModel), specifically413the [clip-vit-large-patch14](https://huggingface.co/openai/clip-vit-large-patch14) variant.414tokenizer (`CLIPTokenizer`):415Tokenizer of class416[CLIPTokenizer](https://huggingface.co/docs/transformers/v4.21.0/en/model_doc/clip#transformers.CLIPTokenizer).417unet ([`UNet2DConditionModel`]): Conditional U-Net architecture to denoise the encoded image latents.418scheduler ([`SchedulerMixin`]):419A scheduler to be used in combination with `unet` to denoise the encoded image latents. Can be one of420[`DDIMScheduler`], [`LMSDiscreteScheduler`], or [`PNDMScheduler`].421safety_checker ([`StableDiffusionSafetyChecker`]):422Classification module that estimates whether generated images could be considered offensive or harmful.423Please, refer to the [model card](https://huggingface.co/CompVis/stable-diffusion-v1-4) for details.424feature_extractor ([`CLIPImageProcessor`]):425Model that extracts features from generated images to be used as inputs for the `safety_checker`.426"""427428if version.parse(version.parse(diffusers.__version__).base_version) >= version.parse("0.9.0"):429430def __init__(431self,432vae: AutoencoderKL,433text_encoder: CLIPTextModel,434tokenizer: CLIPTokenizer,435unet: UNet2DConditionModel,436scheduler: SchedulerMixin,437safety_checker: StableDiffusionSafetyChecker,438feature_extractor: CLIPImageProcessor,439requires_safety_checker: bool = True,440):441super().__init__(442vae=vae,443text_encoder=text_encoder,444tokenizer=tokenizer,445unet=unet,446scheduler=scheduler,447safety_checker=safety_checker,448feature_extractor=feature_extractor,449requires_safety_checker=requires_safety_checker,450)451self.__init__additional__()452453else:454455def __init__(456self,457vae: AutoencoderKL,458text_encoder: CLIPTextModel,459tokenizer: CLIPTokenizer,460unet: UNet2DConditionModel,461scheduler: SchedulerMixin,462safety_checker: StableDiffusionSafetyChecker,463feature_extractor: CLIPImageProcessor,464):465super().__init__(466vae=vae,467text_encoder=text_encoder,468tokenizer=tokenizer,469unet=unet,470scheduler=scheduler,471safety_checker=safety_checker,472feature_extractor=feature_extractor,473)474self.__init__additional__()475476def __init__additional__(self):477if not hasattr(self, "vae_scale_factor"):478setattr(self, "vae_scale_factor", 2 ** (len(self.vae.config.block_out_channels) - 1))479480@property481def _execution_device(self):482r"""483Returns the device on which the pipeline's models will be executed. After calling484`pipeline.enable_sequential_cpu_offload()` the execution device can only be inferred from Accelerate's module485hooks.486"""487if self.device != torch.device("meta") or not hasattr(self.unet, "_hf_hook"):488return self.device489for module in self.unet.modules():490if (491hasattr(module, "_hf_hook")492and hasattr(module._hf_hook, "execution_device")493and module._hf_hook.execution_device is not None494):495return torch.device(module._hf_hook.execution_device)496return self.device497498def _encode_prompt(499self,500prompt,501device,502num_images_per_prompt,503do_classifier_free_guidance,504negative_prompt,505max_embeddings_multiples,506):507r"""508Encodes the prompt into text encoder hidden states.509510Args:511prompt (`str` or `list(int)`):512prompt to be encoded513device: (`torch.device`):514torch device515num_images_per_prompt (`int`):516number of images that should be generated per prompt517do_classifier_free_guidance (`bool`):518whether to use classifier free guidance or not519negative_prompt (`str` or `List[str]`):520The prompt or prompts not to guide the image generation. Ignored when not using guidance (i.e., ignored521if `guidance_scale` is less than `1`).522max_embeddings_multiples (`int`, *optional*, defaults to `3`):523The max multiple length of prompt embeddings compared to the max output length of text encoder.524"""525batch_size = len(prompt) if isinstance(prompt, list) else 1526527if negative_prompt is None:528negative_prompt = [""] * batch_size529elif isinstance(negative_prompt, str):530negative_prompt = [negative_prompt] * batch_size531if batch_size != len(negative_prompt):532raise ValueError(533f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:"534f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches"535" the batch size of `prompt`."536)537538text_embeddings, uncond_embeddings = get_weighted_text_embeddings(539pipe=self,540prompt=prompt,541uncond_prompt=negative_prompt if do_classifier_free_guidance else None,542max_embeddings_multiples=max_embeddings_multiples,543)544bs_embed, seq_len, _ = text_embeddings.shape545text_embeddings = text_embeddings.repeat(1, num_images_per_prompt, 1)546text_embeddings = text_embeddings.view(bs_embed * num_images_per_prompt, seq_len, -1)547548if do_classifier_free_guidance:549bs_embed, seq_len, _ = uncond_embeddings.shape550uncond_embeddings = uncond_embeddings.repeat(1, num_images_per_prompt, 1)551uncond_embeddings = uncond_embeddings.view(bs_embed * num_images_per_prompt, seq_len, -1)552text_embeddings = torch.cat([uncond_embeddings, text_embeddings])553554return text_embeddings555556def check_inputs(self, prompt, height, width, strength, callback_steps):557if not isinstance(prompt, str) and not isinstance(prompt, list):558raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}")559560if strength < 0 or strength > 1:561raise ValueError(f"The value of strength should in [0.0, 1.0] but is {strength}")562563if height % 8 != 0 or width % 8 != 0:564raise ValueError(f"`height` and `width` have to be divisible by 8 but are {height} and {width}.")565566if (callback_steps is None) or (567callback_steps is not None and (not isinstance(callback_steps, int) or callback_steps <= 0)568):569raise ValueError(570f"`callback_steps` has to be a positive integer but is {callback_steps} of type"571f" {type(callback_steps)}."572)573574def get_timesteps(self, num_inference_steps, strength, device, is_text2img):575if is_text2img:576return self.scheduler.timesteps.to(device), num_inference_steps577else:578# get the original timestep using init_timestep579offset = self.scheduler.config.get("steps_offset", 0)580init_timestep = int(num_inference_steps * strength) + offset581init_timestep = min(init_timestep, num_inference_steps)582583t_start = max(num_inference_steps - init_timestep + offset, 0)584timesteps = self.scheduler.timesteps[t_start:].to(device)585return timesteps, num_inference_steps - t_start586587def run_safety_checker(self, image, device, dtype):588if self.safety_checker is not None:589safety_checker_input = self.feature_extractor(self.numpy_to_pil(image), return_tensors="pt").to(device)590image, has_nsfw_concept = self.safety_checker(591images=image, clip_input=safety_checker_input.pixel_values.to(dtype)592)593else:594has_nsfw_concept = None595return image, has_nsfw_concept596597def decode_latents(self, latents):598latents = 1 / 0.18215 * latents599image = self.vae.decode(latents).sample600image = (image / 2 + 0.5).clamp(0, 1)601# we always cast to float32 as this does not cause significant overhead and is compatible with bfloat16602image = image.cpu().permute(0, 2, 3, 1).float().numpy()603return image604605def prepare_extra_step_kwargs(self, generator, eta):606# prepare extra kwargs for the scheduler step, since not all schedulers have the same signature607# eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers.608# eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502609# and should be between [0, 1]610611accepts_eta = "eta" in set(inspect.signature(self.scheduler.step).parameters.keys())612extra_step_kwargs = {}613if accepts_eta:614extra_step_kwargs["eta"] = eta615616# check if the scheduler accepts generator617accepts_generator = "generator" in set(inspect.signature(self.scheduler.step).parameters.keys())618if accepts_generator:619extra_step_kwargs["generator"] = generator620return extra_step_kwargs621622def prepare_latents(self, image, timestep, batch_size, height, width, dtype, device, generator, latents=None):623if image is None:624shape = (625batch_size,626self.unet.in_channels,627height // self.vae_scale_factor,628width // self.vae_scale_factor,629)630631if latents is None:632if device.type == "mps":633# randn does not work reproducibly on mps634latents = torch.randn(shape, generator=generator, device="cpu", dtype=dtype).to(device)635else:636latents = torch.randn(shape, generator=generator, device=device, dtype=dtype)637else:638if latents.shape != shape:639raise ValueError(f"Unexpected latents shape, got {latents.shape}, expected {shape}")640latents = latents.to(device)641642# scale the initial noise by the standard deviation required by the scheduler643latents = latents * self.scheduler.init_noise_sigma644return latents, None, None645else:646init_latent_dist = self.vae.encode(image).latent_dist647init_latents = init_latent_dist.sample(generator=generator)648init_latents = 0.18215 * init_latents649init_latents = torch.cat([init_latents] * batch_size, dim=0)650init_latents_orig = init_latents651shape = init_latents.shape652653# add noise to latents using the timesteps654if device.type == "mps":655noise = torch.randn(shape, generator=generator, device="cpu", dtype=dtype).to(device)656else:657noise = torch.randn(shape, generator=generator, device=device, dtype=dtype)658latents = self.scheduler.add_noise(init_latents, noise, timestep)659return latents, init_latents_orig, noise660661@torch.no_grad()662def __call__(663self,664prompt: Union[str, List[str]],665negative_prompt: Optional[Union[str, List[str]]] = None,666image: Union[torch.FloatTensor, PIL.Image.Image] = None,667mask_image: Union[torch.FloatTensor, PIL.Image.Image] = None,668height: int = 512,669width: int = 512,670num_inference_steps: int = 50,671guidance_scale: float = 7.5,672strength: float = 0.8,673num_images_per_prompt: Optional[int] = 1,674eta: float = 0.0,675generator: Optional[torch.Generator] = None,676latents: Optional[torch.FloatTensor] = None,677max_embeddings_multiples: Optional[int] = 3,678output_type: Optional[str] = "pil",679return_dict: bool = True,680callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None,681is_cancelled_callback: Optional[Callable[[], bool]] = None,682callback_steps: int = 1,683):684r"""685Function invoked when calling the pipeline for generation.686687Args:688prompt (`str` or `List[str]`):689The prompt or prompts to guide the image generation.690negative_prompt (`str` or `List[str]`, *optional*):691The prompt or prompts not to guide the image generation. Ignored when not using guidance (i.e., ignored692if `guidance_scale` is less than `1`).693image (`torch.FloatTensor` or `PIL.Image.Image`):694`Image`, or tensor representing an image batch, that will be used as the starting point for the695process.696mask_image (`torch.FloatTensor` or `PIL.Image.Image`):697`Image`, or tensor representing an image batch, to mask `image`. White pixels in the mask will be698replaced by noise and therefore repainted, while black pixels will be preserved. If `mask_image` is a699PIL image, it will be converted to a single channel (luminance) before use. If it's a tensor, it should700contain one color channel (L) instead of 3, so the expected shape would be `(B, H, W, 1)`.701height (`int`, *optional*, defaults to 512):702The height in pixels of the generated image.703width (`int`, *optional*, defaults to 512):704The width in pixels of the generated image.705num_inference_steps (`int`, *optional*, defaults to 50):706The number of denoising steps. More denoising steps usually lead to a higher quality image at the707expense of slower inference.708guidance_scale (`float`, *optional*, defaults to 7.5):709Guidance scale as defined in [Classifier-Free Diffusion Guidance](https://arxiv.org/abs/2207.12598).710`guidance_scale` is defined as `w` of equation 2. of [Imagen711Paper](https://arxiv.org/pdf/2205.11487.pdf). Guidance scale is enabled by setting `guidance_scale >7121`. Higher guidance scale encourages to generate images that are closely linked to the text `prompt`,713usually at the expense of lower image quality.714strength (`float`, *optional*, defaults to 0.8):715Conceptually, indicates how much to transform the reference `image`. Must be between 0 and 1.716`image` will be used as a starting point, adding more noise to it the larger the `strength`. The717number of denoising steps depends on the amount of noise initially added. When `strength` is 1, added718noise will be maximum and the denoising process will run for the full number of iterations specified in719`num_inference_steps`. A value of 1, therefore, essentially ignores `image`.720num_images_per_prompt (`int`, *optional*, defaults to 1):721The number of images to generate per prompt.722eta (`float`, *optional*, defaults to 0.0):723Corresponds to parameter eta (η) in the DDIM paper: https://arxiv.org/abs/2010.02502. Only applies to724[`schedulers.DDIMScheduler`], will be ignored for others.725generator (`torch.Generator`, *optional*):726A [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make generation727deterministic.728latents (`torch.FloatTensor`, *optional*):729Pre-generated noisy latents, sampled from a Gaussian distribution, to be used as inputs for image730generation. Can be used to tweak the same generation with different prompts. If not provided, a latents731tensor will ge generated by sampling using the supplied random `generator`.732max_embeddings_multiples (`int`, *optional*, defaults to `3`):733The max multiple length of prompt embeddings compared to the max output length of text encoder.734output_type (`str`, *optional*, defaults to `"pil"`):735The output format of the generate image. Choose between736[PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`.737return_dict (`bool`, *optional*, defaults to `True`):738Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a739plain tuple.740callback (`Callable`, *optional*):741A function that will be called every `callback_steps` steps during inference. The function will be742called with the following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`.743is_cancelled_callback (`Callable`, *optional*):744A function that will be called every `callback_steps` steps during inference. If the function returns745`True`, the inference will be cancelled.746callback_steps (`int`, *optional*, defaults to 1):747The frequency at which the `callback` function will be called. If not specified, the callback will be748called at every step.749750Returns:751`None` if cancelled by `is_cancelled_callback`,752[`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`:753[`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] if `return_dict` is True, otherwise a `tuple.754When returning a tuple, the first element is a list with the generated images, and the second element is a755list of `bool`s denoting whether the corresponding generated image likely represents "not-safe-for-work"756(nsfw) content, according to the `safety_checker`.757"""758# 0. Default height and width to unet759height = height or self.unet.config.sample_size * self.vae_scale_factor760width = width or self.unet.config.sample_size * self.vae_scale_factor761762# 1. Check inputs. Raise error if not correct763self.check_inputs(prompt, height, width, strength, callback_steps)764765# 2. Define call parameters766batch_size = 1 if isinstance(prompt, str) else len(prompt)767device = self._execution_device768# here `guidance_scale` is defined analog to the guidance weight `w` of equation (2)769# of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1`770# corresponds to doing no classifier free guidance.771do_classifier_free_guidance = guidance_scale > 1.0772773# 3. Encode input prompt774text_embeddings = self._encode_prompt(775prompt,776device,777num_images_per_prompt,778do_classifier_free_guidance,779negative_prompt,780max_embeddings_multiples,781)782dtype = text_embeddings.dtype783784# 4. Preprocess image and mask785if isinstance(image, PIL.Image.Image):786image = preprocess_image(image)787if image is not None:788image = image.to(device=self.device, dtype=dtype)789if isinstance(mask_image, PIL.Image.Image):790mask_image = preprocess_mask(mask_image, self.vae_scale_factor)791if mask_image is not None:792mask = mask_image.to(device=self.device, dtype=dtype)793mask = torch.cat([mask] * batch_size * num_images_per_prompt)794else:795mask = None796797# 5. set timesteps798self.scheduler.set_timesteps(num_inference_steps, device=device)799timesteps, num_inference_steps = self.get_timesteps(num_inference_steps, strength, device, image is None)800latent_timestep = timesteps[:1].repeat(batch_size * num_images_per_prompt)801802# 6. Prepare latent variables803latents, init_latents_orig, noise = self.prepare_latents(804image,805latent_timestep,806batch_size * num_images_per_prompt,807height,808width,809dtype,810device,811generator,812latents,813)814815# 7. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline816extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta)817818# 8. Denoising loop819for i, t in enumerate(self.progress_bar(timesteps)):820# expand the latents if we are doing classifier free guidance821latent_model_input = torch.cat([latents] * 2) if do_classifier_free_guidance else latents822latent_model_input = self.scheduler.scale_model_input(latent_model_input, t)823824# predict the noise residual825noise_pred = self.unet(latent_model_input, t, encoder_hidden_states=text_embeddings).sample826827# perform guidance828if do_classifier_free_guidance:829noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)830noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)831832# compute the previous noisy sample x_t -> x_t-1833latents = self.scheduler.step(noise_pred, t, latents, **extra_step_kwargs).prev_sample834835if mask is not None:836# masking837init_latents_proper = self.scheduler.add_noise(init_latents_orig, noise, torch.tensor([t]))838latents = (init_latents_proper * mask) + (latents * (1 - mask))839840# call the callback, if provided841if i % callback_steps == 0:842if callback is not None:843callback(i, t, latents)844if is_cancelled_callback is not None and is_cancelled_callback():845return None846847# 9. Post-processing848image = self.decode_latents(latents)849850# 10. Run safety checker851image, has_nsfw_concept = self.run_safety_checker(image, device, text_embeddings.dtype)852853# 11. Convert to PIL854if output_type == "pil":855image = self.numpy_to_pil(image)856857if not return_dict:858return image, has_nsfw_concept859860return StableDiffusionPipelineOutput(images=image, nsfw_content_detected=has_nsfw_concept)861862def text2img(863self,864prompt: Union[str, List[str]],865negative_prompt: Optional[Union[str, List[str]]] = None,866height: int = 512,867width: int = 512,868num_inference_steps: int = 50,869guidance_scale: float = 7.5,870num_images_per_prompt: Optional[int] = 1,871eta: float = 0.0,872generator: Optional[torch.Generator] = None,873latents: Optional[torch.FloatTensor] = None,874max_embeddings_multiples: Optional[int] = 3,875output_type: Optional[str] = "pil",876return_dict: bool = True,877callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None,878is_cancelled_callback: Optional[Callable[[], bool]] = None,879callback_steps: int = 1,880):881r"""882Function for text-to-image generation.883Args:884prompt (`str` or `List[str]`):885The prompt or prompts to guide the image generation.886negative_prompt (`str` or `List[str]`, *optional*):887The prompt or prompts not to guide the image generation. Ignored when not using guidance (i.e., ignored888if `guidance_scale` is less than `1`).889height (`int`, *optional*, defaults to 512):890The height in pixels of the generated image.891width (`int`, *optional*, defaults to 512):892The width in pixels of the generated image.893num_inference_steps (`int`, *optional*, defaults to 50):894The number of denoising steps. More denoising steps usually lead to a higher quality image at the895expense of slower inference.896guidance_scale (`float`, *optional*, defaults to 7.5):897Guidance scale as defined in [Classifier-Free Diffusion Guidance](https://arxiv.org/abs/2207.12598).898`guidance_scale` is defined as `w` of equation 2. of [Imagen899Paper](https://arxiv.org/pdf/2205.11487.pdf). Guidance scale is enabled by setting `guidance_scale >9001`. Higher guidance scale encourages to generate images that are closely linked to the text `prompt`,901usually at the expense of lower image quality.902num_images_per_prompt (`int`, *optional*, defaults to 1):903The number of images to generate per prompt.904eta (`float`, *optional*, defaults to 0.0):905Corresponds to parameter eta (η) in the DDIM paper: https://arxiv.org/abs/2010.02502. Only applies to906[`schedulers.DDIMScheduler`], will be ignored for others.907generator (`torch.Generator`, *optional*):908A [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make generation909deterministic.910latents (`torch.FloatTensor`, *optional*):911Pre-generated noisy latents, sampled from a Gaussian distribution, to be used as inputs for image912generation. Can be used to tweak the same generation with different prompts. If not provided, a latents913tensor will ge generated by sampling using the supplied random `generator`.914max_embeddings_multiples (`int`, *optional*, defaults to `3`):915The max multiple length of prompt embeddings compared to the max output length of text encoder.916output_type (`str`, *optional*, defaults to `"pil"`):917The output format of the generate image. Choose between918[PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`.919return_dict (`bool`, *optional*, defaults to `True`):920Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a921plain tuple.922callback (`Callable`, *optional*):923A function that will be called every `callback_steps` steps during inference. The function will be924called with the following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`.925is_cancelled_callback (`Callable`, *optional*):926A function that will be called every `callback_steps` steps during inference. If the function returns927`True`, the inference will be cancelled.928callback_steps (`int`, *optional*, defaults to 1):929The frequency at which the `callback` function will be called. If not specified, the callback will be930called at every step.931Returns:932[`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`:933[`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] if `return_dict` is True, otherwise a `tuple.934When returning a tuple, the first element is a list with the generated images, and the second element is a935list of `bool`s denoting whether the corresponding generated image likely represents "not-safe-for-work"936(nsfw) content, according to the `safety_checker`.937"""938return self.__call__(939prompt=prompt,940negative_prompt=negative_prompt,941height=height,942width=width,943num_inference_steps=num_inference_steps,944guidance_scale=guidance_scale,945num_images_per_prompt=num_images_per_prompt,946eta=eta,947generator=generator,948latents=latents,949max_embeddings_multiples=max_embeddings_multiples,950output_type=output_type,951return_dict=return_dict,952callback=callback,953is_cancelled_callback=is_cancelled_callback,954callback_steps=callback_steps,955)956957def img2img(958self,959image: Union[torch.FloatTensor, PIL.Image.Image],960prompt: Union[str, List[str]],961negative_prompt: Optional[Union[str, List[str]]] = None,962strength: float = 0.8,963num_inference_steps: Optional[int] = 50,964guidance_scale: Optional[float] = 7.5,965num_images_per_prompt: Optional[int] = 1,966eta: Optional[float] = 0.0,967generator: Optional[torch.Generator] = None,968max_embeddings_multiples: Optional[int] = 3,969output_type: Optional[str] = "pil",970return_dict: bool = True,971callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None,972is_cancelled_callback: Optional[Callable[[], bool]] = None,973callback_steps: int = 1,974):975r"""976Function for image-to-image generation.977Args:978image (`torch.FloatTensor` or `PIL.Image.Image`):979`Image`, or tensor representing an image batch, that will be used as the starting point for the980process.981prompt (`str` or `List[str]`):982The prompt or prompts to guide the image generation.983negative_prompt (`str` or `List[str]`, *optional*):984The prompt or prompts not to guide the image generation. Ignored when not using guidance (i.e., ignored985if `guidance_scale` is less than `1`).986strength (`float`, *optional*, defaults to 0.8):987Conceptually, indicates how much to transform the reference `image`. Must be between 0 and 1.988`image` will be used as a starting point, adding more noise to it the larger the `strength`. The989number of denoising steps depends on the amount of noise initially added. When `strength` is 1, added990noise will be maximum and the denoising process will run for the full number of iterations specified in991`num_inference_steps`. A value of 1, therefore, essentially ignores `image`.992num_inference_steps (`int`, *optional*, defaults to 50):993The number of denoising steps. More denoising steps usually lead to a higher quality image at the994expense of slower inference. This parameter will be modulated by `strength`.995guidance_scale (`float`, *optional*, defaults to 7.5):996Guidance scale as defined in [Classifier-Free Diffusion Guidance](https://arxiv.org/abs/2207.12598).997`guidance_scale` is defined as `w` of equation 2. of [Imagen998Paper](https://arxiv.org/pdf/2205.11487.pdf). Guidance scale is enabled by setting `guidance_scale >9991`. Higher guidance scale encourages to generate images that are closely linked to the text `prompt`,1000usually at the expense of lower image quality.1001num_images_per_prompt (`int`, *optional*, defaults to 1):1002The number of images to generate per prompt.1003eta (`float`, *optional*, defaults to 0.0):1004Corresponds to parameter eta (η) in the DDIM paper: https://arxiv.org/abs/2010.02502. Only applies to1005[`schedulers.DDIMScheduler`], will be ignored for others.1006generator (`torch.Generator`, *optional*):1007A [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make generation1008deterministic.1009max_embeddings_multiples (`int`, *optional*, defaults to `3`):1010The max multiple length of prompt embeddings compared to the max output length of text encoder.1011output_type (`str`, *optional*, defaults to `"pil"`):1012The output format of the generate image. Choose between1013[PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`.1014return_dict (`bool`, *optional*, defaults to `True`):1015Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a1016plain tuple.1017callback (`Callable`, *optional*):1018A function that will be called every `callback_steps` steps during inference. The function will be1019called with the following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`.1020is_cancelled_callback (`Callable`, *optional*):1021A function that will be called every `callback_steps` steps during inference. If the function returns1022`True`, the inference will be cancelled.1023callback_steps (`int`, *optional*, defaults to 1):1024The frequency at which the `callback` function will be called. If not specified, the callback will be1025called at every step.1026Returns:1027[`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`:1028[`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] if `return_dict` is True, otherwise a `tuple.1029When returning a tuple, the first element is a list with the generated images, and the second element is a1030list of `bool`s denoting whether the corresponding generated image likely represents "not-safe-for-work"1031(nsfw) content, according to the `safety_checker`.1032"""1033return self.__call__(1034prompt=prompt,1035negative_prompt=negative_prompt,1036image=image,1037num_inference_steps=num_inference_steps,1038guidance_scale=guidance_scale,1039strength=strength,1040num_images_per_prompt=num_images_per_prompt,1041eta=eta,1042generator=generator,1043max_embeddings_multiples=max_embeddings_multiples,1044output_type=output_type,1045return_dict=return_dict,1046callback=callback,1047is_cancelled_callback=is_cancelled_callback,1048callback_steps=callback_steps,1049)10501051def inpaint(1052self,1053image: Union[torch.FloatTensor, PIL.Image.Image],1054mask_image: Union[torch.FloatTensor, PIL.Image.Image],1055prompt: Union[str, List[str]],1056negative_prompt: Optional[Union[str, List[str]]] = None,1057strength: float = 0.8,1058num_inference_steps: Optional[int] = 50,1059guidance_scale: Optional[float] = 7.5,1060num_images_per_prompt: Optional[int] = 1,1061eta: Optional[float] = 0.0,1062generator: Optional[torch.Generator] = None,1063max_embeddings_multiples: Optional[int] = 3,1064output_type: Optional[str] = "pil",1065return_dict: bool = True,1066callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None,1067is_cancelled_callback: Optional[Callable[[], bool]] = None,1068callback_steps: int = 1,1069):1070r"""1071Function for inpaint.1072Args:1073image (`torch.FloatTensor` or `PIL.Image.Image`):1074`Image`, or tensor representing an image batch, that will be used as the starting point for the1075process. This is the image whose masked region will be inpainted.1076mask_image (`torch.FloatTensor` or `PIL.Image.Image`):1077`Image`, or tensor representing an image batch, to mask `image`. White pixels in the mask will be1078replaced by noise and therefore repainted, while black pixels will be preserved. If `mask_image` is a1079PIL image, it will be converted to a single channel (luminance) before use. If it's a tensor, it should1080contain one color channel (L) instead of 3, so the expected shape would be `(B, H, W, 1)`.1081prompt (`str` or `List[str]`):1082The prompt or prompts to guide the image generation.1083negative_prompt (`str` or `List[str]`, *optional*):1084The prompt or prompts not to guide the image generation. Ignored when not using guidance (i.e., ignored1085if `guidance_scale` is less than `1`).1086strength (`float`, *optional*, defaults to 0.8):1087Conceptually, indicates how much to inpaint the masked area. Must be between 0 and 1. When `strength`1088is 1, the denoising process will be run on the masked area for the full number of iterations specified1089in `num_inference_steps`. `image` will be used as a reference for the masked area, adding more1090noise to that region the larger the `strength`. If `strength` is 0, no inpainting will occur.1091num_inference_steps (`int`, *optional*, defaults to 50):1092The reference number of denoising steps. More denoising steps usually lead to a higher quality image at1093the expense of slower inference. This parameter will be modulated by `strength`, as explained above.1094guidance_scale (`float`, *optional*, defaults to 7.5):1095Guidance scale as defined in [Classifier-Free Diffusion Guidance](https://arxiv.org/abs/2207.12598).1096`guidance_scale` is defined as `w` of equation 2. of [Imagen1097Paper](https://arxiv.org/pdf/2205.11487.pdf). Guidance scale is enabled by setting `guidance_scale >10981`. Higher guidance scale encourages to generate images that are closely linked to the text `prompt`,1099usually at the expense of lower image quality.1100num_images_per_prompt (`int`, *optional*, defaults to 1):1101The number of images to generate per prompt.1102eta (`float`, *optional*, defaults to 0.0):1103Corresponds to parameter eta (η) in the DDIM paper: https://arxiv.org/abs/2010.02502. Only applies to1104[`schedulers.DDIMScheduler`], will be ignored for others.1105generator (`torch.Generator`, *optional*):1106A [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make generation1107deterministic.1108max_embeddings_multiples (`int`, *optional*, defaults to `3`):1109The max multiple length of prompt embeddings compared to the max output length of text encoder.1110output_type (`str`, *optional*, defaults to `"pil"`):1111The output format of the generate image. Choose between1112[PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`.1113return_dict (`bool`, *optional*, defaults to `True`):1114Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a1115plain tuple.1116callback (`Callable`, *optional*):1117A function that will be called every `callback_steps` steps during inference. The function will be1118called with the following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`.1119is_cancelled_callback (`Callable`, *optional*):1120A function that will be called every `callback_steps` steps during inference. If the function returns1121`True`, the inference will be cancelled.1122callback_steps (`int`, *optional*, defaults to 1):1123The frequency at which the `callback` function will be called. If not specified, the callback will be1124called at every step.1125Returns:1126[`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`:1127[`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] if `return_dict` is True, otherwise a `tuple.1128When returning a tuple, the first element is a list with the generated images, and the second element is a1129list of `bool`s denoting whether the corresponding generated image likely represents "not-safe-for-work"1130(nsfw) content, according to the `safety_checker`.1131"""1132return self.__call__(1133prompt=prompt,1134negative_prompt=negative_prompt,1135image=image,1136mask_image=mask_image,1137num_inference_steps=num_inference_steps,1138guidance_scale=guidance_scale,1139strength=strength,1140num_images_per_prompt=num_images_per_prompt,1141eta=eta,1142generator=generator,1143max_embeddings_multiples=max_embeddings_multiples,1144output_type=output_type,1145return_dict=return_dict,1146callback=callback,1147is_cancelled_callback=is_cancelled_callback,1148callback_steps=callback_steps,1149)115011511152