Alle llama.cpp-routermodellen opnieuw laden zonder opnieuw te starten
Gratis VRAM zonder llama-server te beëindigen.
Routermodus van llama.cpp is een van de meest nuttige wijzigingen aan llama-server in jaren. Het geeft lokale LLM-beheerders eindelijk iets dat lijkt op de modelbeheerservaring die mensen verwachten van Ollama, terwijl het de ruwe prestaties en lage-level controle behoudt die llama.cpp in de eerste plaats de moeite waard maken.
Maar er is één scherpe rand: alles ontladen is geen enkele magische knop in de HTTP-API.
De router kan modellen lijsten. Het kan een model laden. Het kan een model ontladen. Het kan het minst recent gebruikte model verdrijven wanneer --models-max is bereikt. Wat het momenteel niet als een eersteklas eindpunt documenteert, is een universele ontlaad alle modellen nu-oproep.

Dat is geen echte blokkade. Het correcte patroon is eenvoudig, expliciet en scriptbaar:
- Vraag de router welke modellen bestaan.
- Filter de modellen waarvan de status
loaded(geladen) is. - Roep
/models/unloadéén keer per geladen model aan.
Dit is de aanpak die ik aanbeziel voor serieuze lokale LLM-workflows. Het is saai, inzichtelijk en eenvoudig te debuggen. Dat is precies wat je wilt wanneer je doel is VRAM vrij te maken zonder de hele inferentieservice opnieuw te starten.
Wat llama.cpp routermodus eigenlijk doet
In klassiek llama-server-gebruik start je één server met één model:
llama-server \
--model ./models/qwen3-8b.gguf \
--port 8080
Routermodus verandert dat model. In plaats van de server te binden aan één GGUF-bestand, wordt de router een coördinator voor meerdere modellen. Het kan modellen ontdekken uit een cache of uit een modelmap, ze op aanvraag laden, verzoeken doorsturen naar het juiste model en modellen ontladen wanneer nodig.
Een typische startopdracht voor routermodus ziet er zo uit:
llama-server \
--models-dir ./models \
--models-max 4 \
--port 8080
De belangrijke optie hier is --models-max. Het bepaalt hoeveel modellen tegelijkertijd geladen mogen worden. Als het limiet wordt bereikt, kan llama.cpp het minst recent gebruikte model verdrijven. Dat is nuttig, maar het is geen vervanging voor een bewuste ontlaadoperatie. LRU-verdrijving (Least Recently Used) is reactief. Een ontlaadscript is operationele controle.
Mijn mening: als je lokale modellen gebruikt voor echt werk, behandel routermodus dan als een inferentieprocesbeheerder, niet als een spelchatserver. Expliciete levenscyclusoperaties zijn belangrijk.
De modelbeheer-eindpunten die je nodig hebt
Het belangrijkste eindpunt voor ontdekking is:
curl -s http://localhost:8080/models | jq
Dat eindpunt retourneert de modellen die de router kent en hun huidige levenscyclusstatus. De exacte JSON-vorm kan iets variëren tussen builds, dus inspecteer je eigen respons voordat je automatisering schrijft.
Een veelvoorkomende responsvorm ziet er zo uit:
{
"data": [
{
"id": "qwen3-8b",
"status": "loaded"
},
{
"id": "llama-3.2-3b",
"status": "unloaded"
}
]
}
Om één model te ontladen, roep dan:
curl -s -X POST http://localhost:8080/models/unload \
-H "Content-Type: application/json" \
-d '{"model":"qwen3-8b"}' \
| jq
Dat is de primitieve operatie. Alles else in dit artikel bouwt daarop voort.
Er is geen gedocumenteerd ‘ontlaad alles’-eindpunt
Dit is het deel waar mensen over struikelen.
Je zou misschien iets als dit verwachten:
curl -X POST http://localhost:8080/models/unload-all
Bouw niet rond die aanname. De gedocumenteerde operatie is per model. Je doorgeeft een modelidentifier aan /models/unload, en llama.cpp laadt dat ene model uit.
Dit is niet per se slecht API-ontwerp. Een per-model operatie is veiliger. Het laat de aanroper beslissen wat er ontladen moet worden. Het voorkomt ook verrassend productiegedrag waarbij één beheerdersverzoek per ongeluk elk warm model dat door andere clients wordt gebruikt, doodt.
Voor een workstation zou een ‘ontlaad alles’-sneltoegang handig zijn. Voor een multi-user inferentieserver zijn expliciete loops beter.
Ontlaad eerst één model
Voordat je alles automatiseert, test de exacte modelidentifier die je router verwacht.
Lijst eerst de modellen:
curl -s http://localhost:8080/models | jq
Kies één geladen model uit de output, en laadt het dan uit:
curl -s -X POST http://localhost:8080/models/unload \
-H "Content-Type: application/json" \
-d '{"model":"qwen3-8b"}' \
| jq
Controleer de modellijst opnieuw:
curl -s http://localhost:8080/models | jq
Als de modelstatus verandert naar unloaded (ontladen), zijn je eindpunt, poort en modelidentifier correct.
Als het niet werkt, radel niet. Inspecteer de JSON. Router-aliases, GGUF-bestandsnamen en model-ID’s zijn vaak niet dezelfde string.
Ontlaad alle geladen modellen met curl en jq
Zodra het ontladen van een enkel model werkt, is het ‘ontlaad alles’-patroon slechts een shell-loop.
Gebruik dit wanneer je /models-respons .data[].id en .data[].status heeft:
curl -s http://localhost:8080/models \
| jq -r '.data[] | select(.status == "loaded") | .id' \
| while IFS= read -r model; do
echo "Unloading: $model"
curl -s -X POST http://localhost:8080/models/unload \
-H "Content-Type: application/json" \
-d "{\"model\":\"$model\"}" \
| jq
done
Dit is de hele truc. Het is niet glansrijk, maar het is de juiste vorm voor een beheerdersoperatie:
- Het laadt alleen modellen uit die daadwerkelijk geladen zijn.
- Het print wat het doet.
- Het faalt model per model in plaats van alles te verbergen achter één ondoorzichtige actie.
- Het werkt vanaf cron, systemd-hooks, SSH of CI-jobs.
Een herbruikbaar script voor productiegoed gebruik
Voor alles wat je meer dan twee keer uitvoert, stop met het plakken van one-liners. Sla een script op.
Maak llama-router-unload-all.sh:
#!/usr/bin/env bash
set -euo pipefail
LLAMA_SERVER_URL="${LLAMA_SERVER_URL:-http://localhost:8080}"
models_json="$(curl -fsS "$LLAMA_SERVER_URL/models")"
loaded_models="$(printf '%s' "$models_json" \
| jq -r '.data[] | select(.status == "loaded") | .id')"
if [ -z "$loaded_models" ]; then
echo "No loaded models found."
exit 0
fi
printf '%s\n' "$loaded_models" | while IFS= read -r model; do
[ -z "$model" ] && continue
echo "Unloading: $model"
curl -fsS -X POST "$LLAMA_SERVER_URL/models/unload" \
-H "Content-Type: application/json" \
-d "{\"model\":\"$model\"}" \
| jq
done
echo "Done. Current model state:"
curl -fsS "$LLAMA_SERVER_URL/models" | jq
Maak het uitvoerbaar:
chmod +x llama-router-unload-all.sh
Voer het uit tegen de standaard lokale server:
./llama-router-unload-all.sh
Voer het uit tegen een andere host:
LLAMA_SERVER_URL=http://192.168.1.50:8080 ./llama-router-unload-all.sh
Dit is de versie die ik daadwerkelijk in een tools-directory zou bewaren. Het gebruikt curl -f zodat HTTP-fouten het script laten falen, en het laat je de server-URL overschrijven zonder het bestand te bewerken.
Het script aanpassen aan je JSON-vorm
Ga niet blindelings ervan uit dat elke llama.cpp-build voor altijd exact dezelfde velden retourneert. Routermodus evolueert nog, en je build kan een iets andere JSON-vorm blootleggen.
Begin met het inspecteren van de respons:
curl -s http://localhost:8080/models | jq
Het script gebruikt deze filter:
jq -r '.data[] | select(.status == "loaded") | .id'
Als je modelidentifier in .name staat, verander het dan naar:
jq -r '.data[] | select(.status == "loaded") | .name'
Als je statusveld een andere waarde gebruikt, pas de filter dienovereenkomstig aan. Het principe is wat telt: selecteer geladen modellen, extraheer de identifier die wordt geaccepteerd door /models/unload, en roep dan ontladen aan voor elk ervan.
Waarom modellen zich mogelijk opnieuw laden nadat je ze hebt ontladen
Dit is de meest voorkomende oorzaak van verwarring.
Routermodus ondersteunt laden op aanvraag. Als een client een chat-completieverzoek verzendt voor een model dat momenteel is ontladen, kan de router het automatisch opnieuw laden.
Dat betekent dat deze sequentie mogelijk is:
- Je laadt elk model uit.
- Open WebUI, een testscript of een agent verzendt een verzoek.
- llama.cpp laadt het gevraagde model opnieuw.
- Je denkt dat ontladen faalde, maar dat was het niet.
De oplossing is operationeel, niet technisch. Stop clientverkeer eerst als je doel is VRAM vrij te houden.
Bijvoorbeeld:
- Stop benchmarkscripts.
- Pauzeer agents en cron-jobs.
- Sluit of verbreek Open WebUI-sessies.
- Schakel health checks uit die per ongeluk daadwerkelijke modelverzoeken uitvoeren.
Ontladen is geen firewall. Als clients blijven vragen om modellen, doet routermodus zijn werk door ze te serveren.
Open WebUI en de Eject-knop
Open WebUI kan integreren met llama.cpp modelontlaadondersteuning. Wanneer de provider is geconfigureerd als llama.cpp, kan Open WebUI de status van geladen modellen tonen en een Eject-actie blootleggen voor beheerders.
Anderzijds roept die actie de eigen ontlaad-API van Open WebUI aan, die dan weer het /models/unload-eindpunt van llama.cpp roept op de geconfigureerde connectie.
Dat is leuk voor handmatige operaties, maar ik zou het shellscript nog steeds behouden. Een UI-knop is handig. Een script is auditabel, herhaalbaar en bruikbaar op een headless box om 2 uur ’s nachts.
Wanneer je ‘ontlaad alles’ moet gebruiken
Het ontladen van elk geladen model is nuttig wanneer je wilt:
- GPU-geheugen vrijmaken voordat je een groter model start.
- Een ontwikkelbox resetten zonder
llama-serveropnieuw te starten. - Voorbereiden op een benchmarkrun met een schone geheugenstatus.
- Lokale inferentiewerklasten drainen voordat onderhoud.
- Herstellen van een rommelige sessie waarbij te veel modellen werden opgewarmd.
Het is niet het juiste instrument wanneer actieve gebruikers afhankelijk zijn van warme modellen. In dat geval, tune --models-max, gebruik bewuste routing, en laat LRU-verdrijving een deel van het werk doen. Als je slimmer timeout-gebaseerd ontladen wilt met levenscycluscontrole per model, is llama-swap een speciaal ontworpen proxy die precies dat laag bovenop elke llama-server-opstelling legt.
Mijn regel is simpel: gebruik LRU voor normale druk, gebruik expliciet ontladen voor operatorintentie.
Probleemoplossing
Het modellen-eindpunt retourneert 404
Je draait misschien geen router-capabele build, of je roept het verkeerde poort aan.
Controleer het serverproces en beschikbare opties:
llama-server --help | grep -i models
Test dan beide eindpunten:
curl -s http://localhost:8080/models | jq
curl -s http://localhost:8080/v1/models | jq
Het /v1/models-eindpunt is de OpenAI-compatibele modellijst. Het /models-eindpunt is het router-modelbeheer-eindpunt. Ze zijn gerelateerd, maar ze zijn niet hetzelfde.
jq is niet geïnstalleerd
Installeer het voordat je JSON-parsing automatiseert.
Op Ubuntu of Debian:
sudo apt-get update
sudo apt-get install jq
Op macOS met Homebrew:
brew install jq
De ontlaadoproep retourneert een fout
De meeste fouten komen voort uit het doorgeven van de verkeerde modelidentifier. Gebruik de exacte identifier die door /models wordt geretourneerd, niet de bestandsnaam waarvan je denkt dat die zou moeten werken.
Controleer ook of je modelnaam quotes, slashes of spaties bevat. Het script hierboven behandelt normale strings goed, maar ongewone namen kunnen zorgvuldiger JSON-constructie vereisen.
Voor maximale veiligheid kun je het POST-body bouwen met jq:
jq -n --arg model "$model" '{model: $model}'
Een defensiever ontlaadloop zou dat body gebruiken in plaats van hand-geescape JSON.
VRAM wordt niet onmiddellijk vrijgemaakt
Bevestig eerst dat de modelstatus veranderde. Controleer dan of een ander verzoek het opnieuw heeft geladen. Onthoud ook dat GPU-geheugentools kunnen achterlopen of allocator-gedrag rapporteren in plaats van directe applicatie-level intentie.
De praktische test is simpel: stop verkeer, laad modellen uit, lijst modelstatus, en inspecteer dan GPU-geheugen. Voor gemeten VRAM-gebruik over modelgroottes en contextvensters op llama.cpp, geven de 16 GB VRAM llama.cpp benchmarks concrete cijfers om tegen te sanity-checken.
Een veiligere JSON-body versie
Als je modelidentifiers ongewone karakters bevatten, gebruik dan jq om het JSON-verzoeklichaam te genereren:
curl -s http://localhost:8080/models \
| jq -r '.data[] | select(.status == "loaded") | .id' \
| while IFS= read -r model; do
echo "Unloading: $model"
body="$(jq -n --arg model "$model" '{model: $model}')"
curl -s -X POST http://localhost:8080/models/unload \
-H "Content-Type: application/json" \
-d "$body" \
| jq
done
Dit is de versie om te gebruiken als je modellen zijn vernoemd naar repository-stijl identifiers, aangepaste aliases of paden.
Eindoordeel
llama.cpp routermodus is een grote stap vooruit voor lokale LLM-operaties. Het geeft je dynamisch laden, modelwisseling en geheugenbewuste verdrijving zonder de directheid van llama-server op te geven.
Maar wacht niet op een perfect ‘ontlaad alles’-eindpunt. De schone oplossing bestaat al: lijst geladen modellen en laadt ze één voor één uit.
Dat patroon is expliciet. Het is scriptbaar. Het werkt over SSH. Het speelt aardig samen met Open WebUI. En het belangrijkste, het maakt VRAM vrij zonder de router opnieuw te starten.
Voor lokale AI-infrastructuur is dat precies het soort saai controleoppervlak dat je wilt.