import sys try: import audioop except ImportError: try: import audioop_lts as audioop sys.modules["audioop"] = audioop except ImportError: pass import spaces import gradio as gr import torch import numpy as np from PIL import Image import tempfile, os from huggingface_hub import hf_hub_download # ─── CONFIGURACIÓN DE MODELOS ────────────────────────────────────────────────── BASE_MODEL = "cyberdelia/CyberRealisticPony" LTX_MODEL = "Lightricks/LTX-Video" DEFAULT_LORA = "John6666/nsfw-master-flux-lora-merged" LTX_NSFW_LORA = "Lora-Daddy/Ltx2.3-real-nudity-early-alpha-30k-steps" pipe_t2i = None pipe_i2i = None pipe_video = None NEG_DEFAULT = "blurry, low quality, bad anatomy, deformed, ugly, watermark, text" # ─── LOADERS ─────────────────────────────────────────────────────────────────── def load_t2i(lora_id=None, lora_scale=1.0): global pipe_t2i from diffusers import StableDiffusionXLPipeline if pipe_t2i is None: pipe_t2i = StableDiffusionXLPipeline.from_pretrained( BASE_MODEL, torch_dtype=torch.float16, use_safetensors=True, variant="fp16" ) if lora_id: try: pipe_t2i.unload_lora_weights() pipe_t2i.load_lora_weights(lora_id) pipe_t2i.fuse_lora(lora_scale=lora_scale) except: pass return pipe_t2i def load_i2i(lora_id=None, lora_scale=1.0): global pipe_i2i from diffusers import StableDiffusionXLImg2ImgPipeline if pipe_i2i is None: pipe_i2i = StableDiffusionXLImg2ImgPipeline.from_pretrained( BASE_MODEL, torch_dtype=torch.float16, use_safetensors=True, variant="fp16" ) if lora_id: try: pipe_i2i.unload_lora_weights() pipe_i2i.load_lora_weights(lora_id) pipe_i2i.fuse_lora(lora_scale=lora_scale) except: pass return pipe_i2i def load_video(): global pipe_video from diffusers import LTXPipeline if pipe_video is None: pipe_video = LTXPipeline.from_pretrained(LTX_MODEL, torch_dtype=torch.bfloat16) try: pipe_video.load_lora_weights(LTX_NSFW_LORA) except: pass return pipe_video # ─── FUNCIONES ───────────────────────────────────────────────────────────────── @spaces.GPU(duration=120) def generate_t2i(prompt, neg, lora_id, lora_scale, steps, cfg, w, h, seed): pipe = load_t2i(lora_id if lora_id else None, lora_scale).to("cuda") gen = torch.Generator("cuda").manual_seed(int(seed)) img = pipe(prompt=prompt, negative_prompt=neg, num_inference_steps=int(steps), guidance_scale=cfg, width=int(w), height=int(h), generator=gen).images[0] pipe.to("cpu"); torch.cuda.empty_cache() return img @spaces.GPU(duration=120) def generate_i2i(prompt, neg, init_image, strength, lora_id, lora_scale, steps, cfg, seed): if init_image is None: return None pipe = load_i2i(lora_id if lora_id else None, lora_scale).to("cuda") gen = torch.Generator("cuda").manual_seed(int(seed)) img = Image.fromarray(init_image).convert("RGB").resize((1024, 1024)) res = pipe(prompt=prompt, negative_prompt=neg, image=img, strength=strength, num_inference_steps=int(steps), guidance_scale=cfg, generator=gen).images[0] pipe.to("cpu"); torch.cuda.empty_cache() return res @spaces.GPU(duration=200) def generate_video(prompt, neg, init_image, num_frames, fps, steps, lora_scale, seed): from diffusers.utils import export_to_video pipe = load_video().to("cuda") gen = torch.Generator("cuda").manual_seed(int(seed)) kwargs = {"prompt": prompt, "negative_prompt": neg, "num_frames": int(num_frames), "num_inference_steps": int(steps), "generator": gen} if init_image is not None: kwargs["image"] = Image.fromarray(init_image).convert("RGB").resize((768, 512)) if lora_scale > 0: kwargs["cross_attention_kwargs"] = {"scale": lora_scale} output = pipe(**kwargs) tmp = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) export_to_video(output.frames[0], tmp.name, fps=int(fps)) pipe.to("cpu"); torch.cuda.empty_cache() return tmp.name # ─── UI CAMUFLADA ────────────────────────────────────────────────────────────── THEME = gr.themes.Default(primary_hue="slate", neutral_hue="slate").set( body_background_fill="#f3f4f6", block_background_fill="#ffffff", ) with gr.Blocks(theme=THEME, title="Image Utility v2.1") as demo: gr.HTML("

🛠 Image Processing Utility v2.1.4

") gr.HTML("

Herramienta técnica para el procesamiento y escalado de matrices de píxeles.

") with gr.Tabs(): with gr.Tab("D-Processor (T2I)"): with gr.Row(): with gr.Column(): t2i_p = gr.Textbox(label="Input Data String", lines=3, placeholder="Enter parameters...") t2i_n = gr.Textbox(label="Excluded Data", value=NEG_DEFAULT) with gr.Row(): t2i_lora = gr.Textbox(label="Extension ID", placeholder="Module ID (optional)") t2i_ls = gr.Slider(0, 1.5, 0.8, label="Extension Weight") with gr.Row(): t2i_w = gr.Slider(512, 1280, 1024, step=64, label="X-Axis") t2i_h = gr.Slider(512, 1280, 1024, step=64, label="Y-Axis") t2i_btn = gr.Button("Execute Process", variant="secondary") t2i_out = gr.Image(label="Output Preview") t2i_btn.click(generate_t2i, [t2i_p, t2i_n, t2i_lora, t2i_ls, gr.Number(30), gr.Number(7.5), t2i_w, t2i_h, gr.Number(42)], t2i_out) with gr.Tab("M-Sequence (Video)"): with gr.Row(): with gr.Column(): v_p = gr.Textbox(label="Motion Vector String", lines=3) v_img = gr.Image(label="Source Buffer", type="numpy") v_ls = gr.Slider(0, 1.5, 0.8, label="Motion Weight") v_btn = gr.Button("Process Sequence", variant="secondary") v_out = gr.Video(label="Sequence Output") v_btn.click(generate_video, [v_p, gr.Textbox(value=NEG_DEFAULT), v_img, gr.Number(49), gr.Number(24), gr.Number(30), v_ls, gr.Number(42)], v_out) demo.launch()