Modalità Router di Llama-Server - Commutazione Dinamica dei Modelli senza Riavvii

Servire e sostituire LLM senza riavvii.

Indice

Per molto tempo, llama.cpp presentava una limitazione evidente:
era possibile servire un solo modello per processo e il passaggio da uno all’altro richiedeva un riavvio.

Quell’epoca è finita.

Gli aggiornamenti recenti hanno introdotto la modalità router in llama-server, portando funzionalità molto più vicine a ci si aspetta dai moderni runtime locali per LLM:

  • caricamento dinamico dei modelli
  • scaricamento su richiesta
  • commutazione per richiesta
  • nessun riavvio del processo

router llm sul tavolo

In altre parole: comportamento simile a Ollama, ma senza le rotelline.

Se stai ancora decidendo tra runtime locali, API cloud e infrastrutture self-hosted, la panoramica sull’hosting LLM è un buon punto di partenza.


Prerequisiti

La modalità router richiede una build recente di llama-server — approssimativamente post metà 2024. Le build più vecchie non dispongono dei flag --models-preset o --models-dir.

Per le opzioni di installazione (gestore pacchetti, binari precompilati o build completa dai sorgenti con CUDA), consulta il quickstart di llama.cpp.

Una volta ottenuto llama-server, conferma che la tua build supporta la modalità router:

llama-server --help | grep -i models

Se compaiono --models-preset o --models-dir, sei a posto. Se sono assenti, aggiorna a una build più recente.

Il mio output attuale relativo all’aiuto sui modelli:

-cl,   --cache-list                     mostra la lista dei modelli nella cache
                                        Prefix/Suffix/Middle) alcuni modelli preferiscono questo. (default: disabilitato)
                                        modelli con risoluzione dinamica (default: leggi dal modello)
                                        modelli con risoluzione dinamica (default: leggi dal modello)
                                        modelli di embedding (default: disabilitato)
--models-dir PATH                       directory contenente i modelli per il server router (default: disabilitato)
                                        (env: LLAMA_ARG_MODELS_DIR)
--models-preset PATH                    percorso al file INI contenente i preset dei modelli per il server router
                                        (env: LLAMA_ARG_MODELS_PRESET)
--models-max N                          per il server router, numero massimo di modelli da caricare simultaneamente
                                        (env: LLAMA_ARG_MODELS_MAX)
