cobramv12 commited on
Commit
14f69e1
verified
1 Parent(s): 6f0f4ea

Fix: Switch to Native Gradio SDK for ZeroGPU stability

Browse files
Files changed (1) hide show
  1. app.py +84 -79
app.py CHANGED
@@ -3,102 +3,102 @@ import os
3
  import gc
4
  import torch
5
 
6
- # --- PARCHE CR脥TICO (FIX RECURSION ERROR) ---
7
  try:
8
  import gradio_client.utils as client_utils
9
  if not hasattr(client_utils, "_old_json_schema_to_python_type"):
10
  client_utils._old_json_schema_to_python_type = client_utils._json_schema_to_python_type
11
-
12
  def patched_json_schema_to_python_type(schema, defs=None):
13
  if isinstance(schema, bool): return "Any"
14
  return client_utils._old_json_schema_to_python_type(schema, defs)
15
-
16
  client_utils._json_schema_to_python_type = patched_json_schema_to_python_type
17
- print("Gradio Patch v2.5 Applied (Recursion Safe)")
18
- except Exception as e:
19
- print(f"Patch Error: {e}")
20
 
21
  import spaces
22
  import gradio as gr
23
  from PIL import Image
24
  import tempfile
25
 
26
- # CONFIG
27
- SDXL_MODELS = {
28
- "CyberRealistic Pony (Pro)": "cyberdelia/CyberRealisticPony",
29
- "RealVisXL V4.0": "SG161222/RealVisXL_V4.0"
30
  }
31
 
32
- LTX_MODELS = {
33
- "LTX-Video (Optimizado)": "Lightricks/LTX-Video"
34
- }
35
-
36
- LTX_LORAS = {
37
  "Ninguno": "",
38
- "Real Nudity Alpha (NSFW)": "Lora-Daddy/Ltx2.3-real-nudity-early-alpha-30k-steps"
 
 
 
39
  }
40
 
 
 
41
  def flush():
42
  gc.collect()
43
  torch.cuda.empty_cache()
44
 
45
- # --- GENERACI脫N ---
46
- @spaces.GPU(duration=120)
47
- def generate_t2i(prompt, neg, model_name, lora_id_custom, lora_scale, steps, cfg, w, h):
48
  flush()
49
- from diffusers import StableDiffusionXLPipeline
50
- model_id = SDXL_MODELS.get(model_name)
51
 
 
52
  pipe = StableDiffusionXLPipeline.from_pretrained(
53
- model_id, torch_dtype=torch.float16, use_safetensors=True, variant="fp16",
54
- low_cpu_mem_usage=True
55
- )
56
- pipe.to("cuda")
57
 
58
- if lora_id_custom:
 
 
 
 
 
 
59
  try:
60
- pipe.load_lora_weights(lora_id_custom)
61
  pipe.fuse_lora(lora_scale=lora_scale)
62
  except: pass
63
-
64
- res = pipe(prompt=prompt, negative_prompt=neg, num_inference_steps=int(steps), guidance_scale=cfg, width=int(w), height=int(h)).images[0]
 
 
 
 
 
 
 
65
 
66
  del pipe
67
  flush()
68
  return res
69
 
70
  @spaces.GPU(duration=250)
71
- def generate_video(prompt, model_name, lora_name, lora_custom, lora_scale, steps, cfg):
72
  flush()
73
  from diffusers import LTXPipeline
74
  from diffusers.utils import export_to_video
75
 
76
- model_id = LTX_MODELS.get(model_name)
77
- lora_id = lora_custom if lora_custom else LTX_LORAS.get(lora_name)
78
-
79
- pipe = LTXPipeline.from_pretrained(
80
- model_id, torch_dtype=torch.bfloat16,
81
- low_cpu_mem_usage=True
82
- )
83
- pipe.to("cuda")
84
  pipe.enable_vae_slicing()
85
 
86
- if lora_id:
87
- try:
88
- pipe.load_lora_weights(lora_id)
89
- except: pass
90
-
91
- output = pipe(
92
- prompt=prompt,
93
- negative_prompt="low quality, blurry, static, distorted",
94
- num_frames=33,
95
- num_inference_steps=int(steps),
96
- guidance_scale=cfg,
97
- height=480,
98
- width=704,
99
- cross_attention_kwargs={"scale": lora_scale} if lora_id else None
100
- )
101
 
 
 
 
 
