Spaces:
Running
on
Zero
Running
on
Zero
Commit
·
bb42522
1
Parent(s):
76bf5ed
updated pipeline example
Browse files- app.py +2 -2
- pipeline/mod_controlnet_tile_sr_sdxl.py +134 -127
app.py
CHANGED
|
@@ -3,7 +3,7 @@ import spaces
|
|
| 3 |
from diffusers import ControlNetUnionModel, AutoencoderKL
|
| 4 |
import gradio as gr
|
| 5 |
|
| 6 |
-
from pipeline.mod_controlnet_tile_sr_sdxl import StableDiffusionXLControlNetTileSRPipeline
|
| 7 |
from pipeline.util import (
|
| 8 |
SAMPLERS,
|
| 9 |
create_hdr_effect,
|
|
@@ -97,7 +97,7 @@ def predict(
|
|
| 97 |
print(f"Applied HDR effect: {True if hdr > 0 else False}")
|
| 98 |
|
| 99 |
# Calculate overlap size
|
| 100 |
-
normal_tile_overlap, border_tile_overlap = calculate_overlap(target_width, target_height)
|
| 101 |
|
| 102 |
# Image generation
|
| 103 |
print("Diffusion kicking in... almost done, coffee's on you!")
|
|
|
|
| 3 |
from diffusers import ControlNetUnionModel, AutoencoderKL
|
| 4 |
import gradio as gr
|
| 5 |
|
| 6 |
+
from pipeline.mod_controlnet_tile_sr_sdxl import StableDiffusionXLControlNetTileSRPipeline
|
| 7 |
from pipeline.util import (
|
| 8 |
SAMPLERS,
|
| 9 |
create_hdr_effect,
|
|
|
|
| 97 |
print(f"Applied HDR effect: {True if hdr > 0 else False}")
|
| 98 |
|
| 99 |
# Calculate overlap size
|
| 100 |
+
normal_tile_overlap, border_tile_overlap = pipeline.pipe.calculate_overlap(target_width, target_height)
|
| 101 |
|
| 102 |
# Image generation
|
| 103 |
print("Diffusion kicking in... almost done, coffee's on you!")
|
pipeline/mod_controlnet_tile_sr_sdxl.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
# Copyright 2025 DEVAIEXP and The HuggingFace Team. All rights reserved.
|
| 2 |
#
|
| 3 |
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
# you may not use this file except in compliance with the License.
|
|
@@ -57,11 +57,13 @@ from diffusers.utils import (
|
|
| 57 |
from diffusers.utils.import_utils import is_invisible_watermark_available
|
| 58 |
from diffusers.utils.torch_utils import is_compiled_module, randn_tensor
|
| 59 |
|
|
|
|
| 60 |
if is_invisible_watermark_available():
|
| 61 |
from diffusers.pipelines.stable_diffusion_xl.watermark import StableDiffusionXLWatermarker
|
| 62 |
|
| 63 |
from diffusers.utils import is_torch_xla_available
|
| 64 |
|
|
|
|
| 65 |
if is_torch_xla_available():
|
| 66 |
import torch_xla.core.xla_model as xm
|
| 67 |
|
|
@@ -74,91 +76,96 @@ logger = logging.get_logger(__name__) # pylint: disable=invalid-name
|
|
| 74 |
|
| 75 |
EXAMPLE_DOC_STRING = """
|
| 76 |
Examples:
|
| 77 |
-
```
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
"
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
```
|
| 159 |
"""
|
| 160 |
|
| 161 |
-
|
| 162 |
# This function was copied and adapted from https://huggingface.co/spaces/gokaygokay/TileUpscalerV2, licensed under Apache 2.0.
|
| 163 |
def _adaptive_tile_size(image_size, base_tile_size=512, max_tile_size=1280):
|
| 164 |
"""
|
|
@@ -256,32 +263,6 @@ def retrieve_latents(
|
|
| 256 |
else:
|
| 257 |
raise AttributeError("Could not access latents of provided encoder_output")
|
| 258 |
|
| 259 |
-
def calculate_overlap(width, height, base_overlap=128):
|
| 260 |
-
"""
|
| 261 |
-
Calculates dynamic overlap based on the image's aspect ratio.
|
| 262 |
-
|
| 263 |
-
Args:
|
| 264 |
-
width (int): Width of the image in pixels.
|
| 265 |
-
height (int): Height of the image in pixels.
|
| 266 |
-
base_overlap (int, optional): Base overlap value in pixels. Defaults to 128.
|
| 267 |
-
|
| 268 |
-
Returns:
|
| 269 |
-
tuple: A tuple containing:
|
| 270 |
-
- row_overlap (int): Overlap between tiles in consecutive rows.
|
| 271 |
-
- col_overlap (int): Overlap between tiles in consecutive columns.
|
| 272 |
-
"""
|
| 273 |
-
ratio = height / width
|
| 274 |
-
if ratio < 1: # Image is wider than tall
|
| 275 |
-
return base_overlap // 2, base_overlap
|
| 276 |
-
else: # Image is taller than wide
|
| 277 |
-
return base_overlap, base_overlap * 2
|
| 278 |
-
|
| 279 |
-
class TileWeightingMethod(Enum):
|
| 280 |
-
"""Mode in which the tile weights will be generated"""
|
| 281 |
-
|
| 282 |
-
COSINE = "Cosine"
|
| 283 |
-
GAUSSIAN = "Gaussian"
|
| 284 |
-
|
| 285 |
class StableDiffusionXLControlNetTileSRPipeline(
|
| 286 |
DiffusionPipeline,
|
| 287 |
StableDiffusionMixin,
|
|
@@ -392,6 +373,32 @@ class StableDiffusionXLControlNetTileSRPipeline(
|
|
| 392 |
self.register_to_config(force_zeros_for_empty_prompt=force_zeros_for_empty_prompt)
|
| 393 |
self.register_to_config(requires_aesthetics_score=requires_aesthetics_score)
|
| 394 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 395 |
# Copied from diffusers.pipelines.stable_diffusion_xl.pipeline_stable_diffusion_xl.StableDiffusionXLPipeline.encode_prompt
|
| 396 |
def encode_prompt(
|
| 397 |
self,
|
|
@@ -452,7 +459,7 @@ class StableDiffusionXLControlNetTileSRPipeline(
|
|
| 452 |
the output of the pre-final layer will be used for computing the prompt embeddings.
|
| 453 |
"""
|
| 454 |
device = device or self._execution_device
|
| 455 |
-
|
| 456 |
# set lora scale so that monkey patched LoRA
|
| 457 |
# function of text encoder can correctly access it
|
| 458 |
if lora_scale is not None and isinstance(self, StableDiffusionXLLoraLoaderMixin):
|
|
@@ -675,48 +682,48 @@ class StableDiffusionXLControlNetTileSRPipeline(
|
|
| 675 |
if strength < 0 or strength > 1:
|
| 676 |
raise ValueError(f"The value of strength should in [0.0, 1.0] but is {strength}")
|
| 677 |
if num_inference_steps is None:
|
| 678 |
-
raise ValueError("`num_inference_steps` cannot be None.")
|
| 679 |
elif not isinstance(num_inference_steps, int) or num_inference_steps <= 0:
|
| 680 |
raise ValueError(
|
| 681 |
f"`num_inference_steps` has to be a positive integer but is {num_inference_steps} of type"
|
| 682 |
f" {type(num_inference_steps)}."
|
| 683 |
)
|
| 684 |
if normal_tile_overlap is None:
|
| 685 |
-
raise ValueError("`normal_tile_overlap` cannot be None.")
|
| 686 |
elif not isinstance(normal_tile_overlap, int) or normal_tile_overlap < 64:
|
| 687 |
raise ValueError(
|
| 688 |
f"`normal_tile_overlap` has to be greater than 64 but is {normal_tile_overlap} of type"
|
| 689 |
f" {type(normal_tile_overlap)}."
|
| 690 |
)
|
| 691 |
if border_tile_overlap is None:
|
| 692 |
-
raise ValueError("`border_tile_overlap` cannot be None.")
|
| 693 |
elif not isinstance(border_tile_overlap, int) or border_tile_overlap < 128:
|
| 694 |
raise ValueError(
|
| 695 |
f"`border_tile_overlap` has to be greater than 128 but is {border_tile_overlap} of type"
|
| 696 |
f" {type(border_tile_overlap)}."
|
| 697 |
)
|
| 698 |
if max_tile_size is None:
|
| 699 |
-
raise ValueError("`max_tile_size` cannot be None.")
|
| 700 |
elif not isinstance(max_tile_size, int) or max_tile_size not in(1024, 1280):
|
| 701 |
raise ValueError(
|
| 702 |
f"`max_tile_size` has to be in 1024 or 1280 but is {max_tile_size} of type"
|
| 703 |
f" {type(max_tile_size)}."
|
| 704 |
-
)
|
| 705 |
if tile_gaussian_sigma is None:
|
| 706 |
-
raise ValueError("`tile_gaussian_sigma` cannot be None.")
|
| 707 |
elif not isinstance(tile_gaussian_sigma, float) or tile_gaussian_sigma <= 0:
|
| 708 |
raise ValueError(
|
| 709 |
f"`tile_gaussian_sigma` has to be a positive float but is {tile_gaussian_sigma} of type"
|
| 710 |
f" {type(tile_gaussian_sigma)}."
|
| 711 |
)
|
| 712 |
if tile_weighting_method is None:
|
| 713 |
-
raise ValueError("`tile_weighting_method` cannot be None.")
|
| 714 |
-
elif not isinstance(tile_weighting_method, str) or tile_weighting_method not in [t.value for t in TileWeightingMethod]:
|
| 715 |
raise ValueError(
|
| 716 |
-
f"`tile_weighting_method` has to be a string in ({[t.value for t in TileWeightingMethod]}) but is {tile_weighting_method} of type"
|
| 717 |
f" {type(tile_weighting_method)}."
|
| 718 |
)
|
| 719 |
-
|
| 720 |
# Check `image`
|
| 721 |
is_compiled = hasattr(F, "scaled_dot_product_attention") and isinstance(
|
| 722 |
self.controlnet, torch._dynamo.eval_frame.OptimizedModule
|
|
@@ -1122,7 +1129,7 @@ class StableDiffusionXLControlNetTileSRPipeline(
|
|
| 1122 |
grid_cols = int(np.ceil((width - normal_tile_overlap) / (tile_width - normal_tile_overlap)))
|
| 1123 |
|
| 1124 |
return grid_rows, grid_cols
|
| 1125 |
-
|
| 1126 |
def prepare_tiles(
|
| 1127 |
self,
|
| 1128 |
grid_rows,
|
|
@@ -1163,7 +1170,7 @@ class StableDiffusionXLControlNetTileSRPipeline(
|
|
| 1163 |
- tile_row_overlaps (np.ndarray): Array of row overlaps for each tile.
|
| 1164 |
- tile_col_overlaps (np.ndarray): Array of column overlaps for each tile.
|
| 1165 |
"""
|
| 1166 |
-
|
| 1167 |
# Create arrays to store dynamic overlaps and weights
|
| 1168 |
tile_row_overlaps = np.full((grid_rows, grid_cols), normal_tile_overlap)
|
| 1169 |
tile_col_overlaps = np.full((grid_rows, grid_cols), normal_tile_overlap)
|
|
@@ -1197,7 +1204,7 @@ class StableDiffusionXLControlNetTileSRPipeline(
|
|
| 1197 |
sigma = tile_sigma * 1.2
|
| 1198 |
|
| 1199 |
# Calculate weights for the current tile
|
| 1200 |
-
if tile_weighting_method == TileWeightingMethod.COSINE.value:
|
| 1201 |
tile_weights[row, col] = self._generate_cosine_weights(
|
| 1202 |
tile_width=current_tile_width,
|
| 1203 |
tile_height=current_tile_height,
|
|
@@ -1452,7 +1459,7 @@ class StableDiffusionXLControlNetTileSRPipeline(
|
|
| 1452 |
original_size = original_size or (height, width)
|
| 1453 |
target_size = target_size or (height, width)
|
| 1454 |
negative_original_size = negative_original_size or original_size
|
| 1455 |
-
negative_target_size = negative_target_size or target_size
|
| 1456 |
control_type = [0 for _ in range(num_control_type)]
|
| 1457 |
control_type = torch.Tensor(control_type)
|
| 1458 |
self._guidance_scale = guidance_scale
|
|
@@ -1486,9 +1493,9 @@ class StableDiffusionXLControlNetTileSRPipeline(
|
|
| 1486 |
|
| 1487 |
# 2 Get tile width and tile height size
|
| 1488 |
tile_width, tile_height = _adaptive_tile_size((width, height), max_tile_size=max_tile_size)
|
| 1489 |
-
|
| 1490 |
-
# 2.1 Calculate the number of tiles needed
|
| 1491 |
-
grid_rows, grid_cols = self._get_num_tiles(height, width, tile_height, tile_width, normal_tile_overlap, border_tile_overlap)
|
| 1492 |
|
| 1493 |
# 2.2 Expand prompt to number of tiles
|
| 1494 |
if not isinstance(prompt, list):
|
|
|
|
| 1 |
+
# Copyright 2025 The DEVAIEXP Team and The HuggingFace Team. All rights reserved.
|
| 2 |
#
|
| 3 |
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
# you may not use this file except in compliance with the License.
|
|
|
|
| 57 |
from diffusers.utils.import_utils import is_invisible_watermark_available
|
| 58 |
from diffusers.utils.torch_utils import is_compiled_module, randn_tensor
|
| 59 |
|
| 60 |
+
|
| 61 |
if is_invisible_watermark_available():
|
| 62 |
from diffusers.pipelines.stable_diffusion_xl.watermark import StableDiffusionXLWatermarker
|
| 63 |
|
| 64 |
from diffusers.utils import is_torch_xla_available
|
| 65 |
|
| 66 |
+
|
| 67 |
if is_torch_xla_available():
|
| 68 |
import torch_xla.core.xla_model as xm
|
| 69 |
|
|
|
|
| 76 |
|
| 77 |
EXAMPLE_DOC_STRING = """
|
| 78 |
Examples:
|
| 79 |
+
``` import torch
|
| 80 |
+
from diffusers import DiffusionPipeline, ControlNetUnionModel, AutoencoderKL, UniPCMultistepScheduler, UNet2DConditionModel
|
| 81 |
+
from diffusers.utils import load_image
|
| 82 |
+
from PIL import Image
|
| 83 |
+
|
| 84 |
+
device = "cuda"
|
| 85 |
+
|
| 86 |
+
# Initialize the models and pipeline
|
| 87 |
+
controlnet = ControlNetUnionModel.from_pretrained(
|
| 88 |
+
"brad-twinkl/controlnet-union-sdxl-1.0-promax", torch_dtype=torch.float16
|
| 89 |
+
).to(device=device)
|
| 90 |
+
vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16).to(device=device)
|
| 91 |
+
|
| 92 |
+
model_id = "SG161222/RealVisXL_V5.0"
|
| 93 |
+
pipe = DiffusionPipeline.from_pretrained(
|
| 94 |
+
model_id,
|
| 95 |
+
torch_dtype=torch.float16,
|
| 96 |
+
vae=vae,
|
| 97 |
+
controlnet=controlnet,
|
| 98 |
+
custom_pipeline="mod_controlnet_tile_sr_sdxl",
|
| 99 |
+
use_safetensors=True,
|
| 100 |
+
variant="fp16",
|
| 101 |
+
).to(device)
|
| 102 |
+
|
| 103 |
+
unet = UNet2DConditionModel.from_pretrained(model_id, subfolder="unet", variant="fp16", use_safetensors=True)
|
| 104 |
+
|
| 105 |
+
#pipe.enable_model_cpu_offload() # << Enable this if you have limited VRAM
|
| 106 |
+
pipe.enable_vae_tiling() # << Enable this if you have limited VRAM
|
| 107 |
+
pipe.enable_vae_slicing() # << Enable this if you have limited VRAM
|
| 108 |
+
|
| 109 |
+
# Set selected scheduler
|
| 110 |
+
pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config)
|
| 111 |
+
|
| 112 |
+
# Load image
|
| 113 |
+
control_image = load_image("https://huggingface.co/datasets/DEVAIEXP/assets/resolve/main/1.jpg")
|
| 114 |
+
original_height = control_image.height
|
| 115 |
+
original_width = control_image.width
|
| 116 |
+
print(f"Current resolution: H:{original_height} x W:{original_width}")
|
| 117 |
+
|
| 118 |
+
# Pre-upscale image for tiling
|
| 119 |
+
resolution = 4096
|
| 120 |
+
tile_gaussian_sigma = 0.3
|
| 121 |
+
max_tile_size = 1024 # or 1280
|
| 122 |
+
|
| 123 |
+
current_size = max(control_image.size)
|
| 124 |
+
scale_factor = max(2, resolution / current_size)
|
| 125 |
+
new_size = (int(control_image.width * scale_factor), int(control_image.height * scale_factor))
|
| 126 |
+
image = control_image.resize(new_size, Image.LANCZOS)
|
| 127 |
+
|
| 128 |
+
# Update target height and width
|
| 129 |
+
target_height = image.height
|
| 130 |
+
target_width = image.width
|
| 131 |
+
print(f"Target resolution: H:{target_height} x W:{target_width}")
|
| 132 |
+
|
| 133 |
+
# Calculate overlap size
|
| 134 |
+
normal_tile_overlap, border_tile_overlap = pipe.calculate_overlap(target_width, target_height)
|
| 135 |
+
|
| 136 |
+
# Set other params
|
| 137 |
+
tile_weighting_method = pipe.TileWeightingMethod.COSINE.value
|
| 138 |
+
guidance_scale = 4
|
| 139 |
+
num_inference_steps = 35
|
| 140 |
+
denoising_strenght = 0.65
|
| 141 |
+
controlnet_strength = 1.0
|
| 142 |
+
prompt = "high-quality, noise-free edges, high quality, 4k, hd, 8k"
|
| 143 |
+
negative_prompt = "blurry, pixelated, noisy, low resolution, artifacts, poor details"
|
| 144 |
+
|
| 145 |
+
# Image generation
|
| 146 |
+
generated_image = pipe(
|
| 147 |
+
image=image,
|
| 148 |
+
control_image=control_image,
|
| 149 |
+
control_mode=[6],
|
| 150 |
+
controlnet_conditioning_scale=float(controlnet_strength),
|
| 151 |
+
prompt=prompt,
|
| 152 |
+
negative_prompt=negative_prompt,
|
| 153 |
+
normal_tile_overlap=normal_tile_overlap,
|
| 154 |
+
border_tile_overlap=border_tile_overlap,
|
| 155 |
+
height=target_height,
|
| 156 |
+
width=target_width,
|
| 157 |
+
original_size=(original_width, original_height),
|
| 158 |
+
target_size=(target_width, target_height),
|
| 159 |
+
guidance_scale=guidance_scale,
|
| 160 |
+
strength=float(denoising_strenght),
|
| 161 |
+
tile_weighting_method=tile_weighting_method,
|
| 162 |
+
max_tile_size=max_tile_size,
|
| 163 |
+
tile_gaussian_sigma=float(tile_gaussian_sigma),
|
| 164 |
+
num_inference_steps=num_inference_steps,
|
| 165 |
+
)["images"][0]
|
| 166 |
```
|
| 167 |
"""
|
| 168 |
|
|
|
|
| 169 |
# This function was copied and adapted from https://huggingface.co/spaces/gokaygokay/TileUpscalerV2, licensed under Apache 2.0.
|
| 170 |
def _adaptive_tile_size(image_size, base_tile_size=512, max_tile_size=1280):
|
| 171 |
"""
|
|
|
|
| 263 |
else:
|
| 264 |
raise AttributeError("Could not access latents of provided encoder_output")
|
| 265 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 266 |
class StableDiffusionXLControlNetTileSRPipeline(
|
| 267 |
DiffusionPipeline,
|
| 268 |
StableDiffusionMixin,
|
|
|
|
| 373 |
self.register_to_config(force_zeros_for_empty_prompt=force_zeros_for_empty_prompt)
|
| 374 |
self.register_to_config(requires_aesthetics_score=requires_aesthetics_score)
|
| 375 |
|
| 376 |
+
def calculate_overlap(self, width, height, base_overlap=128):
|
| 377 |
+
"""
|
| 378 |
+
Calculates dynamic overlap based on the image's aspect ratio.
|
| 379 |
+
|
| 380 |
+
Args:
|
| 381 |
+
width (int): Width of the image in pixels.
|
| 382 |
+
height (int): Height of the image in pixels.
|
| 383 |
+
base_overlap (int, optional): Base overlap value in pixels. Defaults to 128.
|
| 384 |
+
|
| 385 |
+
Returns:
|
| 386 |
+
tuple: A tuple containing:
|
| 387 |
+
- row_overlap (int): Overlap between tiles in consecutive rows.
|
| 388 |
+
- col_overlap (int): Overlap between tiles in consecutive columns.
|
| 389 |
+
"""
|
| 390 |
+
ratio = height / width
|
| 391 |
+
if ratio < 1: # Image is wider than tall
|
| 392 |
+
return base_overlap // 2, base_overlap
|
| 393 |
+
else: # Image is taller than wide
|
| 394 |
+
return base_overlap, base_overlap * 2
|
| 395 |
+
|
| 396 |
+
class TileWeightingMethod(Enum):
|
| 397 |
+
"""Mode in which the tile weights will be generated"""
|
| 398 |
+
|
| 399 |
+
COSINE = "Cosine"
|
| 400 |
+
GAUSSIAN = "Gaussian"
|
| 401 |
+
|
| 402 |
# Copied from diffusers.pipelines.stable_diffusion_xl.pipeline_stable_diffusion_xl.StableDiffusionXLPipeline.encode_prompt
|
| 403 |
def encode_prompt(
|
| 404 |
self,
|
|
|
|
| 459 |
the output of the pre-final layer will be used for computing the prompt embeddings.
|
| 460 |
"""
|
| 461 |
device = device or self._execution_device
|
| 462 |
+
|
| 463 |
# set lora scale so that monkey patched LoRA
|
| 464 |
# function of text encoder can correctly access it
|
| 465 |
if lora_scale is not None and isinstance(self, StableDiffusionXLLoraLoaderMixin):
|
|
|
|
| 682 |
if strength < 0 or strength > 1:
|
| 683 |
raise ValueError(f"The value of strength should in [0.0, 1.0] but is {strength}")
|
| 684 |
if num_inference_steps is None:
|
| 685 |
+
raise ValueError("`num_inference_steps` cannot be None.")
|
| 686 |
elif not isinstance(num_inference_steps, int) or num_inference_steps <= 0:
|
| 687 |
raise ValueError(
|
| 688 |
f"`num_inference_steps` has to be a positive integer but is {num_inference_steps} of type"
|
| 689 |
f" {type(num_inference_steps)}."
|
| 690 |
)
|
| 691 |
if normal_tile_overlap is None:
|
| 692 |
+
raise ValueError("`normal_tile_overlap` cannot be None.")
|
| 693 |
elif not isinstance(normal_tile_overlap, int) or normal_tile_overlap < 64:
|
| 694 |
raise ValueError(
|
| 695 |
f"`normal_tile_overlap` has to be greater than 64 but is {normal_tile_overlap} of type"
|
| 696 |
f" {type(normal_tile_overlap)}."
|
| 697 |
)
|
| 698 |
if border_tile_overlap is None:
|
| 699 |
+
raise ValueError("`border_tile_overlap` cannot be None.")
|
| 700 |
elif not isinstance(border_tile_overlap, int) or border_tile_overlap < 128:
|
| 701 |
raise ValueError(
|
| 702 |
f"`border_tile_overlap` has to be greater than 128 but is {border_tile_overlap} of type"
|
| 703 |
f" {type(border_tile_overlap)}."
|
| 704 |
)
|
| 705 |
if max_tile_size is None:
|
| 706 |
+
raise ValueError("`max_tile_size` cannot be None.")
|
| 707 |
elif not isinstance(max_tile_size, int) or max_tile_size not in(1024, 1280):
|
| 708 |
raise ValueError(
|
| 709 |
f"`max_tile_size` has to be in 1024 or 1280 but is {max_tile_size} of type"
|
| 710 |
f" {type(max_tile_size)}."
|
| 711 |
+
)
|
| 712 |
if tile_gaussian_sigma is None:
|
| 713 |
+
raise ValueError("`tile_gaussian_sigma` cannot be None.")
|
| 714 |
elif not isinstance(tile_gaussian_sigma, float) or tile_gaussian_sigma <= 0:
|
| 715 |
raise ValueError(
|
| 716 |
f"`tile_gaussian_sigma` has to be a positive float but is {tile_gaussian_sigma} of type"
|
| 717 |
f" {type(tile_gaussian_sigma)}."
|
| 718 |
)
|
| 719 |
if tile_weighting_method is None:
|
| 720 |
+
raise ValueError("`tile_weighting_method` cannot be None.")
|
| 721 |
+
elif not isinstance(tile_weighting_method, str) or tile_weighting_method not in [t.value for t in self.TileWeightingMethod]:
|
| 722 |
raise ValueError(
|
| 723 |
+
f"`tile_weighting_method` has to be a string in ({[t.value for t in self.TileWeightingMethod]}) but is {tile_weighting_method} of type"
|
| 724 |
f" {type(tile_weighting_method)}."
|
| 725 |
)
|
| 726 |
+
|
| 727 |
# Check `image`
|
| 728 |
is_compiled = hasattr(F, "scaled_dot_product_attention") and isinstance(
|
| 729 |
self.controlnet, torch._dynamo.eval_frame.OptimizedModule
|
|
|
|
| 1129 |
grid_cols = int(np.ceil((width - normal_tile_overlap) / (tile_width - normal_tile_overlap)))
|
| 1130 |
|
| 1131 |
return grid_rows, grid_cols
|
| 1132 |
+
|
| 1133 |
def prepare_tiles(
|
| 1134 |
self,
|
| 1135 |
grid_rows,
|
|
|
|
| 1170 |
- tile_row_overlaps (np.ndarray): Array of row overlaps for each tile.
|
| 1171 |
- tile_col_overlaps (np.ndarray): Array of column overlaps for each tile.
|
| 1172 |
"""
|
| 1173 |
+
|
| 1174 |
# Create arrays to store dynamic overlaps and weights
|
| 1175 |
tile_row_overlaps = np.full((grid_rows, grid_cols), normal_tile_overlap)
|
| 1176 |
tile_col_overlaps = np.full((grid_rows, grid_cols), normal_tile_overlap)
|
|
|
|
| 1204 |
sigma = tile_sigma * 1.2
|
| 1205 |
|
| 1206 |
# Calculate weights for the current tile
|
| 1207 |
+
if tile_weighting_method == self.TileWeightingMethod.COSINE.value:
|
| 1208 |
tile_weights[row, col] = self._generate_cosine_weights(
|
| 1209 |
tile_width=current_tile_width,
|
| 1210 |
tile_height=current_tile_height,
|
|
|
|
| 1459 |
original_size = original_size or (height, width)
|
| 1460 |
target_size = target_size or (height, width)
|
| 1461 |
negative_original_size = negative_original_size or original_size
|
| 1462 |
+
negative_target_size = negative_target_size or target_size
|
| 1463 |
control_type = [0 for _ in range(num_control_type)]
|
| 1464 |
control_type = torch.Tensor(control_type)
|
| 1465 |
self._guidance_scale = guidance_scale
|
|
|
|
| 1493 |
|
| 1494 |
# 2 Get tile width and tile height size
|
| 1495 |
tile_width, tile_height = _adaptive_tile_size((width, height), max_tile_size=max_tile_size)
|
| 1496 |
+
|
| 1497 |
+
# 2.1 Calculate the number of tiles needed
|
| 1498 |
+
grid_rows, grid_cols = self._get_num_tiles(height, width, tile_height, tile_width, normal_tile_overlap, border_tile_overlap)
|
| 1499 |
|
| 1500 |
# 2.2 Expand prompt to number of tiles
|
| 1501 |
if not isinstance(prompt, list):
|