|
|
|
import os |
|
import torch |
|
from diffusers import StableDiffusionXLPipeline, DPMSolverMultistepScheduler |
|
import gradio as gr |
|
from PIL import Image |
|
|
|
|
|
MODEL_ID = "stabilityai/stable-diffusion-xl-base-1.0" |
|
REFINER_ID = "stabilityai/stable-diffusion-xl-refiner-1.0" |
|
USE_REFINER = True |
|
|
|
|
|
HF_TOKEN = os.environ.get("HF_ACCESS_TOKEN", None) |
|
|
|
device = "cuda" if torch.cuda.is_available() else "cpu" |
|
print("Device:", device) |
|
|
|
|
|
torch_dtype = torch.float16 if device == "cuda" else torch.float32 |
|
|
|
pipe = StableDiffusionXLPipeline.from_pretrained( |
|
MODEL_ID, |
|
torch_dtype=torch_dtype, |
|
use_safetensors=True, |
|
revision="fp16" if device == "cuda" else None, |
|
use_auth_token=HF_TOKEN |
|
) |
|
|
|
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config) |
|
|
|
if device == "cuda": |
|
pipe.enable_xformers_memory_efficient_attention() |
|
pipe.to("cuda") |
|
else: |
|
pipe.to("cpu") |
|
|
|
|
|
refiner = None |
|
if USE_REFINER: |
|
try: |
|
refiner = StableDiffusionXLPipeline.from_pretrained( |
|
REFINER_ID, |
|
torch_dtype=torch_dtype, |
|
use_safetensors=True, |
|
use_auth_token=HF_TOKEN |
|
) |
|
if device == "cuda": |
|
refiner.enable_xformers_memory_efficient_attention() |
|
refiner.to("cuda") |
|
else: |
|
refiner.to("cpu") |
|
except Exception as e: |
|
print("No se pudo cargar refiner:", e) |
|
refiner = None |
|
|
|
|
|
def generate(prompt, negative_prompt, steps, guidance_scale, width, height, seed): |
|
generator = torch.Generator(device=device) |
|
if seed is not None and seed != "": |
|
try: |
|
seed = int(seed) |
|
generator = torch.Generator(device=device).manual_seed(seed) |
|
except: |
|
seed = None |
|
|
|
|
|
height = int(height) |
|
width = int(width) |
|
|
|
with torch.autocast(device_type="cuda" if device=="cuda" else "cpu"): |
|
output = pipe( |
|
prompt, |
|
negative_prompt=negative_prompt if negative_prompt else None, |
|
num_inference_steps=int(steps), |
|
guidance_scale=float(guidance_scale), |
|
generator=generator, |
|
height=height, |
|
width=width |
|
) |
|
image = output.images[0] |
|
|
|
|
|
if refiner is not None: |
|
with torch.autocast(device_type="cuda" if device=="cuda" else "cpu"): |
|
refined = refiner( |
|
prompt, |
|
image=image, |
|
num_inference_steps=10, |
|
guidance_scale=float(guidance_scale), |
|
generator=generator |
|
) |
|
image = refined.images[0] |
|
|
|
return image |
|
|
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("# SDXL — Generador fotorrealista") |
|
with gr.Row(): |
|
with gr.Column(): |
|
prompt = gr.Textbox(label="Prompt (describe la escena fotorrealista)", lines=4, placeholder="Portrait of a young woman... cinematic lighting, 85mm lens, photorealistic") |
|
negative = gr.Textbox(label="Negative prompt (evitar)", lines=2, placeholder="lowres, deformed, cartoon, watermark") |
|
steps = gr.Slider(minimum=10, maximum=60, step=1, value=28, label="Steps") |
|
scale = gr.Slider(minimum=1.0, maximum=12.0, step=0.5, value=7.5, label="Guidance scale (fidelity)") |
|
width = gr.Dropdown([512, 640, 768, 1024], value=1024, label="Width") |
|
height = gr.Dropdown([512, 640, 768, 1024], value=1024, label="Height") |
|
seed = gr.Textbox(label="Seed (opcional)", placeholder="123456") |
|
btn = gr.Button("Generar") |
|
with gr.Column(): |
|
gallery = gr.Image(label="Resultado", type="pil") |
|
|
|
btn.click(fn=generate, inputs=[prompt, negative, steps, scale, width, height, seed], outputs=[gallery]) |
|
|
|
if __name__ == "__main__": |
|
demo.launch() |