--models-autoload, --no-models-autoload
                                        per il server router, se caricare automaticamente i modelli (default:
                                        (env: LLAMA_ARG_MODELS_AUTOLOAD)

Cosa fa realmente la modalità router

La modalità router trasforma llama-server in un dispatcher di modelli.

Invece di legarsi a un singolo modello tramite -m, il server:

  • parte senza modelli caricati
  • riceve una richiesta che nomina un modello
  • carica quel modello se non è già in memoria
  • esegue l’inferenza
  • scarica opzionalmente il modello dopo la risposta, o lo mantiene caldo per la prossima richiesta

L’idea chiave

Non stai più eseguendo:

./llama-server -m model.gguf

Stai eseguendo:

./llama-server --models-preset models.ini --port 8080

E lasciando che il server decida cosa caricare e quando, in base a ciò che il client richiede effettivamente.

Questo è importante perché significa che un singolo processo persistente può servire un’intera flotta di modelli, con i client che selezionano quello giusto per ogni task — un modello per il codice, uno per il chat, uno per la sintesi — senza alcun sovraccarico di coordinamento da parte tua.


Configurazione: definizione dei modelli

Qui le cose sono ancora un po’ grezze.

Non esiste ancora un formato ufficiale completamente stabile, ma le build correnti supportano definizioni di modelli in stile INI tramite un file di configurazione.

Esempio di models.ini

[llama3]
model = /opt/models/llama-3-8b-instruct.Q5_K_M.gguf
ctx-size = 8192
ngl = 35
threads = 8

[mistral]
model = /opt/models/mistral-7b-instruct-v0.3.Q4_K_M.gguf
ctx-size = 4096
ngl = 20
threads = 8

[qwen]
model = /opt/models/qwen2.5-coder-7b-instruct.Q5_K_M.gguf
ctx-size = 16384
ngl = 35
threads = 8

Ogni nome di sezione diventa l’identificativo del modello che i client utilizzano nel campo "model" delle loro richieste API.

Parametri di configurazione chiave

Parametro Cosa controlla
model Percorso assoluto al file GGUF
ctx-size Dimensione della finestra di contesto in token. Valori più grandi utilizzano più VRAM.
ngl Numero di layer GPU offloadati. Imposta a 0 per solo CPU; aumenta fino a raggiungere i limiti VRAM.
threads Thread CPU per i layer che restano sulla CPU.

La scelta del valore ngl giusto dipende dalla VRAM disponibile della tua GPU — per la selezione della GPU e dell’economica hardware, la guida all’hardware di calcolo è un utile riferimento. Per monitorare il consumo VRAM in tempo reale mentre lo imposti, vedi gli strumenti di monitoraggio GPU per Linux.

Avvio del server con configurazione

./llama-server --models-preset /opt/llama.cpp/models.ini --port 8080

Conferma che il server è partito correttamente:

curl http://localhost:8080/v1/models | jq '.data[].id'

Dovresti vedere ciascun nome di sezione dal tuo models.ini elencato come ID modello.

Una nota sulla stabilità

L’interfaccia di configurazione INI è ancora in evoluzione:

  • i flag possono cambiare tra i commit
  • alcuni parametri sono riconosciuti solo da configurazioni di build specifiche
  • la documentazione è in ritardo rispetto all’implementazione

Blocca a un commit specifico di llama.cpp se hai bisogno di riproducibilità tra i riavvii.


Utilizzo API: commutazione modelli su richiesta

Una volta che il server è in esecuzione, la commutazione dei modelli avviene tramite l’API standard compatibile con OpenAI. Basta impostare il campo "model".

Elenco dei modelli registrati

curl http://localhost:8080/v1/models

Richiesta di completamento — primo modello

curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama3",
    "messages": [
      {"role": "user", "content": "Spiega la modalità router in un paragrafo"}
    ]
  }'

Passa a un modello diverso — stesso endpoint, stessa porta

curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen",
    "messages": [
      {"role": "user", "content": "Scrivi una funzione Python che legge un file CSV"}
    ]
  }'

Il server gestisce il ciclo di scaricamento/caricamento in modo trasparente. Il tuo codice client non cambia — solo il campo model.

Esempio in Python

Se stai utilizzando il client Python openai:

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8080/v1", api_key="not-needed")

# Usa il modello per il codice
response = client.chat.completions.create(
    model="qwen",
    messages=[{"role": "user", "content": "Scrivi un handler HTTP in Go"}],
)
print(response.choices[0].message.content)

# Passa al modello per il chat — stesso client, nome modello diverso
response = client.chat.completions.create(
    model="llama3",
    messages=[{"role": "user", "content": "Qual è la capitale dell'Australia?"}],
)
print(response.choices[0].message.content)

Cosa succede internamente

Quando arriva una richiesta per qwen e llama3 è attualmente caricato:

  1. llama3 viene scaricato dalla VRAM
  2. I pesi di qwen vengono letti dal disco e caricati in VRAM
  3. viene eseguita l’inferenza
  4. la prossima richiesta determina se mantenere qwen caricato o scambiare nuovamente

Questo risponde direttamente alla domanda comune:

Come può un server LLM locale cambiare modello senza riavviarsi

Caricando dinamicamente i modelli per richiesta, senza legarsi all’avvio.


Servizio Systemd: setup pronto per la produzione

Crea un utente dedicato e le directory

sudo useradd --system --shell /usr/sbin/nologin --home-dir /opt/llama.cpp llm
sudo mkdir -p /opt/llama.cpp/models
sudo chown -R llm:llm /opt/llama.cpp

Copia il tuo binario e la configurazione dei modelli nella posizione corretta:

