Spaces:
Sleeping
Sleeping
| import os | |
| import subprocess | |
| import time | |
| import urllib.request | |
| import zipfile | |
| import gradio as gr | |
| import uvicorn | |
| from fastapi import FastAPI | |
| from huggingface_hub import hf_hub_download | |
| # --- Config ----------------------------------------------------------------- | |
| SD_TAG = "master-709-92a3b73" | |
| SD_ZIP = "sd-master-92a3b73-bin-Linux-Ubuntu-24.04-x86_64.zip" | |
| SD_URL = f"https://github.com/leejet/stable-diffusion.cpp/releases/download/{SD_TAG}/{SD_ZIP}" | |
| MODEL_REPO = "Green-Sky/SD-Turbo-GGUF" | |
| MODEL_FILE = "sd_turbo-f16-q8_0.gguf" | |
| N_THREADS = int(os.environ.get("N_THREADS", "2")) | |
| WORK = os.path.abspath("runtime") | |
| os.makedirs(WORK, exist_ok=True) | |
| def log(*a): | |
| print("[startup]", *a, flush=True) | |
| # --- Fetch sd.cpp binary ---------------------------------------------------- | |
| def fetch_sd(): | |
| sd_dir = os.path.join(WORK, "sdcpp") | |
| if not os.path.isdir(sd_dir): | |
| zip_path = os.path.join(WORK, "sd.zip") | |
| log("downloading stable-diffusion.cpp ...") | |
| urllib.request.urlretrieve(SD_URL, zip_path) | |
| with zipfile.ZipFile(zip_path) as z: | |
| z.extractall(sd_dir) | |
| sd_bin = os.path.join(sd_dir, "sd-cli") | |
| os.chmod(sd_bin, 0o755) | |
| return sd_dir, sd_bin | |
| log("fetching binary + model ...") | |
| SD_DIR, SD_BIN = fetch_sd() | |
| MODEL_PATH = hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILE) | |
| log("ready.") | |
| def generate(prompt, negative, steps, width, height, seed): | |
| if not prompt or not prompt.strip(): | |
| raise gr.Error("Введите prompt") | |
| out = os.path.join(WORK, "out.png") | |
| if os.path.exists(out): | |
| os.remove(out) | |
| env = dict(os.environ) | |
| env["LD_LIBRARY_PATH"] = SD_DIR + ":" + env.get("LD_LIBRARY_PATH", "") | |
| cmd = [ | |
| SD_BIN, | |
| "-m", MODEL_PATH, | |
| "-p", prompt, | |
| "-n", negative or "", | |
| "--cfg-scale", "1.0", # turbo models: cfg ~1 | |
| "--steps", str(int(steps)), | |
| "--sampling-method", "euler", | |
| "-W", str(int(width)), | |
| "-H", str(int(height)), | |
| "-s", str(int(seed)), | |
| "-t", str(N_THREADS), | |
| "-o", out, | |
| ] | |
| t0 = time.time() | |
| r = subprocess.run(cmd, env=env, capture_output=True, text=True, timeout=1200) | |
| dt = time.time() - t0 | |
| if not os.path.exists(out): | |
| tail = (r.stderr or r.stdout or "no output")[-800:] | |
| raise gr.Error(f"Генерация не удалась:\n{tail}") | |
| return out, f"{dt:.1f}s · steps={int(steps)} · {int(width)}x{int(height)} · seed={int(seed)}" | |
| demo = gr.Interface( | |
| fn=generate, | |
| inputs=[ | |
| gr.Textbox(label="Prompt", value="a cute cat astronaut floating in space, digital art, highly detailed"), | |
| gr.Textbox(label="Negative prompt", value="blurry, low quality, deformed"), | |
| gr.Slider(1, 8, value=3, step=1, label="Steps (turbo: 1-4 достаточно)"), | |
| gr.Slider(256, 768, value=512, step=64, label="Width"), | |
| gr.Slider(256, 768, value=512, step=64, label="Height"), | |
| gr.Number(value=42, label="Seed", precision=0), | |
| ], | |
| outputs=[ | |
| gr.Image(label="Результат", type="filepath"), | |
| gr.Textbox(label="Инфо / тайминг"), | |
| ], | |
| title="SD-Turbo — CPU text→image (stable-diffusion.cpp)", | |
| description=( | |
| "SD-Turbo на CPU Basic (2 vCPU). 512px, few-step (1-4 шага). " | |
| "Одна картинка ~30-90 с — наберитесь терпения, это CPU." | |
| ), | |
| allow_flagging="never", | |
| ) | |
| # Use mount_gradio_app + uvicorn (avoids demo.launch() self-check which crashes | |
| # on gradio_client 1.3.0 get_api_info bug under Python 3.12). | |
| demo.queue(max_size=4) | |
| fastapi_app = FastAPI() | |
| app = gr.mount_gradio_app(fastapi_app, demo, path="/") | |
| if __name__ == "__main__": | |
| uvicorn.run(app, host="0.0.0.0", port=7860) | |