Update app.py
Browse files
app.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
from diffusers import StableDiffusionPipeline, StableDiffusionImg2ImgPipeline
|
| 3 |
from diffusers import StableDiffusionInpaintPipeline, AutoencoderKL
|
|
|
|
| 4 |
from controlnet_module import controlnet_processor
|
| 5 |
import torch
|
| 6 |
from PIL import Image, ImageDraw
|
|
@@ -23,7 +24,8 @@ MODEL_CONFIGS = {
|
|
| 23 |
"description": "Universal model, good all-rounder, reliable results",
|
| 24 |
"requires_vae": False,
|
| 25 |
"recommended_steps": 35,
|
| 26 |
-
"recommended_cfg": 7.5
|
|
|
|
| 27 |
},
|
| 28 |
"SG161222/Realistic_Vision_V6.0_B1_noVAE": {
|
| 29 |
"name": "👤 Realistic Vision V6.0 (Portraits)",
|
|
@@ -31,28 +33,32 @@ MODEL_CONFIGS = {
|
|
| 31 |
"requires_vae": True,
|
| 32 |
"vae_model": "stabilityai/sd-vae-ft-mse",
|
| 33 |
"recommended_steps": 40,
|
| 34 |
-
"recommended_cfg": 7.0
|
|
|
|
| 35 |
},
|
| 36 |
"RunDiffusion/Juggernaut-X-v10": {
|
| 37 |
"name": "🏢 Juggernaut X (Business)",
|
| 38 |
"description": "Ideal for corporate images, team photos, professional settings",
|
| 39 |
"requires_vae": False,
|
| 40 |
"recommended_steps": 35,
|
| 41 |
-
"recommended_cfg": 7.5
|
|
|
|
| 42 |
},
|
| 43 |
"Lykon/DreamShaper": {
|
| 44 |
"name": "🎨 DreamShaper (Artistic)",
|
| 45 |
"description": "Creative interpretations, artistic styles, illustrations",
|
| 46 |
"requires_vae": False,
|
| 47 |
"recommended_steps": 40,
|
| 48 |
-
"recommended_cfg": 8.0
|
|
|
|
| 49 |
},
|
| 50 |
"nitrosocke/redshift-diffusion": {
|
| 51 |
"name": "🖼️ Redshift Diffusion (Design)",
|
| 52 |
"description": "Clean CGI style, product visuals, design mockups",
|
| 53 |
"requires_vae": False,
|
| 54 |
"recommended_steps": 30,
|
| 55 |
-
"recommended_cfg": 8.5
|
|
|
|
| 56 |
}
|
| 57 |
}
|
| 58 |
|
|
@@ -68,7 +74,7 @@ def auto_negative_prompt(positive_prompt):
|
|
| 68 |
# Personen / Portraits
|
| 69 |
if any(w in p for w in ["person", "man", "woman", "face", "portrait", "team", "employee", "people", "crowd"]):
|
| 70 |
negatives.append(
|
| 71 |
-
"bad anatomy, malformed hands, extra fingers, uneven eyes, distorted face, unrealistic skin, mutated"
|
| 72 |
)
|
| 73 |
|
| 74 |
# Business / Corporate
|
|
@@ -162,7 +168,7 @@ def load_txt2img(model_id):
|
|
| 162 |
|
| 163 |
print(f"🔄 Lade Modell: {model_id}")
|
| 164 |
|
| 165 |
-
config = MODEL_CONFIGS[
|
| 166 |
print(f"📋 Modell-Konfiguration: {config['name']}")
|
| 167 |
print(f"📝 Beschreibung: {config['description']}")
|
| 168 |
|
|
@@ -171,59 +177,127 @@ def load_txt2img(model_id):
|
|
| 171 |
vae = None
|
| 172 |
if config.get("requires_vae", False):
|
| 173 |
print(f"🔧 Lade externe VAE: {config['vae_model']}")
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
|
| 180 |
-
# Modell laden
|
| 181 |
print(f"📥 Lade Hauptmodell von Hugging Face...")
|
| 182 |
pipe_txt2img = StableDiffusionPipeline.from_pretrained(
|
| 183 |
model_id,
|
| 184 |
-
|
| 185 |
-
safety_checker=None,
|
| 186 |
-
requires_safety_checker=False,
|
| 187 |
-
add_watermarker=False,
|
| 188 |
-
use_safetensors=True,
|
| 189 |
-
variant="fp16" if torch_dtype == torch.float16 else None,
|
| 190 |
-
vae=vae
|
| 191 |
).to(device)
|
| 192 |
|
| 193 |
-
#
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
|
| 201 |
# Optimierungen
|
| 202 |
pipe_txt2img.enable_attention_slicing()
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 206 |
|
| 207 |
current_pipe_model_id = model_id
|
| 208 |
print(f"✅ {config['name']} erfolgreich geladen")
|
|
|
|
|
|
|
| 209 |
print(f"⚙️ Empfohlene Einstellungen: Steps={config['recommended_steps']}, CFG={config['recommended_cfg']}")
|
| 210 |
|
| 211 |
return pipe_txt2img
|
| 212 |
|
| 213 |
except Exception as e:
|
| 214 |
-
print(f"❌ Fehler beim Laden von {model_id}: {e}")
|
|
|
|
|
|
|
| 215 |
print("🔄 Fallback auf SD 1.5...")
|
| 216 |
|
| 217 |
# Fallback auf Standard SD 1.5
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
|
| 228 |
def load_img2img():
|
| 229 |
global pipe_img2img
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
from diffusers import StableDiffusionPipeline, StableDiffusionImg2ImgPipeline
|
| 3 |
from diffusers import StableDiffusionInpaintPipeline, AutoencoderKL
|
| 4 |
+
from diffusers import DPMSolverMultistepScheduler, PNDMScheduler
|
| 5 |
from controlnet_module import controlnet_processor
|
| 6 |
import torch
|
| 7 |
from PIL import Image, ImageDraw
|
|
|
|
| 24 |
"description": "Universal model, good all-rounder, reliable results",
|
| 25 |
"requires_vae": False,
|
| 26 |
"recommended_steps": 35,
|
| 27 |
+
"recommended_cfg": 7.5,
|
| 28 |
+
"supports_fp16": True # Offizielles Modell hat FP16 Variante
|
| 29 |
},
|
| 30 |
"SG161222/Realistic_Vision_V6.0_B1_noVAE": {
|
| 31 |
"name": "👤 Realistic Vision V6.0 (Portraits)",
|
|
|
|
| 33 |
"requires_vae": True,
|
| 34 |
"vae_model": "stabilityai/sd-vae-ft-mse",
|
| 35 |
"recommended_steps": 40,
|
| 36 |
+
"recommended_cfg": 7.0,
|
| 37 |
+
"supports_fp16": False # Custom Model, keine FP16 Variante
|
| 38 |
},
|
| 39 |
"RunDiffusion/Juggernaut-X-v10": {
|
| 40 |
"name": "🏢 Juggernaut X (Business)",
|
| 41 |
"description": "Ideal for corporate images, team photos, professional settings",
|
| 42 |
"requires_vae": False,
|
| 43 |
"recommended_steps": 35,
|
| 44 |
+
"recommended_cfg": 7.5,
|
| 45 |
+
"supports_fp16": False # Custom Model, keine FP16 Variante
|
| 46 |
},
|
| 47 |
"Lykon/DreamShaper": {
|
| 48 |
"name": "🎨 DreamShaper (Artistic)",
|
| 49 |
"description": "Creative interpretations, artistic styles, illustrations",
|
| 50 |
"requires_vae": False,
|
| 51 |
"recommended_steps": 40,
|
| 52 |
+
"recommended_cfg": 8.0,
|
| 53 |
+
"supports_fp16": False # Custom Model, keine FP16 Variante
|
| 54 |
},
|
| 55 |
"nitrosocke/redshift-diffusion": {
|
| 56 |
"name": "🖼️ Redshift Diffusion (Design)",
|
| 57 |
"description": "Clean CGI style, product visuals, design mockups",
|
| 58 |
"requires_vae": False,
|
| 59 |
"recommended_steps": 30,
|
| 60 |
+
"recommended_cfg": 8.5,
|
| 61 |
+
"supports_fp16": False # Custom Model, keine FP16 Variante
|
| 62 |
}
|
| 63 |
}
|
| 64 |
|
|
|
|
| 74 |
# Personen / Portraits
|
| 75 |
if any(w in p for w in ["person", "man", "woman", "face", "portrait", "team", "employee", "people", "crowd"]):
|
| 76 |
negatives.append(
|
| 77 |
+
"bad anatomy, malformed hands, extra fingers, uneven eyes, distorted face, unrealistic skin, mutated, deformed, ugly, disfigured, poorly drawn face, missing limbs, extra limbs, fused fingers, too many fingers, long neck"
|
| 78 |
)
|
| 79 |
|
| 80 |
# Business / Corporate
|
|
|
|
| 168 |
|
| 169 |
print(f"🔄 Lade Modell: {model_id}")
|
| 170 |
|
| 171 |
+
config = MODEL_CONFIGS.get(model_id, MODEL_CONFIGS["runwayml/stable-diffusion-v1-5"])
|
| 172 |
print(f"📋 Modell-Konfiguration: {config['name']}")
|
| 173 |
print(f"📝 Beschreibung: {config['description']}")
|
| 174 |
|
|
|
|
| 177 |
vae = None
|
| 178 |
if config.get("requires_vae", False):
|
| 179 |
print(f"🔧 Lade externe VAE: {config['vae_model']}")
|
| 180 |
+
try:
|
| 181 |
+
vae = AutoencoderKL.from_pretrained(
|
| 182 |
+
config["vae_model"],
|
| 183 |
+
torch_dtype=torch_dtype
|
| 184 |
+
).to(device)
|
| 185 |
+
print("✅ VAE erfolgreich geladen")
|
| 186 |
+
except Exception as vae_error:
|
| 187 |
+
print(f"⚠️ Fehler beim Laden der VAE: {vae_error}")
|
| 188 |
+
print("ℹ️ Versuche ohne VAE weiter...")
|
| 189 |
+
vae = None
|
| 190 |
+
|
| 191 |
+
# Modellparameter basierend auf Modelltyp
|
| 192 |
+
model_params = {
|
| 193 |
+
"torch_dtype": torch_dtype,
|
| 194 |
+
"safety_checker": None,
|
| 195 |
+
"requires_safety_checker": False,
|
| 196 |
+
"add_watermarker": False,
|
| 197 |
+
"use_safetensors": True,
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
# NUR FP16 Variante laden wenn Modell sie unterstützt UND wir auf GPU sind
|
| 201 |
+
if config.get("supports_fp16", False) and torch_dtype == torch.float16:
|
| 202 |
+
model_params["variant"] = "fp16"
|
| 203 |
+
print("ℹ️ Verwende FP16 Variante")
|
| 204 |
+
else:
|
| 205 |
+
print("ℹ️ Verwende Standard Variante (kein FP16)")
|
| 206 |
+
|
| 207 |
+
# VAE nur wenn nicht None
|
| 208 |
+
if vae is not None:
|
| 209 |
+
model_params["vae"] = vae
|
| 210 |
|
|
|
|
| 211 |
print(f"📥 Lade Hauptmodell von Hugging Face...")
|
| 212 |
pipe_txt2img = StableDiffusionPipeline.from_pretrained(
|
| 213 |
model_id,
|
| 214 |
+
**model_params
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
).to(device)
|
| 216 |
|
| 217 |
+
# SICHERER SCHEDULER-HANDLING
|
| 218 |
+
print("⚙️ Konfiguriere Scheduler...")
|
| 219 |
+
|
| 220 |
+
# Prüfe ob Scheduler existiert
|
| 221 |
+
if pipe_txt2img.scheduler is None:
|
| 222 |
+
print("⚠️ Scheduler ist None, setze Standard-Scheduler")
|
| 223 |
+
pipe_txt2img.scheduler = PNDMScheduler.from_pretrained(
|
| 224 |
+
model_id,
|
| 225 |
+
subfolder="scheduler"
|
| 226 |
+
)
|
| 227 |
+
|
| 228 |
+
# Versuche DPM-Solver zu verwenden (bessere Ergebnisse)
|
| 229 |
+
try:
|
| 230 |
+
# Hole die Scheduler-Konfiguration
|
| 231 |
+
if hasattr(pipe_txt2img.scheduler, 'config'):
|
| 232 |
+
scheduler_config = pipe_txt2img.scheduler.config
|
| 233 |
+
else:
|
| 234 |
+
# Fallback-Konfiguration für Scheduler
|
| 235 |
+
scheduler_config = {
|
| 236 |
+
"beta_start": 0.00085,
|
| 237 |
+
"beta_end": 0.012,
|
| 238 |
+
"beta_schedule": "scaled_linear",
|
| 239 |
+
"num_train_timesteps": 1000,
|
| 240 |
+
"prediction_type": "epsilon",
|
| 241 |
+
"steps_offset": 1
|
| 242 |
+
}
|
| 243 |
+
print("⚠️ Keine Scheduler-Konfig gefunden, verwende Standard")
|
| 244 |
+
|
| 245 |
+
# Setze DPM-Solver Scheduler
|
| 246 |
+
pipe_txt2img.scheduler = DPMSolverMultistepScheduler.from_config(
|
| 247 |
+
scheduler_config,
|
| 248 |
+
use_karras_sigmas=True,
|
| 249 |
+
algorithm_type="sde-dpmsolver++"
|
| 250 |
+
)
|
| 251 |
+
print("✅ DPM-Solver Multistep Scheduler konfiguriert")
|
| 252 |
+
|
| 253 |
+
except Exception as scheduler_error:
|
| 254 |
+
print(f"⚠️ Konnte DPM-Scheduler nicht setzen: {scheduler_error}")
|
| 255 |
+
print("ℹ️ Verwende Standard-Scheduler weiter")
|
| 256 |
+
# Behalte den aktuellen Scheduler bei
|
| 257 |
|
| 258 |
# Optimierungen
|
| 259 |
pipe_txt2img.enable_attention_slicing()
|
| 260 |
+
print("✅ Attention Slicing aktiviert")
|
| 261 |
+
|
| 262 |
+
# VAE Slicing nur wenn VAE existiert
|
| 263 |
+
if hasattr(pipe_txt2img, 'vae') and pipe_txt2img.vae is not None:
|
| 264 |
+
try:
|
| 265 |
+
pipe_txt2img.enable_vae_slicing()
|
| 266 |
+
if hasattr(pipe_txt2img.vae, 'enable_slicing'):
|
| 267 |
+
pipe_txt2img.vae.enable_slicing()
|
| 268 |
+
print("✅ VAE Slicing aktiviert")
|
| 269 |
+
except Exception as vae_slice_error:
|
| 270 |
+
print(f"⚠️ VAE Slicing nicht möglich: {vae_slice_error}")
|
| 271 |
|
| 272 |
current_pipe_model_id = model_id
|
| 273 |
print(f"✅ {config['name']} erfolgreich geladen")
|
| 274 |
+
print(f"📊 Modell-Dtype: {pipe_txt2img.dtype}")
|
| 275 |
+
print(f"📊 Scheduler: {type(pipe_txt2img.scheduler).__name__}")
|
| 276 |
print(f"⚙️ Empfohlene Einstellungen: Steps={config['recommended_steps']}, CFG={config['recommended_cfg']}")
|
| 277 |
|
| 278 |
return pipe_txt2img
|
| 279 |
|
| 280 |
except Exception as e:
|
| 281 |
+
print(f"❌ Fehler beim Laden von {model_id}: {str(e)[:200]}...")
|
| 282 |
+
import traceback
|
| 283 |
+
traceback.print_exc()
|
| 284 |
print("🔄 Fallback auf SD 1.5...")
|
| 285 |
|
| 286 |
# Fallback auf Standard SD 1.5
|
| 287 |
+
try:
|
| 288 |
+
pipe_txt2img = StableDiffusionPipeline.from_pretrained(
|
| 289 |
+
"runwayml/stable-diffusion-v1-5",
|
| 290 |
+
torch_dtype=torch_dtype,
|
| 291 |
+
use_safetensors=True,
|
| 292 |
+
).to(device)
|
| 293 |
+
pipe_txt2img.enable_attention_slicing()
|
| 294 |
+
current_pipe_model_id = "runwayml/stable-diffusion-v1-5"
|
| 295 |
+
print("✅ Fallback auf SD 1.5 erfolgreich")
|
| 296 |
+
|
| 297 |
+
return pipe_txt2img
|
| 298 |
+
except Exception as fallback_error:
|
| 299 |
+
print(f"❌ Auch Fallback fehlgeschlagen: {fallback_error}")
|
| 300 |
+
raise
|
| 301 |
|
| 302 |
def load_img2img():
|
| 303 |
global pipe_img2img
|