Astridkraft commited on
Commit
a445173
·
verified ·
1 Parent(s): 87dbb73

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -9
app.py CHANGED
@@ -319,6 +319,9 @@ pipe_txt2img = None
319
  current_pipe_model_id = None
320
  pipe_img2img = None
321
 
 
 
 
322
  def load_txt2img(model_id):
323
  """Lädt das Text-to-Image Modell basierend auf der Auswahl"""
324
  global pipe_txt2img, current_pipe_model_id
@@ -334,7 +337,7 @@ def load_txt2img(model_id):
334
  print(f"📝 Beschreibung: {config['description']}")
335
 
336
  try:
337
- # VAE-Handling basierend auf Modellkonfiguration
338
  vae = None
339
  if config.get("requires_vae", False):
340
  print(f"🔧 Lade externe VAE: {config['vae_model']}")
@@ -356,7 +359,8 @@ def load_txt2img(model_id):
356
  "add_watermarker": False,
357
  "allow_pickle": True,
358
  }
359
-
 
360
  if model_id in SAFETENSORS_MODELS:
361
  model_params["use_safetensors"] = True
362
  print(f"ℹ️ Verwende safetensors für {model_id}")
@@ -378,7 +382,10 @@ def load_txt2img(model_id):
378
  model_id,
379
  **model_params
380
  ).to(device)
381
-
 
 
 
382
  print("⚙️ Konfiguriere Scheduler...")
383
 
384
  if pipe_txt2img.scheduler is None:
@@ -415,7 +422,8 @@ def load_txt2img(model_id):
415
 
416
  pipe_txt2img.enable_attention_slicing()
417
  print("✅ Attention Slicing aktiviert")
418
-
 
419
  if hasattr(pipe_txt2img, 'vae') and pipe_txt2img.vae is not None:
420
  try:
421
  pipe_txt2img.enable_vae_slicing()
@@ -487,7 +495,9 @@ def load_img2img():
487
  print("✅ Inpainting-Modell geladen und optimiert")
488
 
489
  return pipe_img2img
490
-
 
 
491
  # === NEUE CALLBACK-FUNKTIONEN FÜR FORTSCHRITT ===
492
  class TextToImageProgressCallback:
493
  def __init__(self, progress, total_steps):
@@ -523,6 +533,7 @@ class ImageToImageProgressCallback:
523
  progress_percent = (step / self.actual_total_steps) * 100
524
  self.progress(progress_percent / 100, desc="Generierung läuft...")
525
  return callback_kwargs
 
526
 
527
  # === NEUE FUNKTIONEN FÜR DIE FEATURES (ANGEPASST FÜR 3 MODI) ===
528
  def create_preview_image(image, bbox_coords, mode):
@@ -568,7 +579,7 @@ def create_preview_image(image, bbox_coords, mode):
568
  box_color = (128, 128, 128, 200)
569
  text_bg_color = (64, 64, 64, 160)
570
 
