CoolFace
Datasetpublic

diffusers/community-pipelines-mirror

Community Pipeline Examples For more information about community pipelines, please have a look at this issue. Community pipeline examples consist pipelines that have been added by the community. Please have a look at the following tables to get an overview of all community examples. Click on the Code Example to get a copy-and-paste ready code example that you can try out. If a community pipeline doesn't work as expected, please open an issue and ping the author on it. Please… See the full description on the dataset page: https://huggingface.co/datasets/diffusers/community-pipelines-mirror.

sourceHugging Faceupdated 29d agoView on Hugging Face
9likes22kdownloads
unclip_text_interpolation.py529 linesDownload Raw Back to root
1import inspect2from typing import List, Optional, Tuple, Union3 4import torch5from torch.nn import functional as F6from transformers import CLIPTextModelWithProjection, CLIPTokenizer7from transformers.models.clip.modeling_clip import CLIPTextModelOutput8 9from diffusers import (10    DiffusionPipeline,11    ImagePipelineOutput,12    PriorTransformer,13    UnCLIPScheduler,14    UNet2DConditionModel,15    UNet2DModel,16)17from diffusers.pipelines.unclip import UnCLIPTextProjModel18from diffusers.utils import logging19from diffusers.utils.torch_utils import randn_tensor20 21 22logger = logging.get_logger(__name__)  # pylint: disable=invalid-name23 24 25def slerp(val, low, high):26    """27    Find the interpolation point between the 'low' and 'high' values for the given 'val'. See https://en.wikipedia.org/wiki/Slerp for more details on the topic.28    """29    low_norm = low / torch.norm(low)30    high_norm = high / torch.norm(high)31    omega = torch.acos((low_norm * high_norm))32    so = torch.sin(omega)33    res = (torch.sin((1.0 - val) * omega) / so) * low + (torch.sin(val * omega) / so) * high34    return res35 36 37class UnCLIPTextInterpolationPipeline(DiffusionPipeline):38    """39    Pipeline for prompt-to-prompt interpolation on CLIP text embeddings and using the UnCLIP / Dall-E to decode them to images.40 41    This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods the42    library implements for all the pipelines (such as downloading or saving, running on a particular device, etc.)43 44    Args:45        text_encoder ([`CLIPTextModelWithProjection`]):46            Frozen text-encoder.47        tokenizer (`CLIPTokenizer`):48            Tokenizer of class49            [CLIPTokenizer](https://huggingface.co/docs/transformers/v4.21.0/en/model_doc/clip#transformers.CLIPTokenizer).50        prior ([`PriorTransformer`]):51            The canonical unCLIP prior to approximate the image embedding from the text embedding.52        text_proj ([`UnCLIPTextProjModel`]):53            Utility class to prepare and combine the embeddings before they are passed to the decoder.54        decoder ([`UNet2DConditionModel`]):55            The decoder to invert the image embedding into an image.56        super_res_first ([`UNet2DModel`]):57            Super resolution unet. Used in all but the last step of the super resolution diffusion process.58        super_res_last ([`UNet2DModel`]):59            Super resolution unet. Used in the last step of the super resolution diffusion process.60        prior_scheduler ([`UnCLIPScheduler`]):61            Scheduler used in the prior denoising process. Just a modified DDPMScheduler.62        decoder_scheduler ([`UnCLIPScheduler`]):63            Scheduler used in the decoder denoising process. Just a modified DDPMScheduler.64        super_res_scheduler ([`UnCLIPScheduler`]):65            Scheduler used in the super resolution denoising process. Just a modified DDPMScheduler.66 67    """68 69    prior: PriorTransformer70    decoder: UNet2DConditionModel71    text_proj: UnCLIPTextProjModel72    text_encoder: CLIPTextModelWithProjection73    tokenizer: CLIPTokenizer74    super_res_first: UNet2DModel75    super_res_last: UNet2DModel76 77    prior_scheduler: UnCLIPScheduler78    decoder_scheduler: UnCLIPScheduler79    super_res_scheduler: UnCLIPScheduler80 81    # Copied from diffusers.pipelines.unclip.pipeline_unclip.UnCLIPPipeline.__init__82    def __init__(83        self,84        prior: PriorTransformer,85        decoder: UNet2DConditionModel,86        text_encoder: CLIPTextModelWithProjection,87        tokenizer: CLIPTokenizer,88        text_proj: UnCLIPTextProjModel,89        super_res_first: UNet2DModel,90        super_res_last: UNet2DModel,91        prior_scheduler: UnCLIPScheduler,92        decoder_scheduler: UnCLIPScheduler,93        super_res_scheduler: UnCLIPScheduler,94    ):95        super().__init__()96 97        self.register_modules(98            prior=prior,99            decoder=decoder,100            text_encoder=text_encoder,101            tokenizer=tokenizer,102            text_proj=text_proj,103            super_res_first=super_res_first,104            super_res_last=super_res_last,105            prior_scheduler=prior_scheduler,106            decoder_scheduler=decoder_scheduler,107            super_res_scheduler=super_res_scheduler,108        )109 110    # Copied from diffusers.pipelines.unclip.pipeline_unclip.UnCLIPPipeline.prepare_latents111    def prepare_latents(self, shape, dtype, device, generator, latents, scheduler):112        if latents is None:113            latents = randn_tensor(shape, generator=generator, device=device, dtype=dtype)114        else:115            if latents.shape != shape:116                raise ValueError(f"Unexpected latents shape, got {latents.shape}, expected {shape}")117            latents = latents.to(device)118 119        latents = latents * scheduler.init_noise_sigma120        return latents121 122    # Copied from diffusers.pipelines.unclip.pipeline_unclip.UnCLIPPipeline._encode_prompt123    def _encode_prompt(124        self,125        prompt,126        device,127        num_images_per_prompt,128        do_classifier_free_guidance,129        text_model_output: Optional[Union[CLIPTextModelOutput, Tuple]] = None,130        text_attention_mask: Optional[torch.Tensor] = None,131    ):132        if text_model_output is None:133            batch_size = len(prompt) if isinstance(prompt, list) else 1134            # get prompt text embeddings135            text_inputs = self.tokenizer(136                prompt,137                padding="max_length",138                max_length=self.tokenizer.model_max_length,139                truncation=True,140                return_tensors="pt",141            )142            text_input_ids = text_inputs.input_ids143            text_mask = text_inputs.attention_mask.bool().to(device)144 145            untruncated_ids = self.tokenizer(prompt, padding="longest", return_tensors="pt").input_ids146 147            if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal(148                text_input_ids, untruncated_ids149            ):150                removed_text = self.tokenizer.batch_decode(151                    untruncated_ids[:, self.tokenizer.model_max_length - 1 : -1]152                )153                logger.warning(154                    "The following part of your input was truncated because CLIP can only handle sequences up to"155                    f" {self.tokenizer.model_max_length} tokens: {removed_text}"156                )157                text_input_ids = text_input_ids[:, : self.tokenizer.model_max_length]158 159            text_encoder_output = self.text_encoder(text_input_ids.to(device))160 161            prompt_embeds = text_encoder_output.text_embeds162            text_encoder_hidden_states = text_encoder_output.last_hidden_state163 164        else:165            batch_size = text_model_output[0].shape[0]166            prompt_embeds, text_encoder_hidden_states = text_model_output[0], text_model_output[1]167            text_mask = text_attention_mask168 169        prompt_embeds = prompt_embeds.repeat_interleave(num_images_per_prompt, dim=0)170        text_encoder_hidden_states = text_encoder_hidden_states.repeat_interleave(num_images_per_prompt, dim=0)171        text_mask = text_mask.repeat_interleave(num_images_per_prompt, dim=0)172 173        if do_classifier_free_guidance:174            uncond_tokens = [""] * batch_size175 176            uncond_input = self.tokenizer(177                uncond_tokens,178                padding="max_length",179                max_length=self.tokenizer.model_max_length,180                truncation=True,181                return_tensors="pt",182            )183            uncond_text_mask = uncond_input.attention_mask.bool().to(device)184            negative_prompt_embeds_text_encoder_output = self.text_encoder(uncond_input.input_ids.to(device))185 186            negative_prompt_embeds = negative_prompt_embeds_text_encoder_output.text_embeds187            uncond_text_encoder_hidden_states = negative_prompt_embeds_text_encoder_output.last_hidden_state188 189            # duplicate unconditional embeddings for each generation per prompt, using mps friendly method190 191            seq_len = negative_prompt_embeds.shape[1]192            negative_prompt_embeds = negative_prompt_embeds.repeat(1, num_images_per_prompt)193            negative_prompt_embeds = negative_prompt_embeds.view(batch_size * num_images_per_prompt, seq_len)194 195            seq_len = uncond_text_encoder_hidden_states.shape[1]196            uncond_text_encoder_hidden_states = uncond_text_encoder_hidden_states.repeat(1, num_images_per_prompt, 1)197            uncond_text_encoder_hidden_states = uncond_text_encoder_hidden_states.view(198                batch_size * num_images_per_prompt, seq_len, -1199            )200            uncond_text_mask = uncond_text_mask.repeat_interleave(num_images_per_prompt, dim=0)201 202            # done duplicates203 204            # For classifier free guidance, we need to do two forward passes.205            # Here we concatenate the unconditional and text embeddings into a single batch206            # to avoid doing two forward passes207            prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds])208            text_encoder_hidden_states = torch.cat([uncond_text_encoder_hidden_states, text_encoder_hidden_states])209 210            text_mask = torch.cat([uncond_text_mask, text_mask])211 212        return prompt_embeds, text_encoder_hidden_states, text_mask213 214    @torch.no_grad()215    def __call__(216        self,217        start_prompt: str,218        end_prompt: str,219        steps: int = 5,220        prior_num_inference_steps: int = 25,221        decoder_num_inference_steps: int = 25,222        super_res_num_inference_steps: int = 7,223        generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,224        prior_guidance_scale: float = 4.0,225        decoder_guidance_scale: float = 8.0,226        enable_sequential_cpu_offload=True,227        gpu_id=0,228        output_type: Optional[str] = "pil",229        return_dict: bool = True,230    ):231        """232        Function invoked when calling the pipeline for generation.233 234        Args:235            start_prompt (`str`):236                The prompt to start the image generation interpolation from.237            end_prompt (`str`):238                The prompt to end the image generation interpolation at.239            steps (`int`, *optional*, defaults to 5):240                The number of steps over which to interpolate from start_prompt to end_prompt. The pipeline returns241                the same number of images as this value.242            prior_num_inference_steps (`int`, *optional*, defaults to 25):243                The number of denoising steps for the prior. More denoising steps usually lead to a higher quality244                image at the expense of slower inference.245            decoder_num_inference_steps (`int`, *optional*, defaults to 25):246                The number of denoising steps for the decoder. More denoising steps usually lead to a higher quality247                image at the expense of slower inference.248            super_res_num_inference_steps (`int`, *optional*, defaults to 7):249                The number of denoising steps for super resolution. More denoising steps usually lead to a higher250                quality image at the expense of slower inference.251            generator (`torch.Generator` or `List[torch.Generator]`, *optional*):252                One or a list of [torch generator(s)](https://pytorch.org/docs/stable/generated/torch.Generator.html)253                to make generation deterministic.254            prior_guidance_scale (`float`, *optional*, defaults to 4.0):255                Guidance scale as defined in [Classifier-Free Diffusion Guidance](https://arxiv.org/abs/2207.12598).256                `guidance_scale` is defined as `w` of equation 2. of [Imagen257                Paper](https://arxiv.org/pdf/2205.11487.pdf). Guidance scale is enabled by setting `guidance_scale >258                1`. Higher guidance scale encourages to generate images that are closely linked to the text `prompt`,259                usually at the expense of lower image quality.260            decoder_guidance_scale (`float`, *optional*, defaults to 4.0):261                Guidance scale as defined in [Classifier-Free Diffusion Guidance](https://arxiv.org/abs/2207.12598).262                `guidance_scale` is defined as `w` of equation 2. of [Imagen263                Paper](https://arxiv.org/pdf/2205.11487.pdf). Guidance scale is enabled by setting `guidance_scale >264                1`. Higher guidance scale encourages to generate images that are closely linked to the text `prompt`,265                usually at the expense of lower image quality.266            output_type (`str`, *optional*, defaults to `"pil"`):267                The output format of the generated image. Choose between268                [PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`.269            enable_sequential_cpu_offload (`bool`, *optional*, defaults to `True`):270                If True, offloads all models to CPU using accelerate, significantly reducing memory usage. When called, the pipeline's271                models have their state dicts saved to CPU and then are moved to a `torch.device('meta') and loaded to GPU only272                when their specific submodule has its `forward` method called.273            gpu_id (`int`, *optional*, defaults to `0`):274                The gpu_id to be passed to enable_sequential_cpu_offload. Only works when enable_sequential_cpu_offload is set to True.275            return_dict (`bool`, *optional*, defaults to `True`):276                Whether or not to return a [`~pipelines.ImagePipelineOutput`] instead of a plain tuple.277        """278 279        if not isinstance(start_prompt, str) or not isinstance(end_prompt, str):280            raise ValueError(281                f"`start_prompt` and `end_prompt` should be of type `str` but got {type(start_prompt)} and"282                f" {type(end_prompt)} instead"283            )284 285        if enable_sequential_cpu_offload:286            self.enable_sequential_cpu_offload(gpu_id=gpu_id)287 288        device = self._execution_device289 290        # Turn the prompts into embeddings.291        inputs = self.tokenizer(292            [start_prompt, end_prompt],293            padding="max_length",294            truncation=True,295            max_length=self.tokenizer.model_max_length,296            return_tensors="pt",297        )298        inputs.to(device)299        text_model_output = self.text_encoder(**inputs)300 301        text_attention_mask = torch.max(inputs.attention_mask[0], inputs.attention_mask[1])302        text_attention_mask = torch.cat([text_attention_mask.unsqueeze(0)] * steps).to(device)303 304        # Interpolate from the start to end prompt using slerp and add the generated images to an image output pipeline305        batch_text_embeds = []306        batch_last_hidden_state = []307 308        for interp_val in torch.linspace(0, 1, steps):309            text_embeds = slerp(interp_val, text_model_output.text_embeds[0], text_model_output.text_embeds[1])310            last_hidden_state = slerp(311                interp_val, text_model_output.last_hidden_state[0], text_model_output.last_hidden_state[1]312            )313            batch_text_embeds.append(text_embeds.unsqueeze(0))314            batch_last_hidden_state.append(last_hidden_state.unsqueeze(0))315 316        batch_text_embeds = torch.cat(batch_text_embeds)317        batch_last_hidden_state = torch.cat(batch_last_hidden_state)318 319        text_model_output = CLIPTextModelOutput(320            text_embeds=batch_text_embeds, last_hidden_state=batch_last_hidden_state321        )322 323        batch_size = text_model_output[0].shape[0]324 325        do_classifier_free_guidance = prior_guidance_scale > 1.0 or decoder_guidance_scale > 1.0326 327        prompt_embeds, text_encoder_hidden_states, text_mask = self._encode_prompt(328            prompt=None,329            device=device,330            num_images_per_prompt=1,331            do_classifier_free_guidance=do_classifier_free_guidance,332            text_model_output=text_model_output,333            text_attention_mask=text_attention_mask,334        )335 336        # prior337 338        self.prior_scheduler.set_timesteps(prior_num_inference_steps, device=device)339        prior_timesteps_tensor = self.prior_scheduler.timesteps340 341        embedding_dim = self.prior.config.embedding_dim342 343        prior_latents = self.prepare_latents(344            (batch_size, embedding_dim),345            prompt_embeds.dtype,346            device,347            generator,348            None,349            self.prior_scheduler,350        )351 352        for i, t in enumerate(self.progress_bar(prior_timesteps_tensor)):353            # expand the latents if we are doing classifier free guidance354            latent_model_input = torch.cat([prior_latents] * 2) if do_classifier_free_guidance else prior_latents355 356            predicted_image_embedding = self.prior(357                latent_model_input,358                timestep=t,359                proj_embedding=prompt_embeds,360                encoder_hidden_states=text_encoder_hidden_states,361                attention_mask=text_mask,362            ).predicted_image_embedding363 364            if do_classifier_free_guidance:365                predicted_image_embedding_uncond, predicted_image_embedding_text = predicted_image_embedding.chunk(2)366                predicted_image_embedding = predicted_image_embedding_uncond + prior_guidance_scale * (367                    predicted_image_embedding_text - predicted_image_embedding_uncond368                )369 370            if i + 1 == prior_timesteps_tensor.shape[0]:371                prev_timestep = None372            else:373                prev_timestep = prior_timesteps_tensor[i + 1]374 375            prior_latents = self.prior_scheduler.step(376                predicted_image_embedding,377                timestep=t,378                sample=prior_latents,379                generator=generator,380                prev_timestep=prev_timestep,381            ).prev_sample382 383        prior_latents = self.prior.post_process_latents(prior_latents)384 385        image_embeddings = prior_latents386 387        # done prior388 389        # decoder390 391        text_encoder_hidden_states, additive_clip_time_embeddings = self.text_proj(392            image_embeddings=image_embeddings,393            prompt_embeds=prompt_embeds,394            text_encoder_hidden_states=text_encoder_hidden_states,395            do_classifier_free_guidance=do_classifier_free_guidance,396        )397 398        if device.type == "mps":399            # HACK: MPS: There is a panic when padding bool tensors,400            # so cast to int tensor for the pad and back to bool afterwards401            text_mask = text_mask.type(torch.int)402            decoder_text_mask = F.pad(text_mask, (self.text_proj.clip_extra_context_tokens, 0), value=1)403            decoder_text_mask = decoder_text_mask.type(torch.bool)404        else:405            decoder_text_mask = F.pad(text_mask, (self.text_proj.clip_extra_context_tokens, 0), value=True)406 407        self.decoder_scheduler.set_timesteps(decoder_num_inference_steps, device=device)408        decoder_timesteps_tensor = self.decoder_scheduler.timesteps409 410        num_channels_latents = self.decoder.config.in_channels411        height = self.decoder.config.sample_size412        width = self.decoder.config.sample_size413 414        decoder_latents = self.prepare_latents(415            (batch_size, num_channels_latents, height, width),416            text_encoder_hidden_states.dtype,417            device,418            generator,419            None,420            self.decoder_scheduler,421        )422 423        for i, t in enumerate(self.progress_bar(decoder_timesteps_tensor)):424            # expand the latents if we are doing classifier free guidance425            latent_model_input = torch.cat([decoder_latents] * 2) if do_classifier_free_guidance else decoder_latents426 427            noise_pred = self.decoder(428                sample=latent_model_input,429                timestep=t,430                encoder_hidden_states=text_encoder_hidden_states,431                class_labels=additive_clip_time_embeddings,432                attention_mask=decoder_text_mask,433            ).sample434 435            if do_classifier_free_guidance:436                noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)437                noise_pred_uncond, _ = noise_pred_uncond.split(latent_model_input.shape[1], dim=1)438                noise_pred_text, predicted_variance = noise_pred_text.split(latent_model_input.shape[1], dim=1)439                noise_pred = noise_pred_uncond + decoder_guidance_scale * (noise_pred_text - noise_pred_uncond)440                noise_pred = torch.cat([noise_pred, predicted_variance], dim=1)441 442            if i + 1 == decoder_timesteps_tensor.shape[0]:443                prev_timestep = None444            else:445                prev_timestep = decoder_timesteps_tensor[i + 1]446 447            # compute the previous noisy sample x_t -> x_t-1448            decoder_latents = self.decoder_scheduler.step(449                noise_pred, t, decoder_latents, prev_timestep=prev_timestep, generator=generator450            ).prev_sample451 452        decoder_latents = decoder_latents.clamp(-1, 1)453 454        image_small = decoder_latents455 456        # done decoder457 458        # super res459 460        self.super_res_scheduler.set_timesteps(super_res_num_inference_steps, device=device)461        super_res_timesteps_tensor = self.super_res_scheduler.timesteps462 463        channels = self.super_res_first.config.in_channels // 2464        height = self.super_res_first.config.sample_size465        width = self.super_res_first.config.sample_size466 467        super_res_latents = self.prepare_latents(468            (batch_size, channels, height, width),469            image_small.dtype,470            device,471            generator,472            None,473            self.super_res_scheduler,474        )475 476        if device.type == "mps":477            # MPS does not support many interpolations478            image_upscaled = F.interpolate(image_small, size=[height, width])479        else:480            interpolate_antialias = {}481            if "antialias" in inspect.signature(F.interpolate).parameters:482                interpolate_antialias["antialias"] = True483 484            image_upscaled = F.interpolate(485                image_small, size=[height, width], mode="bicubic", align_corners=False, **interpolate_antialias486            )487 488        for i, t in enumerate(self.progress_bar(super_res_timesteps_tensor)):489            # no classifier free guidance490 491            if i == super_res_timesteps_tensor.shape[0] - 1:492                unet = self.super_res_last493            else:494                unet = self.super_res_first495 496            latent_model_input = torch.cat([super_res_latents, image_upscaled], dim=1)497 498            noise_pred = unet(499                sample=latent_model_input,500                timestep=t,501            ).sample502 503            if i + 1 == super_res_timesteps_tensor.shape[0]:504                prev_timestep = None505            else:506                prev_timestep = super_res_timesteps_tensor[i + 1]507 508            # compute the previous noisy sample x_t -> x_t-1509            super_res_latents = self.super_res_scheduler.step(510                noise_pred, t, super_res_latents, prev_timestep=prev_timestep, generator=generator511            ).prev_sample512 513        image = super_res_latents514        # done super res515 516        # post processing517 518        image = image * 0.5 + 0.5519        image = image.clamp(0, 1)520        image = image.cpu().permute(0, 2, 3, 1).float().numpy()521 522        if output_type == "pil":523            image = self.numpy_to_pil(image)524 525        if not return_dict:526            return (image,)527 528        return ImagePipelineOutput(images=image)529