Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -7,8 +7,6 @@ import time
|
|
| 7 |
import os
|
| 8 |
import tempfile
|
| 9 |
import random
|
| 10 |
-
import threading
|
| 11 |
-
import queue
|
| 12 |
|
| 13 |
# === OPTIMIERTE EINSTELLUNGEN ===
|
| 14 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
|
@@ -17,22 +15,6 @@ IMG_SIZE = 512
|
|
| 17 |
|
| 18 |
print(f"Running on: {device}")
|
| 19 |
|
| 20 |
-
# === GLOBALE FLAGS FÜR INTERRUPT ===
|
| 21 |
-
current_txt2img_task_id = None
|
| 22 |
-
current_img2img_task_id = None
|
| 23 |
-
cancel_txt2img = False
|
| 24 |
-
cancel_img2img = False
|
| 25 |
-
interrupt_queue = queue.Queue()
|
| 26 |
-
|
| 27 |
-
def interrupt_monitor(task_id, is_txt2img):
|
| 28 |
-
"""Überwacht Cancel-Flags in einem separaten Thread und löst Interrupt aus"""
|
| 29 |
-
global cancel_txt2img, cancel_img2img
|
| 30 |
-
while True:
|
| 31 |
-
if (is_txt2img and cancel_txt2img) or (not is_txt2img and cancel_img2img):
|
| 32 |
-
print(f"🛑 Interrupt ausgelöst für Task ID: {task_id}")
|
| 33 |
-
interrupt_queue.put(("interrupt", task_id))
|
| 34 |
-
break
|
| 35 |
-
time.sleep(0.1) # Polling-Intervall
|
| 36 |
|
| 37 |
# === GESICHTSMASKEN-FUNKTIONEN ===
|
| 38 |
def create_face_mask(image, bbox_coords):
|
|
@@ -125,28 +107,13 @@ def load_img2img():
|
|
| 125 |
|
| 126 |
# === FUNKTIONEN ===
|
| 127 |
def text_to_image(prompt, steps, guidance_scale):
|
| 128 |
-
global current_txt2img_task_id, cancel_txt2img
|
| 129 |
-
task_id = random.randint(0, 2**32 - 1) # Eindeutige Task-ID
|
| 130 |
try:
|
| 131 |
if not prompt or not prompt.strip():
|
| 132 |
return None
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
if current_txt2img_task_id is not None:
|
| 136 |
-
print(f"🛑 Cancel vorheriger Text-to-Image Task (ID: {current_txt2img_task_id})")
|
| 137 |
-
cancel_txt2img = True
|
| 138 |
-
time.sleep(1.0) # Wartezeit für CPU
|
| 139 |
-
|
| 140 |
-
current_txt2img_task_id = task_id
|
| 141 |
-
cancel_txt2img = False
|
| 142 |
-
print(f"Starting generation for: {prompt} (Task ID: {task_id})")
|
| 143 |
start_time = time.time()
|
| 144 |
|
| 145 |
-
# Starte Interrupt-Monitor in einem separaten Thread
|
| 146 |
-
monitor_thread = threading.Thread(target=interrupt_monitor, args=(task_id, True))
|
| 147 |
-
monitor_thread.daemon = True
|
| 148 |
-
monitor_thread.start()
|
| 149 |
-
|
| 150 |
pipe = load_txt2img()
|
| 151 |
|
| 152 |
# ZUFÄLLIGER SEED für Variation
|
|
@@ -154,14 +121,6 @@ def text_to_image(prompt, steps, guidance_scale):
|
|
| 154 |
generator = torch.Generator(device=device).manual_seed(seed)
|
| 155 |
print(f"🎲 Using seed: {seed}")
|
| 156 |
|
| 157 |
-
# Prüfe Interrupt-Queue während der Generierung
|
| 158 |
-
for step in range(steps):
|
| 159 |
-
if not interrupt_queue.empty():
|
| 160 |
-
action, interrupted_task_id = interrupt_queue.get()
|
| 161 |
-
if action == "interrupt" and interrupted_task_id == task_id:
|
| 162 |
-
raise RuntimeError("Task interrupted by user")
|
| 163 |
-
time.sleep(0.01) # Kurze Pause für Queue-Prüfung
|
| 164 |
-
|
| 165 |
image = pipe(
|
| 166 |
prompt=prompt,
|
| 167 |
height=IMG_SIZE,
|
|
@@ -173,52 +132,25 @@ def text_to_image(prompt, steps, guidance_scale):
|
|
| 173 |
|
| 174 |
end_time = time.time()
|
| 175 |
print(f"✅ Bild generiert in {end_time - start_time:.2f} Sekunden")
|
| 176 |
-
current_txt2img_task_id = None
|
| 177 |
|
| 178 |
return image
|
| 179 |
|
| 180 |
-
except RuntimeError as e:
|
| 181 |
-
if "interrupt" in str(e).lower():
|
| 182 |
-
print(f"🛑 Generierung unterbrochen (Task ID: {task_id})")
|
| 183 |
-
current_txt2img_task_id = None
|
| 184 |
-
return None
|
| 185 |
-
print(f"❌ Fehler: {e}")
|
| 186 |
-
import traceback
|
| 187 |
-
traceback.print_exc()
|
| 188 |
-
current_txt2img_task_id = None
|
| 189 |
-
return None
|
| 190 |
except Exception as e:
|
| 191 |
print(f"❌ Fehler: {e}")
|
| 192 |
import traceback
|
| 193 |
traceback.print_exc()
|
| 194 |
-
current_txt2img_task_id = None
|
| 195 |
return None
|
| 196 |
|
| 197 |
def img_to_image(image, prompt, neg_prompt, strength, steps, guidance_scale, face_preserve, bbox_x1, bbox_y1, bbox_x2, bbox_y2):
|
| 198 |
-
global current_img2img_task_id, cancel_img2img
|
| 199 |
-
task_id = random.randint(0, 2**32 - 1) # Eindeutige Task-ID
|
| 200 |
try:
|
| 201 |
if image is None:
|
| 202 |
return None
|
| 203 |
|
| 204 |
-
|
| 205 |
-
if current_img2img_task_id is not None:
|
| 206 |
-
print(f"🛑 Cancel vorheriger Image-to-Image Task (ID: {current_img2img_task_id})")
|
| 207 |
-
cancel_img2img = True
|
| 208 |
-
time.sleep(1.0) # Wartezeit für CPU
|
| 209 |
-
|
| 210 |
-
current_img2img_task_id = task_id
|
| 211 |
-
cancel_img2img = False
|
| 212 |
-
print(f"🧩 Img2Img Start → Strength: {strength}, Steps: {steps}, Guidance: {guidance_scale} (Task ID: {task_id})")
|
| 213 |
print(f"Prompt: {prompt}")
|
| 214 |
print(f"Gesicht beibehalten: {face_preserve}")
|
| 215 |
start_time = time.time()
|
| 216 |
|
| 217 |
-
# Starte Interrupt-Monitor in einem separaten Thread
|
| 218 |
-
monitor_thread = threading.Thread(target=interrupt_monitor, args=(task_id, False))
|
| 219 |
-
monitor_thread.daemon = True
|
| 220 |
-
monitor_thread.start()
|
| 221 |
-
|
| 222 |
pipe = load_img2img()
|
| 223 |
img_resized = image.convert("RGB").resize((IMG_SIZE, IMG_SIZE))
|
| 224 |
|
|
@@ -260,14 +192,6 @@ def img_to_image(image, prompt, neg_prompt, strength, steps, guidance_scale, fac
|
|
| 260 |
mask = None
|
| 261 |
|
| 262 |
# --- PIPELINE-AUFRUF ---
|
| 263 |
-
# Prüfe Interrupt-Queue während der Generierung
|
| 264 |
-
for step in range(int(steps)):
|
| 265 |
-
if not interrupt_queue.empty():
|
| 266 |
-
action, interrupted_task_id = interrupt_queue.get()
|
| 267 |
-
if action == "interrupt" and interrupted_task_id == task_id:
|
| 268 |
-
raise RuntimeError("Task interrupted by user")
|
| 269 |
-
time.sleep(0.01) # Kurze Pause für Queue-Prüfung
|
| 270 |
-
|
| 271 |
result = pipe(
|
| 272 |
prompt=prompt,
|
| 273 |
negative_prompt=neg_prompt,
|
|
@@ -281,7 +205,6 @@ def img_to_image(image, prompt, neg_prompt, strength, steps, guidance_scale, fac
|
|
| 281 |
|
| 282 |
end_time = time.time()
|
| 283 |
print(f"✅ Bild transformiert in {end_time - start_time:.2f} Sekunden")
|
| 284 |
-
current_img2img_task_id = None
|
| 285 |
|
| 286 |
generated_image = result.images[0]
|
| 287 |
|
|
@@ -298,21 +221,10 @@ def img_to_image(image, prompt, neg_prompt, strength, steps, guidance_scale, fac
|
|
| 298 |
|
| 299 |
return saved_image
|
| 300 |
|
| 301 |
-
except RuntimeError as e:
|
| 302 |
-
if "interrupt" in str(e).lower():
|
| 303 |
-
print(f"🛑 Generierung unterbrochen (Task ID: {task_id})")
|
| 304 |
-
current_img2img_task_id = None
|
| 305 |
-
return None
|
| 306 |
-
print(f"❌ Fehler: {e}")
|
| 307 |
-
import traceback
|
| 308 |
-
traceback.print_exc()
|
| 309 |
-
current_img2img_task_id = None
|
| 310 |
-
return None
|
| 311 |
except Exception as e:
|
| 312 |
print(f"❌ Fehler: {e}")
|
| 313 |
import traceback
|
| 314 |
traceback.print_exc()
|
| 315 |
-
current_img2img_task_id = None
|
| 316 |
return None
|
| 317 |
|
| 318 |
def update_bbox_from_image(image):
|
|
@@ -455,7 +367,6 @@ with gr.Blocks() as app:
|
|
| 455 |
)
|
| 456 |
|
| 457 |
# === APP START ===
|
| 458 |
-
app.queue(max_size=5)
|
| 459 |
app.launch(
|
| 460 |
share=True,
|
| 461 |
server_name="0.0.0.0",
|
|
|
|
| 7 |
import os
|
| 8 |
import tempfile
|
| 9 |
import random
|
|
|
|
|
|
|
| 10 |
|
| 11 |
# === OPTIMIERTE EINSTELLUNGEN ===
|
| 12 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
|
|
|
| 15 |
|
| 16 |
print(f"Running on: {device}")
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
# === GESICHTSMASKEN-FUNKTIONEN ===
|
| 20 |
def create_face_mask(image, bbox_coords):
|
|
|
|
| 107 |
|
| 108 |
# === FUNKTIONEN ===
|
| 109 |
def text_to_image(prompt, steps, guidance_scale):
|
|
|
|
|
|
|
| 110 |
try:
|
| 111 |
if not prompt or not prompt.strip():
|
| 112 |
return None
|
| 113 |
+
|
| 114 |
+
print(f"Starting generation for: {prompt}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
start_time = time.time()
|
| 116 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
pipe = load_txt2img()
|
| 118 |
|
| 119 |
# ZUFÄLLIGER SEED für Variation
|
|
|
|
| 121 |
generator = torch.Generator(device=device).manual_seed(seed)
|
| 122 |
print(f"🎲 Using seed: {seed}")
|
| 123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
image = pipe(
|
| 125 |
prompt=prompt,
|
| 126 |
height=IMG_SIZE,
|
|
|
|
| 132 |
|
| 133 |
end_time = time.time()
|
| 134 |
print(f"✅ Bild generiert in {end_time - start_time:.2f} Sekunden")
|
|
|
|
| 135 |
|
| 136 |
return image
|
| 137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
except Exception as e:
|
| 139 |
print(f"❌ Fehler: {e}")
|
| 140 |
import traceback
|
| 141 |
traceback.print_exc()
|
|
|
|
| 142 |
return None
|
| 143 |
|
| 144 |
def img_to_image(image, prompt, neg_prompt, strength, steps, guidance_scale, face_preserve, bbox_x1, bbox_y1, bbox_x2, bbox_y2):
|
|
|
|
|
|
|
| 145 |
try:
|
| 146 |
if image is None:
|
| 147 |
return None
|
| 148 |
|
| 149 |
+
print(f"🧩 Img2Img Start → Strength: {strength}, Steps: {steps}, Guidance: {guidance_scale}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
print(f"Prompt: {prompt}")
|
| 151 |
print(f"Gesicht beibehalten: {face_preserve}")
|
| 152 |
start_time = time.time()
|
| 153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
pipe = load_img2img()
|
| 155 |
img_resized = image.convert("RGB").resize((IMG_SIZE, IMG_SIZE))
|
| 156 |
|
|
|
|
| 192 |
mask = None
|
| 193 |
|
| 194 |
# --- PIPELINE-AUFRUF ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
result = pipe(
|
| 196 |
prompt=prompt,
|
| 197 |
negative_prompt=neg_prompt,
|
|
|
|
| 205 |
|
| 206 |
end_time = time.time()
|
| 207 |
print(f"✅ Bild transformiert in {end_time - start_time:.2f} Sekunden")
|
|
|
|
| 208 |
|
| 209 |
generated_image = result.images[0]
|
| 210 |
|
|
|
|
| 221 |
|
| 222 |
return saved_image
|
| 223 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
except Exception as e:
|
| 225 |
print(f"❌ Fehler: {e}")
|
| 226 |
import traceback
|
| 227 |
traceback.print_exc()
|
|
|
|
| 228 |
return None
|
| 229 |
|
| 230 |
def update_bbox_from_image(image):
|
|
|
|
| 367 |
)
|
| 368 |
|
| 369 |
# === APP START ===
|
|
|
|
| 370 |
app.launch(
|
| 371 |
share=True,
|
| 372 |
server_name="0.0.0.0",
|