Spaces:
Runtime error
Runtime error
Upload 3 files
Browse files
app.py
CHANGED
|
@@ -29,7 +29,8 @@ from diffusers import (
|
|
| 29 |
try:
|
| 30 |
import spaces
|
| 31 |
|
| 32 |
-
|
|
|
|
| 33 |
except Exception: # lokal / eigene GPU
|
| 34 |
|
| 35 |
def gpu_decorator(fn):
|
|
@@ -42,8 +43,11 @@ except Exception: # lokal / eigene GPU
|
|
| 42 |
BASE_MODEL = os.environ.get("BASE_MODEL", "stable-diffusion-v1-5/stable-diffusion-v1-5")
|
| 43 |
CONTROLNET_REPO = "monster-labs/control_v1p_sd15_qrcode_monster"
|
| 44 |
CONTROLNET_SUBFOLDER = "v2" # v2 ist deutlich besser als v1
|
| 45 |
-
|
| 46 |
-
|
|
|
|
|
|
|
|
|
|
| 47 |
GRAY = (128, 128, 128) # #808080 – laut Model Card ideal zum "Verschmelzen"
|
| 48 |
MAX_SEED = 2**31 - 1
|
| 49 |
|
|
@@ -67,21 +71,24 @@ SCHEDULERS = {
|
|
| 67 |
controlnet = ControlNetModel.from_pretrained(
|
| 68 |
CONTROLNET_REPO,
|
| 69 |
subfolder=CONTROLNET_SUBFOLDER,
|
| 70 |
-
|
| 71 |
)
|
| 72 |
|
| 73 |
pipe = StableDiffusionControlNetImg2ImgPipeline.from_pretrained(
|
| 74 |
BASE_MODEL,
|
| 75 |
controlnet=controlnet,
|
| 76 |
-
|
| 77 |
safety_checker=None,
|
| 78 |
requires_safety_checker=False,
|
| 79 |
)
|
| 80 |
pipe.scheduler = DPMSolverMultistepScheduler.from_config(
|
| 81 |
pipe.scheduler.config, use_karras_sigmas=True, algorithm_type="dpmsolver++"
|
| 82 |
)
|
| 83 |
-
|
| 84 |
-
|
|
|
|
|
|
|
|
|
|
| 85 |
pipe.enable_vae_tiling()
|
| 86 |
pipe.enable_attention_slicing()
|
| 87 |
|
|
@@ -152,7 +159,13 @@ def generate(
|
|
| 152 |
control_image = make_qr_image(qr_content, size, ERROR_LEVELS[error_level_name])
|
| 153 |
init = prepare_init_image(init_image, size)
|
| 154 |
|
| 155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
|
| 157 |
result = pipe(
|
| 158 |
prompt=prompt,
|
|
|
|
| 29 |
try:
|
| 30 |
import spaces
|
| 31 |
|
| 32 |
+
# Der erste Call schiebt ~5,7 GB Gewichte auf die Karte - deshalb großzügig.
|
| 33 |
+
gpu_decorator = spaces.GPU(duration=120)
|
| 34 |
except Exception: # lokal / eigene GPU
|
| 35 |
|
| 36 |
def gpu_decorator(fn):
|
|
|
|
| 43 |
BASE_MODEL = os.environ.get("BASE_MODEL", "stable-diffusion-v1-5/stable-diffusion-v1-5")
|
| 44 |
CONTROLNET_REPO = "monster-labs/control_v1p_sd15_qrcode_monster"
|
| 45 |
CONTROLNET_SUBFOLDER = "v2" # v2 ist deutlich besser als v1
|
| 46 |
+
# Auf ZeroGPU ist beim Import noch keine GPU sichtbar ("Can't initialize NVML").
|
| 47 |
+
# Deshalb nicht auf torch.cuda.is_available() beim Start vertrauen.
|
| 48 |
+
IS_ZERO_GPU = os.environ.get("SPACES_ZERO_GPU", "").lower() in ("true", "1")
|
| 49 |
+
HAS_CUDA = IS_ZERO_GPU or torch.cuda.is_available()
|
| 50 |
+
DTYPE = torch.float16 if HAS_CUDA else torch.float32
|
| 51 |
GRAY = (128, 128, 128) # #808080 – laut Model Card ideal zum "Verschmelzen"
|
| 52 |
MAX_SEED = 2**31 - 1
|
| 53 |
|
|
|
|
| 71 |
controlnet = ControlNetModel.from_pretrained(
|
| 72 |
CONTROLNET_REPO,
|
| 73 |
subfolder=CONTROLNET_SUBFOLDER,
|
| 74 |
+
dtype=DTYPE, # torch_dtype ist ab diffusers 1.0 entfernt
|
| 75 |
)
|
| 76 |
|
| 77 |
pipe = StableDiffusionControlNetImg2ImgPipeline.from_pretrained(
|
| 78 |
BASE_MODEL,
|
| 79 |
controlnet=controlnet,
|
| 80 |
+
dtype=DTYPE,
|
| 81 |
safety_checker=None,
|
| 82 |
requires_safety_checker=False,
|
| 83 |
)
|
| 84 |
pipe.scheduler = DPMSolverMultistepScheduler.from_config(
|
| 85 |
pipe.scheduler.config, use_karras_sigmas=True, algorithm_type="dpmsolver++"
|
| 86 |
)
|
| 87 |
+
|
| 88 |
+
# Auf ZeroGPU darf CUDA erst innerhalb von @spaces.GPU angefasst werden -
|
| 89 |
+
# dort verschiebt generate() die Pipeline. Sonst gleich beim Start.
|
| 90 |
+
if HAS_CUDA and not IS_ZERO_GPU:
|
| 91 |
+
pipe.to("cuda")
|
| 92 |
pipe.enable_vae_tiling()
|
| 93 |
pipe.enable_attention_slicing()
|
| 94 |
|
|
|
|
| 159 |
control_image = make_qr_image(qr_content, size, ERROR_LEVELS[error_level_name])
|
| 160 |
init = prepare_init_image(init_image, size)
|
| 161 |
|
| 162 |
+
device = "cuda" if HAS_CUDA else "cpu"
|
| 163 |
+
if IS_ZERO_GPU:
|
| 164 |
+
# Erst hier ist die ZeroGPU zugewiesen. Kein attention_slicing /
|
| 165 |
+
# vae_tiling: die H200 hat reichlich VRAM, beides würde nur bremsen.
|
| 166 |
+
pipe.to("cuda")
|
| 167 |
+
|
| 168 |
+
generator = torch.Generator(device=device).manual_seed(seed)
|
| 169 |
|
| 170 |
result = pipe(
|
| 171 |
prompt=prompt,
|