CoolFace
Apppublic

HIST/ControlNet

sourceHugging Faceupdated 4y agoView on Hugging Face
0likes
model.py726 linesDownload Raw Back to root
1# This file is adapted from gradio_*.py in https://github.com/lllyasviel/ControlNet/tree/f4748e3630d8141d7765e2bd9b1e348f478477072# The original license file is LICENSE.ControlNet this repo.3from __future__ import annotations4 5import pathlib6import random7import shlex8import subprocess9import sys10 11import cv212import einops13import numpy as np14import torch15from pytorch_lightning import seed_everything16 17sys.path.append('ControlNet')18 19import config20from annotator.canny import apply_canny21from annotator.hed import apply_hed, nms22from annotator.midas import apply_midas23from annotator.mlsd import apply_mlsd24from annotator.openpose import apply_openpose25from annotator.uniformer import apply_uniformer26from annotator.util import HWC3, resize_image27from cldm.model import create_model, load_state_dict28from ldm.models.diffusion.ddim import DDIMSampler29from share import *30 31 32class Model:33    WEIGHT_NAMES = {34        'canny': 'control_sd15_canny.pth',35        'hough': 'control_sd15_mlsd.pth',36        'hed': 'control_sd15_hed.pth',37        'scribble': 'control_sd15_scribble.pth',38        'pose': 'control_sd15_openpose.pth',39        'seg': 'control_sd15_seg.pth',40        'depth': 'control_sd15_depth.pth',41        'normal': 'control_sd15_normal.pth',42    }43 44    def __init__(self,45                 model_config_path: str = 'ControlNet/models/cldm_v15.yaml',46                 model_dir: str = 'models'):47        self.device = torch.device(48            'cuda:0' if torch.cuda.is_available() else 'cpu')49        self.model = create_model(model_config_path).to(self.device)50        self.ddim_sampler = DDIMSampler(self.model)51        self.task_name = ''52 53        self.model_dir = pathlib.Path(model_dir)54        self.download_models()55 56    def load_weight(self, task_name: str) -> None:57        if task_name == self.task_name:58            return59        weight_path = self.get_weight_path(task_name)60        self.model.load_state_dict(61            load_state_dict(weight_path, location=self.device))62        self.task_name = task_name63 64    def get_weight_path(self, task_name: str) -> str:65        if 'scribble' in task_name:66            task_name = 'scribble'67        return f'{self.model_dir}/{self.WEIGHT_NAMES[task_name]}'68 69    def download_models(self):70        self.model_dir.mkdir(exist_ok=True, parents=True)71        for name in self.WEIGHT_NAMES.values():72            out_path = self.model_dir / name73            if out_path.exists():74                continue75            subprocess.run(76                shlex.split(77                    f'wget https://huggingface.co/ckpt/ControlNet/resolve/main/{name} -O {out_path}'78                ))79 80    @torch.inference_mode()81    def process_canny(self, input_image, prompt, a_prompt, n_prompt,82                      num_samples, image_resolution, ddim_steps, scale, seed,83                      eta, low_threshold, high_threshold):84        self.load_weight('canny')85 86        img = resize_image(HWC3(input_image), image_resolution)87        H, W, C = img.shape88 89        detected_map = apply_canny(img, low_threshold, high_threshold)90        detected_map = HWC3(detected_map)91 92        control = torch.from_numpy(detected_map.copy()).float().cuda() / 255.093        control = torch.stack([control for _ in range(num_samples)], dim=0)94        control = einops.rearrange(control, 'b h w c -> b c h w').clone()95 96        if seed == -1:97            seed = random.randint(0, 65535)98        seed_everything(seed)99 100        if config.save_memory:101            self.model.low_vram_shift(is_diffusing=False)102 103        cond = {104            'c_concat': [control],105            'c_crossattn': [106                self.model.get_learned_conditioning(107                    [prompt + ', ' + a_prompt] * num_samples)108            ]109        }110        un_cond = {111            'c_concat': [control],112            'c_crossattn':113            [self.model.get_learned_conditioning([n_prompt] * num_samples)]114        }115        shape = (4, H // 8, W // 8)116 117        if config.save_memory:118            self.model.low_vram_shift(is_diffusing=True)119 120        samples, intermediates = self.ddim_sampler.sample(121            ddim_steps,122            num_samples,123            shape,124            cond,125            verbose=False,126            eta=eta,127            unconditional_guidance_scale=scale,128            unconditional_conditioning=un_cond)129 130        if config.save_memory:131            self.model.low_vram_shift(is_diffusing=False)132 133        x_samples = self.model.decode_first_stage(samples)134        x_samples = (135            einops.rearrange(x_samples, 'b c h w -> b h w c') * 127.5 +136            127.5).cpu().numpy().clip(0, 255).astype(np.uint8)137 138        results = [x_samples[i] for i in range(num_samples)]139        return [255 - detected_map] + results140 141    @torch.inference_mode()142    def process_hough(self, input_image, prompt, a_prompt, n_prompt,143                      num_samples, image_resolution, detect_resolution,144                      ddim_steps, scale, seed, eta, value_threshold,145                      distance_threshold):146        self.load_weight('hough')147 148        input_image = HWC3(input_image)149        detected_map = apply_mlsd(resize_image(input_image, detect_resolution),150                                  value_threshold, distance_threshold)151        detected_map = HWC3(detected_map)152        img = resize_image(input_image, image_resolution)153        H, W, C = img.shape154 155        detected_map = cv2.resize(detected_map, (W, H),156                                  interpolation=cv2.INTER_NEAREST)157 158        control = torch.from_numpy(detected_map.copy()).float().cuda() / 255.0159        control = torch.stack([control for _ in range(num_samples)], dim=0)160        control = einops.rearrange(control, 'b h w c -> b c h w').clone()161 162        if seed == -1:163            seed = random.randint(0, 65535)164        seed_everything(seed)165 166        if config.save_memory:167            self.model.low_vram_shift(is_diffusing=False)168 169        cond = {170            'c_concat': [control],171            'c_crossattn': [172                self.model.get_learned_conditioning(173                    [prompt + ', ' + a_prompt] * num_samples)174            ]175        }176        un_cond = {177            'c_concat': [control],178            'c_crossattn':179            [self.model.get_learned_conditioning([n_prompt] * num_samples)]180        }181        shape = (4, H // 8, W // 8)182 183        if config.save_memory:184            self.model.low_vram_shift(is_diffusing=True)185 186        samples, intermediates = self.ddim_sampler.sample(187            ddim_steps,188            num_samples,189            shape,190            cond,191            verbose=False,192            eta=eta,193            unconditional_guidance_scale=scale,194            unconditional_conditioning=un_cond)195 196        if config.save_memory:197            self.model.low_vram_shift(is_diffusing=False)198 199        x_samples = self.model.decode_first_stage(samples)200        x_samples = (201            einops.rearrange(x_samples, 'b c h w -> b h w c') * 127.5 +202            127.5).cpu().numpy().clip(0, 255).astype(np.uint8)203 204        results = [x_samples[i] for i in range(num_samples)]205        return [206            255 - cv2.dilate(detected_map,207                             np.ones(shape=(3, 3), dtype=np.uint8),208                             iterations=1)209        ] + results210 211    @torch.inference_mode()212    def process_hed(self, input_image, prompt, a_prompt, n_prompt, num_samples,213                    image_resolution, detect_resolution, ddim_steps, scale,214                    seed, eta):215        self.load_weight('hed')216 217        input_image = HWC3(input_image)218        detected_map = apply_hed(resize_image(input_image, detect_resolution))219        detected_map = HWC3(detected_map)220        img = resize_image(input_image, image_resolution)221        H, W, C = img.shape222 223        detected_map = cv2.resize(detected_map, (W, H),224                                  interpolation=cv2.INTER_LINEAR)225 226        control = torch.from_numpy(detected_map.copy()).float().cuda() / 255.0227        control = torch.stack([control for _ in range(num_samples)], dim=0)228        control = einops.rearrange(control, 'b h w c -> b c h w').clone()229 230        if seed == -1:231            seed = random.randint(0, 65535)232        seed_everything(seed)233 234        if config.save_memory:235            self.model.low_vram_shift(is_diffusing=False)236 237        cond = {238            'c_concat': [control],239            'c_crossattn': [240                self.model.get_learned_conditioning(241                    [prompt + ', ' + a_prompt] * num_samples)242            ]243        }244        un_cond = {245            'c_concat': [control],246            'c_crossattn':247            [self.model.get_learned_conditioning([n_prompt] * num_samples)]248        }249        shape = (4, H // 8, W // 8)250 251        if config.save_memory:252            self.model.low_vram_shift(is_diffusing=True)253 254        samples, intermediates = self.ddim_sampler.sample(255            ddim_steps,256            num_samples,257            shape,258            cond,259            verbose=False,260            eta=eta,261            unconditional_guidance_scale=scale,262            unconditional_conditioning=un_cond)263 264        if config.save_memory:265            self.model.low_vram_shift(is_diffusing=False)266 267        x_samples = self.model.decode_first_stage(samples)268        x_samples = (269            einops.rearrange(x_samples, 'b c h w -> b h w c') * 127.5 +270            127.5).cpu().numpy().clip(0, 255).astype(np.uint8)271 272        results = [x_samples[i] for i in range(num_samples)]273        return [detected_map] + results274 275    @torch.inference_mode()276    def process_scribble(self, input_image, prompt, a_prompt, n_prompt,277                         num_samples, image_resolution, ddim_steps, scale,278                         seed, eta):279        self.load_weight('scribble')280 281        img = resize_image(HWC3(input_image), image_resolution)282        H, W, C = img.shape283 284        detected_map = np.zeros_like(img, dtype=np.uint8)285        detected_map[np.min(img, axis=2) < 127] = 255286 287        control = torch.from_numpy(detected_map.copy()).float().cuda() / 255.0288        control = torch.stack([control for _ in range(num_samples)], dim=0)289        control = einops.rearrange(control, 'b h w c -> b c h w').clone()290 291        if seed == -1:292            seed = random.randint(0, 65535)293        seed_everything(seed)294 295        if config.save_memory:296            self.model.low_vram_shift(is_diffusing=False)297 298        cond = {299            'c_concat': [control],300            'c_crossattn': [301                self.model.get_learned_conditioning(302                    [prompt + ', ' + a_prompt] * num_samples)303            ]304        }305        un_cond = {306            'c_concat': [control],307            'c_crossattn':308            [self.model.get_learned_conditioning([n_prompt] * num_samples)]309        }310        shape = (4, H // 8, W // 8)311 312        if config.save_memory:313            self.model.low_vram_shift(is_diffusing=True)314 315        samples, intermediates = self.ddim_sampler.sample(316            ddim_steps,317            num_samples,318            shape,319            cond,320            verbose=False,321            eta=eta,322            unconditional_guidance_scale=scale,323            unconditional_conditioning=un_cond)324 325        if config.save_memory:326            self.model.low_vram_shift(is_diffusing=False)327 328        x_samples = self.model.decode_first_stage(samples)329        x_samples = (330            einops.rearrange(x_samples, 'b c h w -> b h w c') * 127.5 +331            127.5).cpu().numpy().clip(0, 255).astype(np.uint8)332 333        results = [x_samples[i] for i in range(num_samples)]334        return [255 - detected_map] + results335 336    @torch.inference_mode()337    def process_scribble_interactive(self, input_image, prompt, a_prompt,338                                     n_prompt, num_samples, image_resolution,339                                     ddim_steps, scale, seed, eta):340        self.load_weight('scribble')341 342        img = resize_image(HWC3(input_image['mask'][:, :, 0]),343                           image_resolution)344        H, W, C = img.shape345 346        detected_map = np.zeros_like(img, dtype=np.uint8)347        detected_map[np.min(img, axis=2) > 127] = 255348 349        control = torch.from_numpy(detected_map.copy()).float().cuda() / 255.0350        control = torch.stack([control for _ in range(num_samples)], dim=0)351        control = einops.rearrange(control, 'b h w c -> b c h w').clone()352 353        if seed == -1:354            seed = random.randint(0, 65535)355        seed_everything(seed)356 357        if config.save_memory:358            self.model.low_vram_shift(is_diffusing=False)359 360        cond = {361            'c_concat': [control],362            'c_crossattn': [363                self.model.get_learned_conditioning(364                    [prompt + ', ' + a_prompt] * num_samples)365            ]366        }367        un_cond = {368            'c_concat': [control],369            'c_crossattn':370            [self.model.get_learned_conditioning([n_prompt] * num_samples)]371        }372        shape = (4, H // 8, W // 8)373 374        if config.save_memory:375            self.model.low_vram_shift(is_diffusing=True)376 377        samples, intermediates = self.ddim_sampler.sample(378            ddim_steps,379            num_samples,380            shape,381            cond,382            verbose=False,383            eta=eta,384            unconditional_guidance_scale=scale,385            unconditional_conditioning=un_cond)386 387        if config.save_memory:388            self.model.low_vram_shift(is_diffusing=False)389 390        x_samples = self.model.decode_first_stage(samples)391        x_samples = (392            einops.rearrange(x_samples, 'b c h w -> b h w c') * 127.5 +393            127.5).cpu().numpy().clip(0, 255).astype(np.uint8)394 395        results = [x_samples[i] for i in range(num_samples)]396        return [255 - detected_map] + results397 398    @torch.inference_mode()399    def process_fake_scribble(self, input_image, prompt, a_prompt, n_prompt,400                              num_samples, image_resolution, detect_resolution,401                              ddim_steps, scale, seed, eta):402        self.load_weight('scribble')403 404        input_image = HWC3(input_image)405        detected_map = apply_hed(resize_image(input_image, detect_resolution))406        detected_map = HWC3(detected_map)407        img = resize_image(input_image, image_resolution)408        H, W, C = img.shape409 410        detected_map = cv2.resize(detected_map, (W, H),411                                  interpolation=cv2.INTER_LINEAR)412        detected_map = nms(detected_map, 127, 3.0)413        detected_map = cv2.GaussianBlur(detected_map, (0, 0), 3.0)414        detected_map[detected_map > 4] = 255415        detected_map[detected_map < 255] = 0416 417        control = torch.from_numpy(detected_map.copy()).float().cuda() / 255.0418        control = torch.stack([control for _ in range(num_samples)], dim=0)419        control = einops.rearrange(control, 'b h w c -> b c h w').clone()420 421        if seed == -1:422            seed = random.randint(0, 65535)423        seed_everything(seed)424 425        if config.save_memory:426            self.model.low_vram_shift(is_diffusing=False)427 428        cond = {429            'c_concat': [control],430            'c_crossattn': [431                self.model.get_learned_conditioning(432                    [prompt + ', ' + a_prompt] * num_samples)433            ]434        }435        un_cond = {436            'c_concat': [control],437            'c_crossattn':438            [self.model.get_learned_conditioning([n_prompt] * num_samples)]439        }440        shape = (4, H // 8, W // 8)441 442        if config.save_memory:443            self.model.low_vram_shift(is_diffusing=True)444 445        samples, intermediates = self.ddim_sampler.sample(446            ddim_steps,447            num_samples,448            shape,449            cond,450            verbose=False,451            eta=eta,452            unconditional_guidance_scale=scale,453            unconditional_conditioning=un_cond)454 455        if config.save_memory:456            self.model.low_vram_shift(is_diffusing=False)457 458        x_samples = self.model.decode_first_stage(samples)459        x_samples = (460            einops.rearrange(x_samples, 'b c h w -> b h w c') * 127.5 +461            127.5).cpu().numpy().clip(0, 255).astype(np.uint8)462 463        results = [x_samples[i] for i in range(num_samples)]464        return [255 - detected_map] + results465 466    @torch.inference_mode()467    def process_pose(self, input_image, prompt, a_prompt, n_prompt,468                     num_samples, image_resolution, detect_resolution,469                     ddim_steps, scale, seed, eta):470        self.load_weight('pose')471 472        input_image = HWC3(input_image)473        detected_map, _ = apply_openpose(474            resize_image(input_image, detect_resolution))475        detected_map = HWC3(detected_map)476        img = resize_image(input_image, image_resolution)477        H, W, C = img.shape478 479        detected_map = cv2.resize(detected_map, (W, H),480                                  interpolation=cv2.INTER_NEAREST)481 482        control = torch.from_numpy(detected_map.copy()).float().cuda() / 255.0483        control = torch.stack([control for _ in range(num_samples)], dim=0)484        control = einops.rearrange(control, 'b h w c -> b c h w').clone()485 486        if seed == -1:487            seed = random.randint(0, 65535)488        seed_everything(seed)489 490        if config.save_memory:491            self.model.low_vram_shift(is_diffusing=False)492 493        cond = {494            'c_concat': [control],495            'c_crossattn': [496                self.model.get_learned_conditioning(497                    [prompt + ', ' + a_prompt] * num_samples)498            ]499        }500        un_cond = {501            'c_concat': [control],502            'c_crossattn':503            [self.model.get_learned_conditioning([n_prompt] * num_samples)]504        }505        shape = (4, H // 8, W // 8)506 507        if config.save_memory:508            self.model.low_vram_shift(is_diffusing=True)509 510        samples, intermediates = self.ddim_sampler.sample(511            ddim_steps,512            num_samples,513            shape,514            cond,515            verbose=False,516            eta=eta,517            unconditional_guidance_scale=scale,518            unconditional_conditioning=un_cond)519 520        if config.save_memory:521            self.model.low_vram_shift(is_diffusing=False)522 523        x_samples = self.model.decode_first_stage(samples)524        x_samples = (525            einops.rearrange(x_samples, 'b c h w -> b h w c') * 127.5 +526            127.5).cpu().numpy().clip(0, 255).astype(np.uint8)527 528        results = [x_samples[i] for i in range(num_samples)]529        return [detected_map] + results530 531    @torch.inference_mode()532    def process_seg(self, input_image, prompt, a_prompt, n_prompt, num_samples,533                    image_resolution, detect_resolution, ddim_steps, scale,534                    seed, eta):535        self.load_weight('seg')536 537        input_image = HWC3(input_image)538        detected_map = apply_uniformer(539            resize_image(input_image, detect_resolution))540        img = resize_image(input_image, image_resolution)541        H, W, C = img.shape542 543        detected_map = cv2.resize(detected_map, (W, H),544                                  interpolation=cv2.INTER_NEAREST)545 546        control = torch.from_numpy(detected_map.copy()).float().cuda() / 255.0547        control = torch.stack([control for _ in range(num_samples)], dim=0)548        control = einops.rearrange(control, 'b h w c -> b c h w').clone()549 550        if seed == -1:551            seed = random.randint(0, 65535)552        seed_everything(seed)553 554        if config.save_memory:555            self.model.low_vram_shift(is_diffusing=False)556 557        cond = {558            'c_concat': [control],559            'c_crossattn': [560                self.model.get_learned_conditioning(561                    [prompt + ', ' + a_prompt] * num_samples)562            ]563        }564        un_cond = {565            'c_concat': [control],566            'c_crossattn':567            [self.model.get_learned_conditioning([n_prompt] * num_samples)]568        }569        shape = (4, H // 8, W // 8)570 571        if config.save_memory:572            self.model.low_vram_shift(is_diffusing=True)573 574        samples, intermediates = self.ddim_sampler.sample(575            ddim_steps,576            num_samples,577            shape,578            cond,579            verbose=False,580            eta=eta,581            unconditional_guidance_scale=scale,582            unconditional_conditioning=un_cond)583 584        if config.save_memory:585            self.model.low_vram_shift(is_diffusing=False)586 587        x_samples = self.model.decode_first_stage(samples)588        x_samples = (589            einops.rearrange(x_samples, 'b c h w -> b h w c') * 127.5 +590            127.5).cpu().numpy().clip(0, 255).astype(np.uint8)591 592        results = [x_samples[i] for i in range(num_samples)]593        return [detected_map] + results594 595    @torch.inference_mode()596    def process_depth(self, input_image, prompt, a_prompt, n_prompt,597                      num_samples, image_resolution, detect_resolution,598                      ddim_steps, scale, seed, eta):599        self.load_weight('depth')600 601        input_image = HWC3(input_image)602        detected_map, _ = apply_midas(603            resize_image(input_image, detect_resolution))604        detected_map = HWC3(detected_map)605        img = resize_image(input_image, image_resolution)606        H, W, C = img.shape607 608        detected_map = cv2.resize(detected_map, (W, H),609                                  interpolation=cv2.INTER_LINEAR)610 611        control = torch.from_numpy(detected_map.copy()).float().cuda() / 255.0612        control = torch.stack([control for _ in range(num_samples)], dim=0)613        control = einops.rearrange(control, 'b h w c -> b c h w').clone()614 615        if seed == -1:616            seed = random.randint(0, 65535)617        seed_everything(seed)618 619        if config.save_memory:620            self.model.low_vram_shift(is_diffusing=False)621 622        cond = {623            'c_concat': [control],624            'c_crossattn': [625                self.model.get_learned_conditioning(626                    [prompt + ', ' + a_prompt] * num_samples)627            ]628        }629        un_cond = {630            'c_concat': [control],631            'c_crossattn':632            [self.model.get_learned_conditioning([n_prompt] * num_samples)]633        }634        shape = (4, H // 8, W // 8)635 636        if config.save_memory:637            self.model.low_vram_shift(is_diffusing=True)638 639        samples, intermediates = self.ddim_sampler.sample(640            ddim_steps,641            num_samples,642            shape,643            cond,644            verbose=False,645            eta=eta,646            unconditional_guidance_scale=scale,647            unconditional_conditioning=un_cond)648 649        if config.save_memory:650            self.model.low_vram_shift(is_diffusing=False)651 652        x_samples = self.model.decode_first_stage(samples)653        x_samples = (654            einops.rearrange(x_samples, 'b c h w -> b h w c') * 127.5 +655            127.5).cpu().numpy().clip(0, 255).astype(np.uint8)656 657        results = [x_samples[i] for i in range(num_samples)]658        return [detected_map] + results659 660    @torch.inference_mode()661    def process_normal(self, input_image, prompt, a_prompt, n_prompt,662                       num_samples, image_resolution, detect_resolution,663                       ddim_steps, scale, seed, eta, bg_threshold):664        self.load_weight('normal')665 666        input_image = HWC3(input_image)667        _, detected_map = apply_midas(resize_image(input_image,668                                                   detect_resolution),669                                      bg_th=bg_threshold)670        detected_map = HWC3(detected_map)671        img = resize_image(input_image, image_resolution)672        H, W, C = img.shape673 674        detected_map = cv2.resize(detected_map, (W, H),675                                  interpolation=cv2.INTER_LINEAR)676 677        control = torch.from_numpy(678            detected_map[:, :, ::-1].copy()).float().cuda() / 255.0679        control = torch.stack([control for _ in range(num_samples)], dim=0)680        control = einops.rearrange(control, 'b h w c -> b c h w').clone()681 682        if seed == -1:683            seed = random.randint(0, 65535)684        seed_everything(seed)685 686        if config.save_memory:687            self.model.low_vram_shift(is_diffusing=False)688 689        cond = {690            'c_concat': [control],691            'c_crossattn': [692                self.model.get_learned_conditioning(693                    [prompt + ', ' + a_prompt] * num_samples)694            ]695        }696        un_cond = {697            'c_concat': [control],698            'c_crossattn':699            [self.model.get_learned_conditioning([n_prompt] * num_samples)]700        }701        shape = (4, H // 8, W // 8)702 703        if config.save_memory:704            self.model.low_vram_shift(is_diffusing=True)705 706        samples, intermediates = self.ddim_sampler.sample(707            ddim_steps,708            num_samples,709            shape,710            cond,711            verbose=False,712            eta=eta,713            unconditional_guidance_scale=scale,714            unconditional_conditioning=un_cond)715 716        if config.save_memory:717            self.model.low_vram_shift(is_diffusing=False)718 719        x_samples = self.model.decode_first_stage(samples)720        x_samples = (721            einops.rearrange(x_samples, 'b c h w -> b h w c') * 127.5 +722            127.5).cpu().numpy().clip(0, 255).astype(np.uint8)723 724        results = [x_samples[i] for i in range(num_samples)]725        return [detected_map] + results726