102
  tmp = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
103
  export_to_video(output.frames[0], tmp.name, fps=16)
104
 
@@ -106,39 +106,44 @@ def generate_video(prompt, model_name, lora_name, lora_custom, lora_scale, steps
106
  flush()
107
  return tmp.name
108
 
109
- # --- INTERFAZ ---
110
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="purple")) as demo:
111
- gr.HTML("<h1 style='text-align:center;'>馃殌 Studio Privado v2.5 PRO</h1>")
112
 
113
  with gr.Tabs():
114
- with gr.Tab("馃柤 Imagen"):
115
  with gr.Row():
116
- with gr.Column():
117
- t2i_p = gr.Textbox(label="Prompt", lines=3)
118
- t2i_n = gr.Textbox(label="Negativo", value="blurry, ugly")
119
- t2i_m = gr.Dropdown(choices=list(SDXL_MODELS.keys()), value="CyberRealistic Pony (Pro)", label="Modelo")
120
- t2i_lora = gr.Textbox(label="LoRA ID Opcional")
121
- t2i_ls = gr.Slider(0, 1.5, 0.8, label="Peso LoRA")
122
  with gr.Row():
123
- t2i_w = gr.Slider(512, 1024, 1024, step=64, label="Ancho")
124
- t2i_h = gr.Slider(512, 1024, 1024, step=64, label="Alto")
125
- t2i_btn = gr.Button("GENERAR IMAGEN", variant="primary")
126
- t2i_out = gr.Image(label="Resultado")
127
- t2i_btn.click(generate_t2i, [t2i_p, t2i_n, t2i_m, t2i_lora, t2i_ls, gr.Number(value=30, visible=False), gr.Number(value=7, visible=False), t2i_w, t2i_h], t2i_out)
128
-
129
- with gr.Tab("馃幀 Video (LTX)"):
 
 
 
 
 
 
 
 
130
  with gr.Row():
131
  with gr.Column():
132
- v_p = gr.Textbox(label="Video Prompt", lines=3)
133
- v_m = gr.Dropdown(choices=list(LTX_MODELS.keys()), value="LTX-Video (Optimizado)", label="Modelo")
134
- v_lora = gr.Dropdown(choices=list(LTX_LORAS.keys()), value="Real Nudity Alpha (NSFW)", label="LoRA Video")
135
- v_lora_c = gr.Textbox(label="O ID LoRA Video personalizado")
136
- v_ls = gr.Slider(0, 1.5, 1.0, label="Peso LoRA Video")
137
  with gr.Row():
138
- v_steps = gr.Slider(10, 40, 25, step=1, label="Pasos (25 recomendado)")
139
  v_cfg = gr.Slider(1, 7, 3.5, label="Guidance")
140
- v_btn = gr.Button("GENERAR VIDEO", variant="primary")
141
- v_out = gr.Video(label="Resultado Video")
142
- v_btn.click(generate_video, [v_p, v_m, v_lora, v_lora_c, v_ls, v_steps, v_cfg], v_out)
 
 
 
143
 
144
  demo.queue().launch(show_api=False, server_name="0.0.0.0", server_port=7860)
 
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"):
10
  client_utils._old_json_schema_to_python_type = client_utils._json_schema_to_python_type
 
11
  def patched_json_schema_to_python_type(schema, defs=None):
12
  if isinstance(schema, bool): return "Any"
13
  return client_utils._old_json_schema_to_python_type(schema, defs)
 
14
  client_utils._json_schema_to_python_type = patched_json_schema_to_python_type
15
+ except: pass
 
 
16
 
17
  import spaces
18
  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:
62
+ pipe.load_lora_weights(lora_id)
63
  pipe.fuse_lora(lora_scale=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,
93
+ "num_frames": 33,
94
+ "width": 704,
95
+ "height": 480
96
+ }
 
 
 
 
 
 
97
 
98
+ if init_img is not None:
99
+ kwargs["image"] = init_img
100
+
101
+ output = pipe(**kwargs)
102
  tmp = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
103
  export_to_video(output.frames[0], tmp.name, fps=16)
104
 
 
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)