cobramv12 commited on
Commit
ba81970
·
verified ·
1 Parent(s): 219831b

Fix: Switch to Native Gradio SDK for ZeroGPU stability

Browse files
Files changed (1) hide show
  1. app.py +60 -67
app.py CHANGED
@@ -3,13 +3,12 @@ import os
3
  import gc
4
  import torch
5
 
6
- # --- PARCHES CRÍTICOS ---
7
  try:
8
  import gradio_client.utils as client_utils
9
- old_json_schema_to_python_type = client_utils._json_schema_to_python_type
10
  def patched_json_schema_to_python_type(schema, defs=None):
11
  if isinstance(schema, bool): return "Any"
12
- return old_json_schema_to_python_type(schema, defs)
13
  client_utils._json_schema_to_python_type = patched_json_schema_to_python_type
14
  except: pass
15
 
@@ -20,39 +19,35 @@ import tempfile
20
 
21
  # CONFIG
22
  SDXL_MODELS = {
23
- "CyberRealistic Pony (Recomendado)": "cyberdelia/CyberRealisticPony",
24
- "RealVisXL V4.0": "SG161222/RealVisXL_V4.0",
25
- "Juggernaut XL V9": "RunDiffusion/Juggernaut-XL-v9"
26
  }
27
 
28
  LTX_MODELS = {
29
- "LTX-Video (Standard)": "Lightricks/LTX-Video"
30
  }
31
 
32
  LTX_LORAS = {
33
  "Ninguno": "",
34
- "Real Nudity Alpha (NSFW)": "Lora-Daddy/Ltx2.3-real-nudity-early-alpha-30k-steps",
35
- "LTX Realism Boost": "strangerzonehf/LTX-Video-LoRA"
36
  }
37
 
38
- # --- FUNCIONES DE CARGA ---
39
- def load_t2i(model_id, is_img2img=False):
40
- from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline
41
- cls = StableDiffusionXLImg2ImgPipeline if is_img2img else StableDiffusionXLPipeline
42
- pipe = cls.from_pretrained(model_id, torch_dtype=torch.float16, use_safetensors=True, variant="fp16")
43
- return pipe
44
-
45
- def load_video(model_id):
46
- from diffusers import LTXPipeline
47
- pipe = LTXPipeline.from_pretrained(model_id, torch_dtype=torch.bfloat16)
48
- return pipe
49
 
50
  # --- GENERACIÓN ---
51
- @spaces.GPU(duration=100)
52
- def generate_t2i(prompt, neg, model_name, lora_id_custom, lora_scale, steps, cfg, w, h, init_img):
 
 
53
  model_id = SDXL_MODELS.get(model_name)
54
- is_img2img = init_img is not None
55
- pipe = load_t2i(model_id, is_img2img).to("cuda")
 
 
 
 
56
 
57
  if lora_id_custom:
58
  try:
@@ -60,90 +55,88 @@ def generate_t2i(prompt, neg, model_name, lora_id_custom, lora_scale, steps, cfg
60
  pipe.fuse_lora(lora_scale=lora_scale)
61
  except: pass
62
 
63
- kwargs = {"prompt": prompt, "negative_prompt": neg, "num_inference_steps": int(steps), "guidance_scale": cfg, "width": int(w), "height": int(h)}
64
- if is_img2img:
65
- kwargs["image"] = Image.fromarray(init_img).convert("RGB").resize((int(w), int(h)))
66
- kwargs.pop("width"); kwargs.pop("height")
67
- kwargs["strength"] = 0.6
68
-
69
- res = pipe(**kwargs).images[0]
70
- # Limpieza
71
  del pipe
72
- gc.collect()
73
- torch.cuda.empty_cache()
74
  return res
75
 
76
- @spaces.GPU(duration=200)
77
- def generate_video(prompt, model_name, lora_name, lora_custom, lora_scale, init_image, steps, cfg):
 
 
78
  from diffusers.utils import export_to_video
 
79
  model_id = LTX_MODELS.get(model_name)
80
  lora_id = lora_custom if lora_custom else LTX_LORAS.get(lora_name)
81
 
82
- pipe = load_video(model_id).to("cuda")
 
 
 
 
 
 
 
 
83
 
84
  if lora_id:
85
  try:
86
  pipe.load_lora_weights(lora_id)
87
  except: pass
88
 
89
- kwargs = {
90
- "prompt": prompt,
91
- "negative_prompt": "low quality, blurry, static",
92
- "num_frames": 49,
93
- "num_inference_steps": int(steps),
94
- "guidance_scale": cfg
95
- }
 
 
 
 
96
 
97
- if lora_id:
98
- kwargs["cross_attention_kwargs"] = {"scale": lora_scale}
99
-
100
- if init_image is not None:
101
- kwargs["image"] = Image.fromarray(init_image).convert("RGB").resize((768, 512))
102
-
103
- output = pipe(**kwargs)
104
  tmp = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
105
- export_to_video(output.frames[0], tmp.name, fps=24)
106
 
107
- # Limpieza profunda
108
  del pipe
109
- gc.collect()
110
- torch.cuda.empty_cache()
111
  return tmp.name
112
 
113
  # --- INTERFAZ ---
114
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="purple")) as demo:
115
- gr.HTML("<h1 style='text-align:center;'>🚀 Studio Privado v2.3 Pro</h1>")
116
 
