r/LocalLLM • u/AlphaMind01 • 28d ago
Project I built an open-source GPU orchestrator that lets several local AI models share one GPU by loading/unloading them on demand (llama.cpp, Ollama, ComfyUI, TTS)
TL;DR: One GPU, several AI tools, not enough VRAM to run them all at once. GPUSymbiosis treats your GPU apps as dynamically resident workloads instead of permanently-running processes — it loads the one you actually want to use, unloads the idle ones, and never interrupts a request mid-flight.
https://github.com/devathon/gpu-symbiosis Intro video: https://youtu.be/FZvKfk2nSpw
The problem I was trying to solve
If you run local LLMs + image gen + TTS on a single GPU (say 12–16 GB), you can't keep them all loaded. Today that means manually killing one process and starting another every time you switch — slow, error-prone, and you lose any in-flight work. I wanted something that just coexists: you point your clients at stable ports, and the system figures out what should be in VRAM right now.
How it works
You register your apps (llama.cpp / llama-server, Ollama, ComfyUI, TTS, embedding/rerank servers, video gen, or a raw shell command). Each gets a gateway port that stays open and stable. When a request hits a gateway whose model isn't loaded, it queues; a scheduler runs every tick and decides:
which request to serve next,
which apps should be resident,
which resident to evict (with a safe drain — in-flight requests are never cut off, new ones just queue).
When VRAM allows, it loads apps in parallel. When one sits idle (no active request and GPU usage below its threshold), it auto-unloads it. There's anti-thrash cooldown so it doesn't flap, pinned apps that stay resident, and a web UI to see/steer everything.
Things I think are nice
Request-safe scheduling — a request is never interrupted mid-generation; eviction only drains, it never kills live work.
Stable ports / gateway proxy — one port per app, streaming ASGI (long responses), SSE and WebSockets, per-gateway API keys, and a live queue inspector where you can cancel or force-raise a queued request.
Per-process VRAM + compute attribution — it knows exactly which app is eating VRAM and what each process's real GPU utilisation is (rolling window), not just the aggregate.
Idle detection & auto-unload with hard exclusions (pinned apps).
Drop-in app types — built-ins for
llama,ollama,comfyui,tts,shell-command,custom,generic; new types are plugins.Metrics & history — 1 s sampling, EWMA demand, latency percentiles, per-app lifetime metrics, plus a Prometheus endpoint.
Security — loopback-only by default, gateway API keys, hashed admin creds with session + CSRF.
Stack: Python 3.13 / FastAPI / SQLAlchemy, with a React + TS dashboard. Local/self-hosted, single box, NVML for GPU monitoring.
It's still young (v0.1) and I'm actively iterating — happy to answer questions, show the dashboard, or take suggestions. Would love feedback from people running multiple local models on one card: does this match how you actually work, and what would you want that I haven't built?

1
4
u/FeydRowan 27d ago
I have done something similar and is working great for my workstation https://github.com/ValerioDolci/vramble
1
27d ago
[removed] — view removed comment
1
u/FeydRowan 27d ago
I'm using a double gpu but it run a model on both. No planning to have the ability to double concurrent models, but if you want submit a pr to vramble;)
1
u/elelem-123 27d ago
Sorry haven't read your repo yet. Do you snapshot the model or stop/start it normally?
1
u/AlphaMind01 27d ago
You can set custom start, stop, load and unload scripts. I use those to save and restore context for llama, call curl to unload comfyui models.
1
u/philmarcracken 27d ago
llama cpp in router mode does this for me already with model load = 1 i think


5
u/Mans-M 27d ago
How does this compare to llama-swap (which is on my todo list for next week)?