sudo cp build/bin/llama-server /opt/llama.cpp/
sudo cp models.ini /opt/llama.cpp/

/etc/systemd/system/llama-server.service

[Unit]
Description=Llama.cpp Router Server
After=network.target

[Service]
Type=simple
User=llm
WorkingDirectory=/opt/llama.cpp
ExecStart=/opt/llama.cpp/llama-server --models-preset /opt/llama.cpp/models.ini --port 8080
Restart=always
RestartSec=5

Environment=LLAMA_LOG_LEVEL=info

[Install]
WantedBy=multi-user.target

Abilita e avvia

sudo systemctl daemon-reload
sudo systemctl enable llama-server
sudo systemctl start llama-server

Verifica e ispeziona i log

sudo systemctl status llama-server
journalctl -u llama-server -f

In un avvio riuscito vedrai righe che indicano che il server è in ascolto e che il registro dei modelli è stato caricato. Un rapido controllo di sanità:

curl -s http://localhost:8080/v1/models | jq '.data[].id'

Ora hai un servizio persistente con riavvio automatico e commutazione dei modelli centralizzata — nessuna gestione manuale dei processi richiesta. Se vuoi applicare lo stesso schema ad altri binari, hosting di qualsiasi eseguibile come servizio Linux illustra l’approccio generale.

Il flag --metrics di llama-server espone un endpoint compatibile con Prometheus. Per dashboard specifiche per llama.cpp, query PromQL e regole di allerta, vedi la guida al monitoraggio dell’inferenza LLM. Per il setup di osservabilità più ampio, la guida all’osservabilità copre l’intero stack.


Limitazioni che devi comprendere

La modalità router è genuinamente utile, ma comporta compromessi che dovresti chiarire prima di affidarti a essa in produzione.

Solo un modello in memoria alla volta

Anche se più modelli sono definiti in models.ini, solo uno è residente in VRAM per worker in ogni dato momento. La commutazione significa un ciclo completo di scaricamento e ricarica.

  • la commutazione significa ricarica
  • un picco di latenza è inevitabile
  • su un tipico modello 7B a Q5, una ricarica può richiedere 3–10 secondi a seconda della velocità del disco e della larghezza di banda VRAM

Questo risponde a un’altra domanda chiave:

Llama.cpp supporta il servizio di più modelli contemporaneamente?

Non proprio. Supporta definizioni multiple, non residenza simultanea. Se hai bisogno di due modelli realmente caricati in parallelo, hai bisogno di due processi su due GPU separate.

Per il consumo VRAM misurato e i token-al-secondo tra diverse dimensioni dei modelli, i benchmark delle prestazioni LLM coprono il quadro completo. Per numeri specifici su llama.cpp su una GPU da 16 GB — modelli dense e MoE a diverse dimensioni di contesto — vedi i benchmark llama.cpp su VRAM da 16 GB.

Nessun caching intelligente

A differenza di Ollama, che mantiene un pool caldo e espelle i modelli in base alla recenza:

  • non esiste una strategia automatica di espulsione dei modelli
  • nessun pre-riscaldamento in background
  • nessuna coda di priorità per i modelli usati frequentemente

Se invii richieste alternate per llama3 e mistral, ogni singola richiesta innesca una ricarica. Questo è il costo fondamentale di essere più vicini al metallo.

La latenza è imprevedibile per carichi di lavoro misti

Un carico di lavoro ben comportato che usa un modello in modo costante sarà veloce. Un carico di lavoro che intreccia più modelli sarà lento. Pianifica di conseguenza la logica di routing del tuo client — raggruppa le richieste per modello dove possibile.

La configurazione non è stabile

Il supporto INI esiste e funziona nelle build più recenti, ma non è completamente standardizzato. Flag e nomi dei parametri sono cambiati tra le versioni. Se aggiorni llama-server, testa il tuo models.ini contro la nuova build prima di distribuire.


Llama.cpp vs Ollama: confronto onesto

