CatInSpace / app.py
freshcodestech's picture
Update app.py
ed350f0 verified
Raw
History Blame Contribute Delete
3.79 kB
# app.py — SDXL + LoRA from Hub (PEFT) with version-safe adapter weighting
import torch, gradio as gr
from diffusers import StableDiffusionXLPipeline, DPMSolverMultistepScheduler
# --- Config ---
BASE_MODEL = "stabilityai/stable-diffusion-xl-base-1.0"
LORA_REPO = "freshcodestech/LingoSpace" # your HF LoRA repo
LORA_FILE = "LingoSpace-10.safetensors" # exact filename in that repo
ADAPTER = "lingospace" # local nickname; any safe string
LORA_W = 0.8 # 0.6–1.0 typical
# Device / dtype
device = "cuda" if torch.cuda.is_available() else "cpu"
dtype = torch.float16 if device == "cuda" else torch.float32
# --- Load SDXL base (disable watermarker to avoid extra deps on Spaces) ---
pipe = StableDiffusionXLPipeline.from_pretrained(
BASE_MODEL,
torch_dtype=dtype,
use_safetensors=True,
add_watermarker=False,
**({"variant": "fp16"} if device == "cuda" else {}) # fp16 only on GPU
)
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
pipe = pipe.to(device)
# --- Load LoRA from Hub via PEFT backend ---
pipe.load_lora_weights(
LORA_REPO,
weight_name=LORA_FILE,
adapter_name=ADAPTER,
use_peft_backend=True
)
# Try all known set_adapters signatures; else fall back to per-call scaling
USE_RUNTIME_SCALE = False
if hasattr(pipe, "set_adapters"):
try:
# Newer diffusers: keyword
pipe.set_adapters(ADAPTER, adapter_weights=LORA_W)
except TypeError:
try:
# Older diffusers: 2 positional lists
pipe.set_adapters([ADAPTER], [LORA_W])
except Exception:
USE_RUNTIME_SCALE = True
else:
USE_RUNTIME_SCALE = True
# Memory helpers (T4)
if device == "cuda":
if hasattr(pipe, "enable_xformers_memory_efficient_attention"):
pipe.enable_xformers_memory_efficient_attention()
pipe.enable_attention_slicing()
pipe.enable_vae_tiling()
# Defaults (smaller on CPU)
DEF_STEPS = 30 if device == "cuda" else 15
DEF_H = 1024 if device == "cuda" else 768
DEF_W = 1024 if device == "cuda" else 768
def infer(prompt, steps, cfg, h, w, lora_strength):
# If we couldn’t set adapter weight globally, pass strength per call
kwargs = {}
if USE_RUNTIME_SCALE:
kwargs["cross_attention_kwargs"] = {"scale": float(lora_strength)}
else:
# If API exists, update weight dynamically per request
try:
pipe.set_adapters(ADAPTER, adapter_weights=float(lora_strength))
except TypeError:
pipe.set_adapters([ADAPTER], [float(lora_strength)])
out = pipe(
prompt,
num_inference_steps=int(steps),
guidance_scale=float(cfg),
height=int(h),
width=int(w),
**kwargs
)
return out.images[0]
DEFAULT_PROMPT = (
"lingospace, cartoon, 2d illustration, flat colors, clean lineart, "
"a raccoon in a compact utility space suit, holding a steaming bowl of rice, "
"stars and soft nebula, cozy composition"
)
demo = gr.Interface(
fn=infer,
inputs=[
gr.Textbox(label="Prompt", value=DEFAULT_PROMPT, lines=3),
gr.Slider(10, 50, value=DEF_STEPS, step=1, label="Steps"),
gr.Slider(3.0, 9.0, value=7.5, step=0.5, label="CFG"),
gr.Slider(512, 1216, value=DEF_H, step=64, label="Height"),
gr.Slider(512, 1216, value=DEF_W, step=64, label="Width"),
gr.Slider(0.3, 1.2, value=LORA_W, step=0.05, label="LoRA Strength"),
],
outputs=gr.Image(label="Output"),
title="SDXL + LoRA (freshcodestech/LingoSpace)",
description=f"Device: {device.upper()} • Base: {BASE_MODEL} • LoRA: {LORA_REPO}/{LORA_FILE}"
)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860, show_api=True)