117
  with gr.Tabs():
118
- with gr.Tab("🖼 Imagen / T2I"):
119
  with gr.Row():
120
  with gr.Column():
121
  t2i_p = gr.Textbox(label="Prompt", lines=3)
122
  t2i_n = gr.Textbox(label="Negativo", value="blurry, ugly")
123
- t2i_m = gr.Dropdown(choices=list(SDXL_MODELS.keys()), value="CyberRealistic Pony (Recomendado)", label="Modelo")
124
- t2i_lora = gr.Textbox(label="LoRA ID Personalizado (Opcional)")
125
  t2i_ls = gr.Slider(0, 1.5, 0.8, label="Peso LoRA")
126
  with gr.Row():
127
  t2i_w = gr.Slider(512, 1024, 1024, step=64, label="Ancho")
128
  t2i_h = gr.Slider(512, 1024, 1024, step=64, label="Alto")
129
  t2i_btn = gr.Button("GENERAR IMAGEN", variant="primary")
130
  t2i_out = gr.Image(label="Resultado")
131
- 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, gr.State(None)], t2i_out)
132
 
133
- with gr.Tab("🎬 Video / M-Sequence"):
134
  with gr.Row():
135
  with gr.Column():
136
  v_p = gr.Textbox(label="Video Prompt", lines=3)
137
- v_m = gr.Dropdown(choices=list(LTX_MODELS.keys()), value="LTX-Video (Standard)", label="Modelo de Video")
138
- v_lora = gr.Dropdown(choices=list(LTX_LORAS.keys()), value="Real Nudity Alpha (NSFW)", label="Seleccionar LoRA Video")
139
  v_lora_c = gr.Textbox(label="O ID LoRA Video personalizado")
140
  v_ls = gr.Slider(0, 1.5, 1.0, label="Peso LoRA Video")
141
- v_img = gr.Image(label="Imagen de Inicio (Opcional)", type="numpy")
142
  with gr.Row():
143
- v_steps = gr.Slider(10, 50, 30, step=1, label="Pasos")
144
- v_cfg = gr.Slider(1, 10, 3.5, label="Guidance")
145
  v_btn = gr.Button("GENERAR VIDEO", variant="primary")
146
  v_out = gr.Video(label="Resultado Video")
147
- v_btn.click(generate_video, [v_p, v_m, v_lora, v_lora_c, v_ls, v_img, v_steps, v_cfg], v_out)
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
+ # --- PARCHES ---
7
  try:
8
  import gradio_client.utils as client_utils
 
9
  def patched_json_schema_to_python_type(schema, defs=None):
10
  if isinstance(schema, bool): return "Any"
11
+ return client_utils._json_schema_to_python_type(schema, defs)
12
  client_utils._json_schema_to_python_type = patched_json_schema_to_python_type
13
  except: pass
14
 
 
19
 
20
  # CONFIG
21
  SDXL_MODELS = {
22
+ "CyberRealistic Pony (Pro)": "cyberdelia/CyberRealisticPony",
23
+ "RealVisXL V4.0": "SG161222/RealVisXL_V4.0"
 
24
  }
25
 
26
  LTX_MODELS = {
27
+ "LTX-Video (Optimizado)": "Lightricks/LTX-Video"
28
  }
29
 
30
  LTX_LORAS = {
31
  "Ninguno": "",
32
+ "Real Nudity Alpha (NSFW)": "Lora-Daddy/Ltx2.3-real-nudity-early-alpha-30k-steps"
 
33
  }
34
 
35
+ def flush():
36
+ gc.collect()
37
+ torch.cuda.empty_cache()
 
 
 
 
 
 
 
 
38
 
39
  # --- GENERACIÓN ---
40
+ @spaces.GPU(duration=120)
41
+ def generate_t2i(prompt, neg, model_name, lora_id_custom, lora_scale, steps, cfg, w, h):
42
+ flush()
43
+ from diffusers import StableDiffusionXLPipeline
44
  model_id = SDXL_MODELS.get(model_name)
45
+
46
+ pipe = StableDiffusionXLPipeline.from_pretrained(
47
+ model_id, torch_dtype=torch.float16, use_safetensors=True, variant="fp16",
48
+ low_cpu_mem_usage=True
49
+ )
50
+ pipe.to("cuda")
51
 