Caratteristica Router llama.cpp Ollama
Caricamento dinamico
Commutazione modelli
Registro integrato Parziale (INI) Sì (basato su pull)
Gestione memoria Base Avanzata
Espulsione modelli Nessuna Basata su TTL
Polish UX Basso Alto
Compatibilità API OpenAI
Controllo Massimo Opinione forte
Stabilità config Sperimentale Stabile

Opinione personale

Scegli la modalità router di llama.cpp quando vuoi:

  • controllo massimo sui parametri di runtime per modello
  • sovraccarico di processo minimo
  • accesso diretto ai flag di llama.cpp senza livelli di astrazione
  • una base modificabile per tooling personalizzato

Scegli Ollama quando vuoi:

  • un’esperienza stabile e rifinita
  • download automatico dei modelli e versioning
  • keep-alive intelligente ed espulsione senza configurazione
  • tutto incluso fin dal primo giorno

Nessuno dei due è sbagliato. La scelta dipende da quanto vuoi gestire tu stesso.

Se opti per Ollama, il cheat sheet CLI di Ollama copre i comandi quotidiani. Per un confronto più ampio che include anche vLLM, LM Studio e LocalAI, vedi come si confrontano i diversi runtime locali nel 2026.


Llama.cpp vs llama-swap

llama-swap è un orchestratore esterno che si posiziona davanti a una o più istanze di llama-server:

  • intercetta le richieste e ispeziona il campo model
  • avvia il processo llama-server appropriato per quel modello
  • spegne le istanze inattive dopo un timeout configurabile
  • proxy la richiesta una volta che il modello è pronto

Per un setup pratico, vedi il quickstart di llama-swap.

Differenza chiave

Aspetto Modalità router llama-swap
Integrato No (binario separato)
Maturità Sperimentale Più stabile
Flessibilità Limitata Alta
Livello di controllo Interno Proxy esterno
Config per modello File INI File YAML
Modello processo Singolo processo Un processo per modello

Quando usare llama-swap

llama-swap ti dà isolamento a livello di processo per modello, il che significa che un crash in un’istanza di un modello non ne affetta altre. Permette anche a ogni modello di girare con flag llama-server completamente indipendenti.

Usalo se hai bisogno di:

  • migliore controllo del ciclo di vita e isolamento
  • logica di commutazione più intelligente con timeout di inattività configurabili
  • latenza più prevedibile (ogni modello ha un processo caldo dopo il primo caricamento)
  • stabilità di produzione oggi, non in futuro

Quando la modalità router nativa è sufficiente

Usa il router integrato se vuoi:

  • zero dipendenze esterne
  • un singolo processo da gestire
  • deployment più semplice (un binario, un file di configurazione)
  • stack minimo per dev o setup single-user

Considerazioni finali

La modalità router è un passo avanti significativo per llama-server.

Risponde alla domanda da tempo in sospeso:

Cos’è la modalità router nel server llama.cpp

È lo strato mancante che trasforma un binario statico in un servizio di inferenza dinamico — un singolo processo che può gestire richieste per un intero catalogo di modelli.

Ma non è finito.

Oggi è:

  • abbastanza potente per carichi di lavoro reali
  • promettente come base per routing più sofisticati
  • leggermente ruvido ai bordi della configurazione e stabilità

Se il tuo carico di lavoro è prevedibile e puoi raggruppare le richieste per modello, la modalità router funziona bene oggi. Se hai bisogno di affidabilità di livello produzione e isolamento per modello, punta su llama-swap mentre l’implementazione nativa matura.

Quando hai bisogno di liberare VRAM senza riavviare — per un run di benchmark, una finestra di manutenzione o un reset di sviluppo pulito — l’approccio scriptabile è elencare i modelli caricati e chiamare l’endpoint di scaricamento per ciascuno. Il pattern completo curl-e-jq è coperto in Scarica tutti i modelli router di llama.cpp senza riavviare.

In ogni caso, ottieni comportamento simile a Ollama, senza nascondere il meccanismo.

Iscriviti

Ricevi nuovi articoli su sistemi, infrastruttura e ingegneria AI.