571
- # Skaliere Rahmendicke basierend auf Bildgröße
572
  border_width = max(8, image.width // 200) # Mindestens 8px, bei großen Bildern dicker
573
  draw.rectangle([0, 0, preview.width-1, preview.height-1],
574
  outline=border_color, width=border_width)
@@ -613,6 +624,7 @@ def update_live_preview(image, bbox_x1, bbox_y1, bbox_x2, bbox_y2, mode):
613
  bbox_coords = sort_coordinates(bbox_x1, bbox_y1, bbox_x2, bbox_y2)
614
 
615
  return create_preview_image(image, bbox_coords, mode)
 
616
 
617
  def process_image_upload(image):
618
  """Verarbeitet Bild-Upload und gibt Bild + Koordinaten zurück"""
@@ -634,6 +646,7 @@ def process_image_upload(image):
634
  print(f"Bild {width}x{height} -> Slider-Originalwerte: [{bbox_x1}, {bbox_y1}, {bbox_x2}, {bbox_y2}]")
635
 
636
  return preview, bbox_x1, bbox_y1, bbox_x2, bbox_y2
 
637
 
638
  # === FUNKTION FÜR SLIDER-UPDATE ===
639
  def update_slider_for_image(image):
@@ -718,6 +731,7 @@ def img_to_image(image, prompt, neg_prompt, strength, steps, guidance_scale,
718
  print(f"ℹ️ Kein manueller Negativ-Prompt, verwende nur automatischen: {combined_negative_prompt}")
719
 
720
  print(f"✅ Finaler kombinierter Negativ-Prompt: {combined_negative_prompt}")
 
721
 
722
  # ===== GESICHTS-SPEZIFISCHE BOOSTER FÜR NUR-GESICHT MODUS =====
723
  if mode == "face_only_change":
@@ -732,6 +746,7 @@ def img_to_image(image, prompt, neg_prompt, strength, steps, guidance_scale,
732
  print(f"👤 Benutzer hat bereits Gesichts-Booster im Prompt")
733
  else:
734
  enhanced_prompt = prompt
 
735
 
736
  # ===== HINTERGRUND-BOOSTER FÜR UMGEBUNGS-ÄNDERUNG =====
737
  if mode == "environment_change":
@@ -744,7 +759,10 @@ def img_to_image(image, prompt, neg_prompt, strength, steps, guidance_scale,
744
 
745
  print(f"🎯 Finaler Prompt für {mode}: {enhanced_prompt}")
746
 
 
 
747
  progress(0, desc="Starte Generierung mit ControlNet...")
 
748
 
749
  # ===== MODUS-SPEZIFISCHE EINSTELLUNGEN =====
750
  adj_strength = min(0.85, strength * 1.25)
@@ -786,7 +804,11 @@ def img_to_image(image, prompt, neg_prompt, strength, steps, guidance_scale,
786
  original_mask, # Originalmaske
787
  target_size=IMG_SIZE
788
  )
789
-
 
 
 
 
790
  controlnet_input = scaled_image # Verwende das skalierte Bild für ControlNet
791
  print(f"✅ Gemeinsame Skalierung abgeschlossen")
792
  print(f" Original: {image.size} → Skaliert: {scaled_image.size}")
@@ -1230,13 +1252,13 @@ def main_ui():
1230
  )
1231
  with gr.Column():
1232
  img_steps = gr.Slider(
1233
- minimum=10, maximum=100, value=35, step=1,
1234
  label="⚙️ Inferenz-Schritte",
1235
  info="Anzahl der Verarbeitungsschritte (25-45 für gute Ergebnisse)"
1236
  )
1237
  with gr.Column():
1238
  img_guidance = gr.Slider(
1239
- minimum=1.0, maximum=20.0, value=7.5, step=0.5,
1240
  label="🎛️ Prompt-Stärke",
1241
  info="Einfluss des Prompts auf das Ergebnis (6-10 für natürliche Ergebnisse)"
1242
  )
 
319
  current_pipe_model_id = None
320
  pipe_img2img = None
321
 
322
+
323
+ #Das Laden des Modells bedeutet, die trainierten Gewichte (Parameter) von der Festplatte zu lesen und
324
+ #im Arbeitsspeicher (RAM) und idealerweise im Grafikspeicher (VRAM) zu halten, damit sie für Berechnungen schnell verfügbar sind.
325
  def load_txt2img(model_id):
326
  """Lädt das Text-to-Image Modell basierend auf der Auswahl"""
327
  global pipe_txt2img, current_pipe_model_id
 
337
  print(f"📝 Beschreibung: {config['description']}")
338
 
339
  try:
340
+ # VAE-Handling basierend auf Modellkonfiguration (Realistic Vision hat kein VAE-der Autoencoder ist ein CNN)
341
  vae = None
342
  if config.get("requires_vae", False):
343
  print(f"🔧 Lade externe VAE: {config['vae_model']}")
 
359
  "add_watermarker": False,
360
  "allow_pickle": True,
361
  }
362
+
363
+ # Jetzt wird nicht mehr erzwungen wo nach Gewichten gesucht werden soll sondern gezielt mitgeteilt welche Gewichte gewählt wurden.
364
  if model_id in SAFETENSORS_MODELS:
365
  model_params["use_safetensors"] = True
366
  print(f"ℹ️ Verwende safetensors für {model_id}")
 
382
  model_id,
383
  **model_params
384
  ).to(device)
385
+
386
+
387
+ # Der Scheduler (z.B. DPM-Solver++ oder PNDM) ist der Algorithmus, der den Zeitplan für das schrittweise Entrauschen (Denoising)
388
+ # festlegt - er bestimmt, wie viele und welche Rauschschritte in welcher Reihenfolge abgearbeitet werden.
389
  print("⚙️ Konfiguriere Scheduler...")
390
 
391
  if pipe_txt2img.scheduler is None:
 
422
 
423
  pipe_txt2img.enable_attention_slicing()
424
  print("✅ Attention Slicing aktiviert")
425
+
426
+ # Attention Slicing ist Aufteilung der Attention-Matrix auf die Heads -> späteres concat
427
  if hasattr(pipe_txt2img, 'vae') and pipe_txt2img.vae is not None:
428
  try:
429
  pipe_txt2img.enable_vae_slicing()
 
495
  print("✅ Inpainting-Modell geladen und optimiert")
496
 
497
  return pipe_img2img
498
+
499
+ #Die Callback-Funktion wird von der Pipeline nach jedem Verarbeitungsschritt aufgerufen und erhält Informationen
500
+ #wie den aktuellen step und timestep. Diese nutzt der Progressbalken-Callback, um den Fortschritt zu berechnen und anzuzeigen.
501
  # === NEUE CALLBACK-FUNKTIONEN FÜR FORTSCHRITT ===
502
  class TextToImageProgressCallback:
503
  def __init__(self, progress, total_steps):
 
533
  progress_percent = (step / self.actual_total_steps) * 100
534
  self.progress(progress_percent / 100, desc="Generierung läuft...")
535
  return callback_kwargs
536
+
537
 
538
  # === NEUE FUNKTIONEN FÜR DIE FEATURES (ANGEPASST FÜR 3 MODI) ===
539
  def create_preview_image(image, bbox_coords, mode):
 
579
  box_color = (128, 128, 128, 200)
580
  text_bg_color = (64, 64, 64, 160)
581
 
582
+ # Skaliere Rahmendicke basierend auf Bildgröße (sonst bei großen Bildern ganz dünne Rahmen!)
583
  border_width = max(8, image.width // 200) # Mindestens 8px, bei großen Bildern dicker
584
  draw.rectangle([0, 0, preview.width-1, preview.height-1],
585
  outline=border_color, width=border_width)
 
624
  bbox_coords = sort_coordinates(bbox_x1, bbox_y1, bbox_x2, bbox_y2)
625
 
626
  return create_preview_image(image, bbox_coords, mode)
627
+
628
 
629
  def process_image_upload(image):
630
  """Verarbeitet Bild-Upload und gibt Bild + Koordinaten zurück"""
 
646
  print(f"Bild {width}x{height} -> Slider-Originalwerte: [{bbox_x1}, {bbox_y1}, {bbox_x2}, {bbox_y2}]")
647
 
648
  return preview, bbox_x1, bbox_y1, bbox_x2, bbox_y2
649
+
650
 
651
  # === FUNKTION FÜR SLIDER-UPDATE ===
652
  def update_slider_for_image(image):
 
731
  print(f"ℹ️ Kein manueller Negativ-Prompt, verwende nur automatischen: {combined_negative_prompt}")
732
 
733
  print(f"✅ Finaler kombinierter Negativ-Prompt: {combined_negative_prompt}")
734
+
735
 
736
  # ===== GESICHTS-SPEZIFISCHE BOOSTER FÜR NUR-GESICHT MODUS =====
737
  if mode == "face_only_change":
 
746
  print(f"👤 Benutzer hat bereits Gesichts-Booster im Prompt")
747
  else:
748
  enhanced_prompt = prompt
749
+
750
 
751
  # ===== HINTERGRUND-BOOSTER FÜR UMGEBUNGS-ÄNDERUNG =====
752
  if mode == "environment_change":
 
759
 
760
  print(f"🎯 Finaler Prompt für {mode}: {enhanced_prompt}")
761
 
762
+
763
+ #Zur Überbrückung bis von der Pipelines Infos kommen!
764
  progress(0, desc="Starte Generierung mit ControlNet...")
765
+
766
 
767
  # ===== MODUS-SPEZIFISCHE EINSTELLUNGEN =====
768
  adj_strength = min(0.85, strength * 1.25)
 
804
  original_mask, # Originalmaske
805
  target_size=IMG_SIZE
806
  )
807
+
808
+ #ControlNet ist ein paralleles Modell (CNN), das unveränderte Control-Maps (z. B. Tiefenkarten)
809
+ #verarbeitet und konditionierende Signale an das frozen UNet weiterleitet, um die Gesamtgeneration zu steuern,
810
+ #ohne pixelgenaue Manipulationen vorzunehmen. Es beeinflusst den Diffusionsprozess global/lokal durch Addition zu den Features.
811
+ #ControlNet-Bildgröße und Inpaint-Bildgröße müssen übereinstimmen!
812
  controlnet_input = scaled_image # Verwende das skalierte Bild für ControlNet
813
  print(f"✅ Gemeinsame Skalierung abgeschlossen")
814
  print(f" Original: {image.size} → Skaliert: {scaled_image.size}")
 
1252
  )
1253
  with gr.Column():
1254
  img_steps = gr.Slider(
1255
+ minimum=10, maximum=45, value=35, step=1,
1256
  label="⚙️ Inferenz-Schritte",
1257
  info="Anzahl der Verarbeitungsschritte (25-45 für gute Ergebnisse)"
1258
  )
1259
  with gr.Column():
1260
  img_guidance = gr.Slider(
1261
+ minimum=1.0, maximum=15.0, value=7.5, step=0.5,
1262
  label="🎛️ Prompt-Stärke",
1263
  info="Einfluss des Prompts auf das Ergebnis (6-10 für natürliche Ergebnisse)"
1264
  )