diff --git a/README.md b/README.md index a5d0ec6..6d0e012 100644 --- a/README.md +++ b/README.md @@ -256,6 +256,11 @@ SparkyUI includes a **StabilityMatrix-style Model Manager** - a lightweight Fast - **HuggingFace** - paste a `resolve` URL (works with gated repos via your token) - **Settings** - store your **CivitAI API key** and **HuggingFace token** persistently (saved to a SQLite DB under `./sparkyui-data`, never committed to git) +- **Free GPU memory** - a sidebar button that unloads all models from ComfyUI and releases + memory (proxies ComfyUI's `/free`). ComfyUI keeps the last model cached for fast reuse when + RAM is plentiful, so memory won't drop on its own after switching models - use this to + release it on demand. (For automatic unload after every generation, add + `--disable-smart-memory` to `COMFYUI_FLAGS`, at the cost of reloading each run.) **How it works:** - Runs as a FastAPI server in its own container (`python:3.12-slim`) diff --git a/docker-compose.yml b/docker-compose.yml index b900d9b..84e934a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -154,6 +154,8 @@ services: # Ports used by the device-routing landing page (/start) COMFYUI_PORT: "${COMFYUI_PORT:-8188}" COMFYUIMINI_PORT: "${COMFYUIMINI_PORT:-3000}" + # Internal URL used to proxy the "Free GPU memory" action + COMFYUI_URL: "http://comfyui:8188" volumes: # Shared models dir - read-WRITE here so downloads land on the host. diff --git a/model-manager/app/config.py b/model-manager/app/config.py index 5458e12..4ba815b 100644 --- a/model-manager/app/config.py +++ b/model-manager/app/config.py @@ -19,6 +19,10 @@ DB_PATH = DATA_DIR / "manager.db" COMFYUI_PORT = os.environ.get("COMFYUI_PORT", "8188") COMFYUIMINI_PORT = os.environ.get("COMFYUIMINI_PORT", "3000") +# Internal URL of the ComfyUI container (reachable over the docker network), +# used to proxy the "free memory / unload models" action. +COMFYUI_URL = os.environ.get("COMFYUI_URL", "http://comfyui:8188") + # Image file types shown in the gallery. IMAGE_EXTS = {".png", ".jpg", ".jpeg", ".webp", ".gif", ".bmp"} diff --git a/model-manager/app/main.py b/model-manager/app/main.py index 7a51e05..b7388c0 100644 --- a/model-manager/app/main.py +++ b/model-manager/app/main.py @@ -15,6 +15,7 @@ from pydantic import BaseModel from . import db, downloader, registries from .config import ( COMFYUI_PORT, + COMFYUI_URL, COMFYUIMINI_PORT, IMAGE_EXTS, KEY_BY_FOLDER, @@ -314,6 +315,20 @@ def ui_config() -> dict: return {"comfyui_port": COMFYUI_PORT, "comfyuimini_port": COMFYUIMINI_PORT} +@app.post("/api/comfyui/free") +async def comfyui_free() -> dict: + """Ask ComfyUI to unload all models and free GPU/RAM (proxies POST /free).""" + try: + async with httpx.AsyncClient(timeout=30) as client: + resp = await client.post( + f"{COMFYUI_URL}/free", + json={"unload_models": True, "free_memory": True}) + resp.raise_for_status() + except Exception as exc: # noqa: BLE001 - report to UI + raise HTTPException(502, f"Could not reach ComfyUI: {exc}") + return {"ok": True} + + @app.get("/start") def start() -> FileResponse: return FileResponse(STATIC_DIR / "start.html") diff --git a/model-manager/app/static/app.js b/model-manager/app/static/app.js index eb209ed..32291e8 100644 --- a/model-manager/app/static/app.js +++ b/model-manager/app/static/app.js @@ -663,6 +663,24 @@ $("#saveSettings").addEventListener("click", async () => { } }); +// ---- free GPU memory ------------------------------------------------------ + +$("#freeMemBtn").addEventListener("click", async () => { + const btn = $("#freeMemBtn"); + const msg = $("#freeMemMsg"); + btn.disabled = true; + msg.className = "form-msg"; msg.textContent = "Unloading…"; + try { + await api("/api/comfyui/free", { method: "POST" }); + msg.className = "form-msg ok"; msg.textContent = "Models unloaded."; + } catch (err) { + msg.className = "form-msg err"; msg.textContent = err.message; + } finally { + btn.disabled = false; + setTimeout(() => { msg.textContent = ""; }, 4000); + } +}); + // ---- boot ----------------------------------------------------------------- (async function init() { diff --git a/model-manager/app/static/index.html b/model-manager/app/static/index.html index 23a5413..3acea13 100644 --- a/model-manager/app/static/index.html +++ b/model-manager/app/static/index.html @@ -33,7 +33,12 @@ Settings -
+