| 6 | |
| 7 | |
| 8 | class BasePipeline(torch.nn.Module): |
| 9 | |
| 10 | def __init__(self, device="cuda", torch_dtype=torch.float16, height_division_factor=64, width_division_factor=64): |
| 11 | super().__init__() |
| 12 | self.device = device |
| 13 | self.torch_dtype = torch_dtype |
| 14 | self.height_division_factor = height_division_factor |
| 15 | self.width_division_factor = width_division_factor |
| 16 | self.cpu_offload = False |
| 17 | self.model_names = [] |
| 18 | |
| 19 | |
| 20 | def check_resize_height_width(self, height, width): |
| 21 | if height % self.height_division_factor != 0: |
| 22 | height = (height + self.height_division_factor - 1) // self.height_division_factor * self.height_division_factor |
| 23 | print(f"The height cannot be evenly divided by {self.height_division_factor}. We round it up to {height}.") |
| 24 | if width % self.width_division_factor != 0: |
| 25 | width = (width + self.width_division_factor - 1) // self.width_division_factor * self.width_division_factor |
| 26 | print(f"The width cannot be evenly divided by {self.width_division_factor}. We round it up to {width}.") |
| 27 | return height, width |
| 28 | |
| 29 | |
| 30 | def preprocess_image(self, image): |
| 31 | image = torch.Tensor(np.array(image, dtype=np.float32) * (2 / 255) - 1).permute(2, 0, 1).unsqueeze(0) |
| 32 | return image |
| 33 | |
| 34 | |
| 35 | def preprocess_images(self, images): |
| 36 | return [self.preprocess_image(image) for image in images] |
| 37 | |
| 38 | |
| 39 | def vae_output_to_image(self, vae_output): |
| 40 | image = vae_output[0].cpu().float().permute(1, 2, 0).numpy() |
| 41 | image = Image.fromarray(((image / 2 + 0.5).clip(0, 1) * 255).astype("uint8")) |
| 42 | return image |
| 43 | |
| 44 | |
| 45 | def vae_output_to_video(self, vae_output): |
| 46 | video = vae_output.cpu().permute(1, 2, 0).numpy() |
| 47 | video = [Image.fromarray(((image / 2 + 0.5).clip(0, 1) * 255).astype("uint8")) for image in video] |
| 48 | return video |
| 49 | |
| 50 | |
| 51 | def merge_latents(self, value, latents, masks, scales, blur_kernel_size=33, blur_sigma=10.0): |
| 52 | if len(latents) > 0: |
| 53 | blur = GaussianBlur(kernel_size=blur_kernel_size, sigma=blur_sigma) |
| 54 | height, width = value.shape[-2:] |
| 55 | weight = torch.ones_like(value) |
| 56 | for latent, mask, scale in zip(latents, masks, scales): |
| 57 | mask = self.preprocess_image(mask.resize((width, height))).mean(dim=1, keepdim=True) > 0 |
| 58 | mask = mask.repeat(1, latent.shape[1], 1, 1).to(dtype=latent.dtype, device=latent.device) |
| 59 | mask = blur(mask) |
| 60 | value += latent * mask * scale |
| 61 | weight += mask * scale |
| 62 | value /= weight |
| 63 | return value |
| 64 | |
| 65 |
nothing calls this directly
no outgoing calls
no test coverage detected