52
  if lora_id_custom:
53
  try:
 
55
  pipe.fuse_lora(lora_scale=lora_scale)
56
  except: pass
57
 
58
+ res = pipe(prompt=prompt, negative_prompt=neg, num_inference_steps=int(steps), guidance_scale=cfg, width=int(w), height=int(h)).images[0]
59
+
 
 
 
 
 
 
60
  del pipe
61
+ flush()
 
62
  return res
63
 
64
+ @spaces.GPU(duration=250)
65
+ def generate_video(prompt, model_name, lora_name, lora_custom, lora_scale, steps, cfg):
66
+ flush() # Limpiar todo antes de empezar
67
+ from diffusers import LTXPipeline
68
  from diffusers.utils import export_to_video
69
+
70
  model_id = LTX_MODELS.get(model_name)
71
  lora_id = lora_custom if lora_custom else LTX_LORAS.get(lora_name)
72
 
73
+ # CARGA OPTIMIZADA
74
+ pipe = LTXPipeline.from_pretrained(
75
+ model_id, torch_dtype=torch.bfloat16,
76
+ low_cpu_mem_usage=True
77
+ )
78
+ pipe.to("cuda")
79
+
80
+ # IMPORTANTE: Ahorro de memoria para video
81
+ pipe.enable_vae_slicing()
82
 
83
  if lora_id:
84
  try:
85
  pipe.load_lora_weights(lora_id)
86
  except: pass
87
 
88
+ # Generar video (Reducido a 33 frames para evitar timeout/OOM)
89
+ output = pipe(
90
+ prompt=prompt,
91
+ negative_prompt="low quality, blurry, static, distorted",
92
+ num_frames=33,
93
+ num_inference_steps=int(steps),
94
+ guidance_scale=cfg,
95
+ height=480,
96
+ width=704,
97
+ cross_attention_kwargs={"scale": lora_scale} if lora_id else None
98
+ )
99
 
 
 
 
 
 
 
 
100
  tmp = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
101
+ export_to_video(output.frames[0], tmp.name, fps=16)
102
 
 
103
  del pipe
104
+ flush()
 
105
  return tmp.name
106
 
107
  # --- INTERFAZ ---
108
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="purple")) as demo:
109
+ gr.HTML("<h1 style='text-align:center;'>🚀 Studio Privado v2.4 (Ultra-Stable)</h1>")
110
 
111
  with gr.Tabs():
112
+ with gr.Tab("🖼 Imagen"):
113
  with gr.Row():
114
  with gr.Column():
115
  t2i_p = gr.Textbox(label="Prompt", lines=3)
116
  t2i_n = gr.Textbox(label="Negativo", value="blurry, ugly")
117
+ t2i_m = gr.Dropdown(choices=list(SDXL_MODELS.keys()), value="CyberRealistic Pony (Pro)", label="Modelo")
118
+ t2i_lora = gr.Textbox(label="LoRA ID Opcional")
119
  t2i_ls = gr.Slider(0, 1.5, 0.8, label="Peso LoRA")
120
  with gr.Row():
121
  t2i_w = gr.Slider(512, 1024, 1024, step=64, label="Ancho")
122
  t2i_h = gr.Slider(512, 1024, 1024, step=64, label="Alto")
123
  t2i_btn = gr.Button("GENERAR IMAGEN", variant="primary")
124
  t2i_out = gr.Image(label="Resultado")
125
+ 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)
126
 
127
+ with gr.Tab("🎬 Video (LTX)"):
128
  with gr.Row():
129
  with gr.Column():
130
  v_p = gr.Textbox(label="Video Prompt", lines=3)
131
+ v_m = gr.Dropdown(choices=list(LTX_MODELS.keys()), value="LTX-Video (Optimizado)", label="Modelo")
132
+ v_lora = gr.Dropdown(choices=list(LTX_LORAS.keys()), value="Real Nudity Alpha (NSFW)", label="LoRA Video")
133
  v_lora_c = gr.Textbox(label="O ID LoRA Video personalizado")
134
  v_ls = gr.Slider(0, 1.5, 1.0, label="Peso LoRA Video")
 
135
  with gr.Row():
136
+ v_steps = gr.Slider(10, 40, 25, step=1, label="Pasos (25 recomendado)")
137
+ v_cfg = gr.Slider(1, 7, 3.5, label="Guidance")
138
  v_btn = gr.Button("GENERAR VIDEO", variant="primary")
139
  v_out = gr.Video(label="Resultado Video")
140
+ v_btn.click(generate_video, [v_p, v_m, v_lora, v_lora_c, v_ls, v_steps, v_cfg], v_out)
141
 
142
  demo.queue().launch(show_api=False, server_name="0.0.0.0", server_port=7860)