CoolFace
Apppublic

LTT/PRM

sourceHugging Faceupdated 1y agoView on Hugging Face
24likes
pipeline.py407 linesDownload Raw Back to zero123plus
1from typing import Any, Dict, Optional2from diffusers.models import AutoencoderKL, UNet2DConditionModel3from diffusers.schedulers import KarrasDiffusionSchedulers4 5import numpy6import torch7import torch.nn as nn8import torch.utils.checkpoint9import torch.distributed10import transformers11from collections import OrderedDict12from PIL import Image13from torchvision import transforms14from transformers import CLIPImageProcessor, CLIPTextModel, CLIPTokenizer15 16import diffusers17from diffusers import (18    AutoencoderKL,19    DDPMScheduler,20    DiffusionPipeline,21    EulerAncestralDiscreteScheduler,22    UNet2DConditionModel,23    ImagePipelineOutput24)25from diffusers.image_processor import VaeImageProcessor26from diffusers.models.attention_processor import Attention, AttnProcessor, XFormersAttnProcessor, AttnProcessor2_027from diffusers.utils.import_utils import is_xformers_available28 29 30def to_rgb_image(maybe_rgba: Image.Image):31    if maybe_rgba.mode == 'RGB':32        return maybe_rgba33    elif maybe_rgba.mode == 'RGBA':34        rgba = maybe_rgba35        img = numpy.random.randint(255, 256, size=[rgba.size[1], rgba.size[0], 3], dtype=numpy.uint8)36        img = Image.fromarray(img, 'RGB')37        img.paste(rgba, mask=rgba.getchannel('A'))38        return img39    else:40        raise ValueError("Unsupported image type.", maybe_rgba.mode)41 42 43class ReferenceOnlyAttnProc(torch.nn.Module):44    def __init__(45        self,46        chained_proc,47        enabled=False,48        name=None49    ) -> None:50        super().__init__()51        self.enabled = enabled52        self.chained_proc = chained_proc53        self.name = name54 55    def __call__(56        self, attn: Attention, hidden_states, encoder_hidden_states=None, attention_mask=None,57        mode="w", ref_dict: dict = None, is_cfg_guidance = False58    ) -> Any:59        if encoder_hidden_states is None:60            encoder_hidden_states = hidden_states61        if self.enabled and is_cfg_guidance:62            res0 = self.chained_proc(attn, hidden_states[:1], encoder_hidden_states[:1], attention_mask)63            hidden_states = hidden_states[1:]64            encoder_hidden_states = encoder_hidden_states[1:]65        if self.enabled:66            if mode == 'w':67                ref_dict[self.name] = encoder_hidden_states68            elif mode == 'r':69                encoder_hidden_states = torch.cat([encoder_hidden_states, ref_dict.pop(self.name)], dim=1)70            elif mode == 'm':71                encoder_hidden_states = torch.cat([encoder_hidden_states, ref_dict[self.name]], dim=1)72            else:73                assert False, mode74        res = self.chained_proc(attn, hidden_states, encoder_hidden_states, attention_mask)75        if self.enabled and is_cfg_guidance:76            res = torch.cat([res0, res])77        return res78 79 80class RefOnlyNoisedUNet(torch.nn.Module):81    def __init__(self, unet: UNet2DConditionModel, train_sched: DDPMScheduler, val_sched: EulerAncestralDiscreteScheduler) -> None:82        super().__init__()83        self.unet = unet84        self.train_sched = train_sched85        self.val_sched = val_sched86 87        unet_lora_attn_procs = dict()88        for name, _ in unet.attn_processors.items():89            if torch.__version__ >= '2.0':90                default_attn_proc = AttnProcessor2_0()91            elif is_xformers_available():92                default_attn_proc = XFormersAttnProcessor()93            else:94                default_attn_proc = AttnProcessor()95            unet_lora_attn_procs[name] = ReferenceOnlyAttnProc(96                default_attn_proc, enabled=name.endswith("attn1.processor"), name=name97            )98        unet.set_attn_processor(unet_lora_attn_procs)99 100    def __getattr__(self, name: str):101        try:102            return super().__getattr__(name)103        except AttributeError:104            return getattr(self.unet, name)105 106    def forward_cond(self, noisy_cond_lat, timestep, encoder_hidden_states, class_labels, ref_dict, is_cfg_guidance, **kwargs):107        if is_cfg_guidance:108            encoder_hidden_states = encoder_hidden_states[1:]109            class_labels = class_labels[1:]110        self.unet(111            noisy_cond_lat, timestep,112            encoder_hidden_states=encoder_hidden_states,113            class_labels=class_labels,114            cross_attention_kwargs=dict(mode="w", ref_dict=ref_dict),115            **kwargs116        )117 118    def forward(119        self, sample, timestep, encoder_hidden_states, class_labels=None,120        *args, cross_attention_kwargs,121        down_block_res_samples=None, mid_block_res_sample=None,122        **kwargs123    ):124        cond_lat = cross_attention_kwargs['cond_lat']125        is_cfg_guidance = cross_attention_kwargs.get('is_cfg_guidance', False)126        noise = torch.randn_like(cond_lat)127        if self.training:128            noisy_cond_lat = self.train_sched.add_noise(cond_lat, noise, timestep)129            noisy_cond_lat = self.train_sched.scale_model_input(noisy_cond_lat, timestep)130        else:131            noisy_cond_lat = self.val_sched.add_noise(cond_lat, noise, timestep.reshape(-1))132            noisy_cond_lat = self.val_sched.scale_model_input(noisy_cond_lat, timestep.reshape(-1))133        ref_dict = {}134        self.forward_cond(135            noisy_cond_lat, timestep,136            encoder_hidden_states, class_labels,137            ref_dict, is_cfg_guidance, **kwargs138        )139        weight_dtype = self.unet.dtype140        return self.unet(141            sample, timestep,142            encoder_hidden_states, *args,143            class_labels=class_labels,144            cross_attention_kwargs=dict(mode="r", ref_dict=ref_dict, is_cfg_guidance=is_cfg_guidance),145            down_block_additional_residuals=[146                sample.to(dtype=weight_dtype) for sample in down_block_res_samples147            ] if down_block_res_samples is not None else None,148            mid_block_additional_residual=(149                mid_block_res_sample.to(dtype=weight_dtype)150                if mid_block_res_sample is not None else None151            ),152            **kwargs153        )154 155 156def scale_latents(latents):157    latents = (latents - 0.22) * 0.75158    return latents159 160 161def unscale_latents(latents):162    latents = latents / 0.75 + 0.22163    return latents164 165 166def scale_image(image):167    image = image * 0.5 / 0.8168    return image169 170 171def unscale_image(image):172    image = image / 0.5 * 0.8173    return image174 175 176class DepthControlUNet(torch.nn.Module):177    def __init__(self, unet: RefOnlyNoisedUNet, controlnet: Optional[diffusers.ControlNetModel] = None, conditioning_scale=1.0) -> None:178        super().__init__()179        self.unet = unet180        if controlnet is None:181            self.controlnet = diffusers.ControlNetModel.from_unet(unet.unet)182        else:183            self.controlnet = controlnet184        DefaultAttnProc = AttnProcessor2_0185        if is_xformers_available():186            DefaultAttnProc = XFormersAttnProcessor187        self.controlnet.set_attn_processor(DefaultAttnProc())188        self.conditioning_scale = conditioning_scale189 190    def __getattr__(self, name: str):191        try:192            return super().__getattr__(name)193        except AttributeError:194            return getattr(self.unet, name)195 196    def forward(self, sample, timestep, encoder_hidden_states, class_labels=None, *args, cross_attention_kwargs: dict, **kwargs):197        cross_attention_kwargs = dict(cross_attention_kwargs)198        control_depth = cross_attention_kwargs.pop('control_depth')199        down_block_res_samples, mid_block_res_sample = self.controlnet(200            sample,201            timestep,202            encoder_hidden_states=encoder_hidden_states,203            controlnet_cond=control_depth,204            conditioning_scale=self.conditioning_scale,205            return_dict=False,206        )207        return self.unet(208            sample,209            timestep,210            encoder_hidden_states=encoder_hidden_states,211            down_block_res_samples=down_block_res_samples,212            mid_block_res_sample=mid_block_res_sample,213            cross_attention_kwargs=cross_attention_kwargs214        )215 216 217class ModuleListDict(torch.nn.Module):218    def __init__(self, procs: dict) -> None:219        super().__init__()220        self.keys = sorted(procs.keys())221        self.values = torch.nn.ModuleList(procs[k] for k in self.keys)222 223    def __getitem__(self, key):224        return self.values[self.keys.index(key)]225 226 227class SuperNet(torch.nn.Module):228    def __init__(self, state_dict: Dict[str, torch.Tensor]):229        super().__init__()230        state_dict = OrderedDict((k, state_dict[k]) for k in sorted(state_dict.keys()))231        self.layers = torch.nn.ModuleList(state_dict.values())232        self.mapping = dict(enumerate(state_dict.keys()))233        self.rev_mapping = {v: k for k, v in enumerate(state_dict.keys())}234 235        # .processor for unet, .self_attn for text encoder236        self.split_keys = [".processor", ".self_attn"]237 238        # we add a hook to state_dict() and load_state_dict() so that the239        # naming fits with `unet.attn_processors`240        def map_to(module, state_dict, *args, **kwargs):241            new_state_dict = {}242            for key, value in state_dict.items():243                num = int(key.split(".")[1])  # 0 is always "layers"244                new_key = key.replace(f"layers.{num}", module.mapping[num])245                new_state_dict[new_key] = value246 247            return new_state_dict248 249        def remap_key(key, state_dict):250            for k in self.split_keys:251                if k in key:252                    return key.split(k)[0] + k253            return key.split('.')[0]254 255        def map_from(module, state_dict, *args, **kwargs):256            all_keys = list(state_dict.keys())257            for key in all_keys:258                replace_key = remap_key(key, state_dict)259                new_key = key.replace(replace_key, f"layers.{module.rev_mapping[replace_key]}")260                state_dict[new_key] = state_dict[key]261                del state_dict[key]262 263        self._register_state_dict_hook(map_to)264        self._register_load_state_dict_pre_hook(map_from, with_module=True)265 266 267class Zero123PlusPipeline(diffusers.StableDiffusionPipeline):268    tokenizer: transformers.CLIPTokenizer269    text_encoder: transformers.CLIPTextModel270    vision_encoder: transformers.CLIPVisionModelWithProjection271 272    feature_extractor_clip: transformers.CLIPImageProcessor273    unet: UNet2DConditionModel274    scheduler: diffusers.schedulers.KarrasDiffusionSchedulers275 276    vae: AutoencoderKL277    ramping: nn.Linear278 279    feature_extractor_vae: transformers.CLIPImageProcessor280 281    depth_transforms_multi = transforms.Compose([282        transforms.ToTensor(),283        transforms.Normalize([0.5], [0.5])284    ])285 286    def __init__(287        self,288        vae: AutoencoderKL,289        text_encoder: CLIPTextModel,290        tokenizer: CLIPTokenizer,291        unet: UNet2DConditionModel,292        scheduler: KarrasDiffusionSchedulers,293        vision_encoder: transformers.CLIPVisionModelWithProjection,294        feature_extractor_clip: CLIPImageProcessor, 295        feature_extractor_vae: CLIPImageProcessor,296        ramping_coefficients: Optional[list] = None,297        safety_checker=None,298    ):299        DiffusionPipeline.__init__(self)300 301        self.register_modules(302            vae=vae, text_encoder=text_encoder, tokenizer=tokenizer,303            unet=unet, scheduler=scheduler, safety_checker=None,304            vision_encoder=vision_encoder,305            feature_extractor_clip=feature_extractor_clip,306            feature_extractor_vae=feature_extractor_vae307        )308        self.register_to_config(ramping_coefficients=ramping_coefficients)309        self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1)310        self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor)311 312    def prepare(self):313        train_sched = DDPMScheduler.from_config(self.scheduler.config)314        if isinstance(self.unet, UNet2DConditionModel):315            self.unet = RefOnlyNoisedUNet(self.unet, train_sched, self.scheduler).eval()316 317    def add_controlnet(self, controlnet: Optional[diffusers.ControlNetModel] = None, conditioning_scale=1.0):318        self.prepare()319        self.unet = DepthControlUNet(self.unet, controlnet, conditioning_scale)320        return SuperNet(OrderedDict([('controlnet', self.unet.controlnet)]))321 322    def encode_condition_image(self, image: torch.Tensor):323        image = self.vae.encode(image).latent_dist.sample()324        return image325 326    @torch.no_grad()327    def __call__(328        self,329        image: Image.Image = None,330        prompt = "",331        *args,332        num_images_per_prompt: Optional[int] = 1,333        guidance_scale=4.0,334        depth_image: Image.Image = None,335        output_type: Optional[str] = "pil",336        width=640,337        height=960,338        num_inference_steps=28,339        return_dict=True,340        **kwargs341    ):342        self.prepare()343        if image is None:344            raise ValueError("Inputting embeddings not supported for this pipeline. Please pass an image.")345        assert not isinstance(image, torch.Tensor)346        image = to_rgb_image(image)347        image_1 = self.feature_extractor_vae(images=image, return_tensors="pt").pixel_values348        image_2 = self.feature_extractor_clip(images=image, return_tensors="pt").pixel_values349        if depth_image is not None and hasattr(self.unet, "controlnet"):350            depth_image = to_rgb_image(depth_image)351            depth_image = self.depth_transforms_multi(depth_image).to(352                device=self.unet.controlnet.device, dtype=self.unet.controlnet.dtype353            )354        image = image_1.to(device=self.vae.device, dtype=self.vae.dtype)355        image_2 = image_2.to(device=self.vae.device, dtype=self.vae.dtype)356        cond_lat = self.encode_condition_image(image)357        if guidance_scale > 1:358            negative_lat = self.encode_condition_image(torch.zeros_like(image))359            cond_lat = torch.cat([negative_lat, cond_lat])360        encoded = self.vision_encoder(image_2, output_hidden_states=False)361        global_embeds = encoded.image_embeds362        global_embeds = global_embeds.unsqueeze(-2)363        364        if hasattr(self, "encode_prompt"):365            encoder_hidden_states = self.encode_prompt(366                prompt,367                self.device,368                num_images_per_prompt,369                False370            )[0]371        else:372            encoder_hidden_states = self._encode_prompt(373                prompt,374                self.device,375                num_images_per_prompt,376                False377            )378        ramp = global_embeds.new_tensor(self.config.ramping_coefficients).unsqueeze(-1)379        encoder_hidden_states = encoder_hidden_states + global_embeds * ramp380        cak = dict(cond_lat=cond_lat)381        if hasattr(self.unet, "controlnet"):382            cak['control_depth'] = depth_image383        latents: torch.Tensor = super().__call__(384            None,385            *args,386            cross_attention_kwargs=cak,387            guidance_scale=guidance_scale,388            num_images_per_prompt=num_images_per_prompt,389            prompt_embeds=encoder_hidden_states,390            num_inference_steps=num_inference_steps,391            output_type='latent',392            width=width,393            height=height,394            **kwargs395        ).images396        latents = unscale_latents(latents)397        if not output_type == "latent":398            image = unscale_image(self.vae.decode(latents / self.vae.config.scaling_factor, return_dict=False)[0])399        else:400            image = latents401 402        image = self.image_processor.postprocess(image, output_type=output_type)403        if not return_dict:404            return (image,)405 406        return ImagePipelineOutput(images=image)407