cobramv12 commited on
Commit
0e3aefb
·
verified ·
1 Parent(s): 14f69e1

Fix: Switch to Native Gradio SDK for ZeroGPU stability

Browse files
Files changed (1) hide show
  1. app.py +53 -54
app.py CHANGED
@@ -3,7 +3,7 @@ import os
3
  import gc
4
  import torch
5
 
6
- # --- PATCH GRADIO RECURSION ---
7
  try:
8
  import gradio_client.utils as client_utils
9
  if not hasattr(client_utils, "_old_json_schema_to_python_type"):
@@ -19,43 +19,47 @@ import gradio as gr
19
  from PIL import Image
20
  import tempfile
21
 
22
- # CONFIG MODELOS Y LORAS
23
  MODELS = {
24
- "Pony Diffusion V6 XL (Ultra Realismo)": "cyberdelia/CyberRealisticPony",
25
- "RealVisXL V4.0 (Fotografía)": "SG161222/RealVisXL_V4.0"
26
  }
27
 
28
  LORAS = {
29
  "Ninguno": "",
30
- "💎 NSFW: Real Nudity (Anatomía)": "Lora-Daddy/Ltx2.3-real-nudity-early-alpha-30k-steps",
31
  "📜 DOCS: ID Card / Passport": "j0rdan/passport-sdxl",
32
- "🔫 WEAPONS: Tactical Gear & Guns": "Ostris/SDXL_LoRA_Test",
33
- "✍️ TEXT: Typography Fix": "ntc/Typography-SDXL"
34
  }
35
 
36
- LTX_MODELS = {"LTX-Video Pro": "Lightricks/LTX-Video"}
37
-
38
  def flush():
39
  gc.collect()
40
- torch.cuda.empty_cache()
 
41
 
42
- # --- MOTORES ---
43
- @spaces.GPU(duration=150)
44
  def process_image(prompt, neg, model_name, lora_name, lora_id_custom, lora_scale, steps, cfg, w, h, init_img=None, strength=0.6):
45
  flush()
 
46
  from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline
47
- model_id = MODELS.get(model_name)
48
 
49
- # Carga base
50
- pipe = StableDiffusionXLPipeline.from_pretrained(
51
- model_id, torch_dtype=torch.float16, variant="fp16", low_cpu_mem_usage=True
52
- ).to("cuda")
53
 
54
- # Inyectar Calidad Pony si es necesario
55
  if "Pony" in model_name:
56
  prompt = f"score_9, score_8_up, score_7_up, {prompt}"
57
 
58
- # Cargar LoRA
 
 
 
 
 
 
 
 
59
  lora_id = lora_id_custom if lora_id_custom else LORAS.get(lora_name)
60
  if lora_id:
61
  try:
