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):
|