@@ -64,29 +68,33 @@ def process_image(prompt, neg, model_name, lora_name, lora_id_custom, lora_scale
64
  except: pass
65
 
66
  if init_img is not None:
67
- # Modo Image-to-Image (Modificación)
68
  pipe_i2i = StableDiffusionXLImg2ImgPipeline.from_pipe(pipe)
69
  res = pipe_i2i(prompt=prompt, negative_prompt=neg, image=init_img, strength=strength, num_inference_steps=int(steps), guidance_scale=cfg).images[0]
70
  del pipe_i2i
71
  else:
72
- # Modo Text-to-Image (Creación)
73
  res = pipe(prompt=prompt, negative_prompt=neg, num_inference_steps=int(steps), guidance_scale=cfg, width=int(w), height=int(h)).images[0]
74
 
75
  del pipe
76
  flush()
77
  return res
78
 
 
79
  @spaces.GPU(duration=250)
80
  def process_video(prompt, init_img, steps, cfg):
81
  flush()
82
  from diffusers import LTXPipeline
83
  from diffusers.utils import export_to_video
84
 
85
- pipe = LTXPipeline.from_pretrained("Lightricks/LTX-Video", torch_dtype=torch.bfloat16, low_cpu_mem_usage=True).to("cuda")
 
 
 
 
 
86
  pipe.enable_vae_slicing()
87
 
88
  kwargs = {
89
- "prompt": prompt,
90
  "negative_prompt": "low quality, blurry, static, ugly",
91
  "num_inference_steps": int(steps),
92
  "guidance_scale": cfg,
@@ -106,44 +114,35 @@ def process_video(prompt, init_img, steps, cfg):
106
  flush()
107
  return tmp.name
108
 
109
- # --- UI ---
110
- with gr.Blocks(theme=gr.themes.Default(primary_hue="blue", secondary_hue="indigo")) as demo:
111
- gr.HTML("<h1 style='text-align:center;'>🌌 Omni-Studio Pro v3.0</h1>")
112
 
113
  with gr.Tabs():
114
- with gr.Tab("🎨 Imagen (Crear / Modificar)"):
115
  with gr.Row():
116
- with gr.Column(scale=1):
117
- prompt = gr.Textbox(label="Prompt Principal", placeholder="Escribe lo que quieres ver...", lines=3)
118
- neg = gr.Textbox(label="Negativo", value="blurry, ugly, distorted, lowres")
119
- with gr.Row():
120
- model = gr.Dropdown(choices=list(MODELS.keys()), value=list(MODELS.keys())[0], label="Motor")
121
- category = gr.Dropdown(choices=list(LORAS.keys()), value="Ninguno", label="Especialidad (LoRA)")
122
- with gr.Row():
123
- l_custom = gr.Textbox(label="LoRA ID Personalizado")
124
- l_scale = gr.Slider(0, 2.0, 0.8, label="Fuerza LoRA")
125
  with gr.Row():
126
- w = gr.Slider(512, 1024, 1024, step=64, label="Ancho")
127
- h = gr.Slider(512, 1024, 1024, step=64, label="Alto")
128
- img_input = gr.Image(label="Imagen Base (Opcional para Modificar)", type="pil")
129
- strength = gr.Slider(0.1, 0.9, 0.6, label="Fuerza de Modificación (I2I)")
130
- btn_i = gr.Button("🚀 GENERAR / TRANSFORMAR", variant="primary")
131
- with gr.Column(scale=1):
132
- out_i = gr.Image(label="Resultado")
133
 
134
- with gr.Tab("🎥 Video (T2V / I2V)"):
135
  with gr.Row():
136
  with gr.Column():
137
- v_prompt = gr.Textbox(label="Video Prompt", lines=3)
138
- v_input = gr.Image(label="Imagen Inicial (Opcional)", type="pil")
139
- with gr.Row():
140
- v_steps = gr.Slider(10, 40, 25, step=1, label="Pasos")
141
- v_cfg = gr.Slider(1, 7, 3.5, label="Guidance")
142
- btn_v = gr.Button("🎬 GENERAR VIDEO", variant="primary")
143
- with gr.Column():
144
- out_v = gr.Video(label="Resultado Video")
145
 
146
- btn_i.click(process_image, [prompt, neg, model, category, l_custom, l_scale, gr.Number(value=30, visible=False), gr.Number(value=7, visible=False), w, h, img_input, strength], out_i)
147
- btn_v.click(process_video, [v_prompt, v_input, v_steps, v_cfg], out_v)
148
 
149
  demo.queue().launch(show_api=False, server_name="0.0.0.0", server_port=7860)
 
3
  import gc
4
  import torch
5
 
6
+ # --- PARCHE DE GRADIO ---
7
  try:
8
  import gradio_client.utils as client_utils
9
  if not hasattr(client_utils, "_old_json_schema_to_python_type"):
 
19
  from PIL import Image
20
  import tempfile
21
 
22
+ # CONFIG
23
  MODELS = {
24
+ "Pony Diffusion V6 XL": "cyberdelia/CyberRealisticPony",
25
+ "RealVisXL V4.0": "SG161222/RealVisXL_V4.0"
26
  }
27
 
28
  LORAS = {
29
  "Ninguno": "",
30
+ "💎 NSFW: Real Nudity": "Lora-Daddy/Ltx2.3-real-nudity-early-alpha-30k-steps",
31
  "📜 DOCS: ID Card / Passport": "j0rdan/passport-sdxl",
32
+ "🔫 WEAPONS: Tactical Gear": "Ostris/SDXL_LoRA_Test",
33
+ "✍️ TEXT: Typography": "ntc/Typography-SDXL"
34
  }
35
 
 
 
36
  def flush():
37
  gc.collect()
38
+ if torch.cuda.is_available():
39
+ torch.cuda.empty_cache()
40
 
41
+ # --- MOTOR DE IMAGEN ---
42
+ @spaces.GPU(duration=120)
43
  def process_image(prompt, neg, model_name, lora_name, lora_id_custom, lora_scale, steps, cfg, w, h, init_img=None, strength=0.6):
44
  flush()
45
+ # Importación local para ahorrar RAM
46
  from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline
 
47
 
48
+ model_id = MODELS.get(model_name)
 
 
 
49
 
50
+ # Inyectar tags de calidad Pony
51
  if "Pony" in model_name:
52
  prompt = f"score_9, score_8_up, score_7_up, {prompt}"
53
 
54
+ # Carga con bajo consumo de CPU
55
+ pipe = StableDiffusionXLPipeline.from_pretrained(
56
+ model_id, torch_dtype=torch.float16, variant="fp16", use_safetensors=True,
57
+ low_cpu_mem_usage=True
58
+ ).to("cuda")
59
+
60
+ # Activar offload para ahorrar RAM
61
+ pipe.enable_model_cpu_offload()
62
+
63
  lora_id = lora_id_custom if lora_id_custom else LORAS.get(lora_name)
64
  if lora_id:
65
  try:
 
68
  except: pass
69
 
70
  if init_img is not None:
 
71
  pipe_i2i = StableDiffusionXLImg2ImgPipeline.from_pipe(pipe)
72
  res = pipe_i2i(prompt=prompt, negative_prompt=neg, image=init_img, strength=strength, num_inference_steps=int(steps), guidance_scale=cfg).images[0]
73
  del pipe_i2i
74
  else:
 
75
  res = pipe(prompt=prompt, negative_prompt=neg, num_inference_steps=int(steps), guidance_scale=cfg, width=int(w), height=int(h)).images[0]
76
 
77
  del pipe
78
  flush()
79
  return res
80
 
81
+ # --- MOTOR DE VIDEO ---
82
  @spaces.GPU(duration=250)
83
  def process_video(prompt, init_img, steps, cfg):
84
  flush()
85
  from diffusers import LTXPipeline
86
  from diffusers.utils import export_to_video
87
 
88
+ pipe = LTXPipeline.from_pretrained(
89
+ "Lightricks/LTX-Video", torch_dtype=torch.bfloat16,
90
+ low_cpu_mem_usage=True
91
+ ).to("cuda")
92
+
93
+ pipe.enable_model_cpu_offload()
94
  pipe.enable_vae_slicing()
95
 
96
  kwargs = {
97
+ "prompt": f"score_9, {prompt}",
98
  "negative_prompt": "low quality, blurry, static, ugly",
99
  "num_inference_steps": int(steps),
100
  "guidance_scale": cfg,
 
114
  flush()
115
  return tmp.name
116
 
117
+ # --- INTERFAZ ---
118
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
119
+ gr.HTML("<h1 style='text-align:center;'>🌌 Omni-Studio v3.1 (Power-Optimized)</h1>")
120
 
121
  with gr.Tabs():
122
+ with gr.Tab("🎨 Imagen"):
123
  with gr.Row():
124
+ with gr.Column():
125
+ p = gr.Textbox(label="Prompt", lines=3)
126
+ n = gr.Textbox(label="Negativo", value="blurry, lowres")
127
+ m = gr.Dropdown(choices=list(MODELS.keys()), value=list(MODELS.keys())[0], label="Motor")
128
+ l = gr.Dropdown(choices=list(LORAS.keys()), value="Ninguno", label="LoRA")
 
 
 
 
129
  with gr.Row():
130
+ w = gr.Slider(512, 1024, 832, step=64, label="Ancho")
131
+ h = gr.Slider(512, 1024, 1216, step=64, label="Alto")
132
+ img_in = gr.Image(label="Imagen Base (Opcional)", type="pil")
133
+ str_i = gr.Slider(0.1, 0.9, 0.6, label="Fuerza Mod")
134
+ btn_i = gr.Button("GENERAR IMAGEN", variant="primary")
135
+ out_i = gr.Image(label="Resultado")
 
136
 
137
+ with gr.Tab("🎥 Video"):
138
  with gr.Row():
139
  with gr.Column():
140
+ vp = gr.Textbox(label="Video Prompt", lines=3)
141
+ vin = gr.Image(label="Imagen Inicial (Opcional)", type="pil")
142
+ btn_v = gr.Button("GENERAR VIDEO", variant="primary")
143
+ out_v = gr.Video(label="Resultado Video")
 
 
 
 
144
 
145
+ btn_i.click(process_image, [p, n, m, l, gr.Textbox(visible=False), gr.Number(value=0.8, visible=False), gr.Number(value=30, visible=False), gr.Number(value=7, visible=False), w, h, img_in, str_i], out_i)
146
+ btn_v.click(process_video, [vp, vin, gr.Number(value=25, visible=False), gr.Number(value=3.5, visible=False)], out_v)
147
 
148
  demo.queue().launch(show_api=False, server_name="0.0.0.0", server_port=7860)