Modalità Router di Llama-Server: commutazione dinamica del modello senza riavvii

Servire e scambiare LLM senza riavvii.

Indice

Per molto tempo, llama.cpp ha avuto una limitazione evidente:
potevi servire un solo modello per processo e il cambio richiedeva un riavvio.

Quell’epoca è finita.

Aggiornamenti recenti hanno introdotto la modalità router in llama-server, portando qualcosa che si avvicina molto a ciò che ci si aspetta dai moderni runtime locali per LLM:

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

llm router on the table

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

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 hanno il flag --models.

Per le opzioni di installazione (gestore pacchetti, binari pre-compilati o build completa da sorgente con CUDA), vedi la guida rapida a llama.cpp.

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

llama-server --help | grep -i models

Se appare il flag --models, sei a posto. Se è assente, aggiorna a una build più recente.

Il mio output attuale relativo ai modelli:

-cl,   --cache-list                     show list of models in cache
                                        Prefix/Suffix/Middle) as some models prefer this. (default: disabled)
                                        models with dynamic resolution (default: read from model)
                                        models with dynamic resolution (default: read from model)
                                        embedding models (default: disabled)
--models-dir PATH                       directory containing models for the router server (default: disabled)
                                        (env: LLAMA_ARG_MODELS_DIR)
--models-preset PATH                    path to INI file containing model presets for the router server
                                        (env: LLAMA_ARG_MODELS_PRESET)
--models-max N                          for router server, maximum number of models to load simultaneously
                                        (env: LLAMA_ARG_MODELS_MAX)
--models-autoload, --no-models-autoload
                                        for router server, whether to automatically load models (default:
                                        (env: LLAMA_ARG_MODELS_AUTOLOAD)

Cosa fa effettivamente 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 alcun modello caricato
  • riceve una richiesta che nomina un modello
  • carica quel modello se non è già in memoria
  • esegue l’inferenza
  • opzionalmente scarica il modello dopo la risposta o lo mantiene caldo per la richiesta successiva

L’idea chiave

Non stai più eseguendo:

./llama-server -m model.gguf

Stai eseguendo:

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

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

Questo è importante perché significa che un processo persistente può servire un’intera flotta di modelli, con i clienti che selezionano quello giusto per ogni compito — un modello per il coding, un modello per il chat, un modello per il riassunto — senza alcun overhead di coordinamento da parte tua.


Configurazione: definizione dei tuoi modelli

Qui le cose sono ancora un po’ grezze.

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

Esempio 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’identificatore del modello che i clienti usano nel campo "model" delle loro richieste API.

Parametri chiave della configurazione

Parametro Cosa controlla
model Percorso assoluto al file GGUF
ctx-size Dimensione della finestra di contesto in token. Valori più grandi usano più VRAM.
ngl Numero di livelli GPU offloadati. Imposta a 0 per solo CPU; aumenta finché non raggiungi i limiti VRAM.
threads Thread CPU per i livelli che rimangono sulla CPU.

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

Avvio del server con configurazione

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

Conferma che il server sia partito correttamente:

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

Dovresti vedere ogni nome di sezione del tuo models.ini elencato come ID modello.

Una nota sulla stabilità

L’interfaccia di configurazione INI è ancora in evoluzione:

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

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


Utilizzo API: cambio modelli su richiesta

Una volta che il server è in esecuzione, il cambio di modello avviene tramite la standard API compatibile OpenAI. Ti basta impostare il campo "model".

Elenco 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": "Explain router mode in one paragraph"}
    ]
  }'

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": "Write a Python function that reads a CSV file"}
    ]
  }'

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

Esempio Python

Se stai usando 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 coding
response = client.chat.completions.create(
    model="qwen",
    messages=[{"role": "user", "content": "Write a Go HTTP handler"}],
)
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": "What is the capital of 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 richiesta successiva determina se mantenere qwen caricato o fare di nuovo uno swap

Questo risponde direttamente a una domanda comune:

Come può un server LLM locale cambiare modelli senza riavvio

Caricando dinamicamente i modelli per richiesta, non legandoli all’avvio.


Servizio Systemd: configurazione pronta 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 /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 caso di avvio riuscito, vedrai righe che indicano che il server sta ascoltando e che il registro dei modelli è stato caricato. Un rapido controllo di validità:

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

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

Il flag llama-server --metrics espone un endpoint compatibile con Prometheus. Per dashboard specifici 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 di cui dovresti essere consapevoli prima di affidarti a essa in produzione.

Solo un modello in memoria alla volta

Anche se sono definiti più modelli in models.ini, solo uno è residente in VRAM per worker in un dato momento. Il cambio significa un ciclo completo di scarico e ricaricamento.

  • il cambio significa ricaricamento
  • il picco di latenza è inevitabile
  • su un modello tipico da 7B a Q5, un ricaricamento può richiedere 3–10 secondi a seconda della velocità del disco e della banda VRAM

Questo risponde a un’altra domanda chiave:

llama.cpp supporta il servizio di più modelli contemporaneamente

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

Per il consumo VRAM misurato e i token al secondo attraverso le dimensioni dei modelli, i benchmark delle prestazioni LLM coprono il quadro completo. Per numeri specifici per llama.cpp su una GPU da 16 GB — modelli densi e MoE a più dimensioni di contesto — vedi i benchmark llama.cpp per VRAM 16 GB.

Nessun caching intelligente

A differenza di Ollama, che mantiene un pool caldo ed espelle i modelli in base alla recente attività:

  • non esiste alcuna 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 un ricaricamento. 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 coerente sarà veloce. Un carico di lavoro che intreccia più modelli sarà lento. Pianifica di conseguenza la logica di instradamento del tuo cliente — raggruppa le richieste per modello dove possibile.

La configurazione non è stabile

Il supporto INI esiste e funziona nella maggior parte delle build recenti, ma non è completamente standardizzato. I flag e i 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
Cambio modello
Registro incorporato Parziale (INI) Sì (basato su pull)
Gestione memoria Base Avanzata
Espulsione modello Nessuna Basata su TTL
Rifinitura UX Bassa Alta
Compatibilità API OpenAI
Controllo Massimo Opinione
Stabilità configurazione Sperimentale Stabile

Opinione personale

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

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

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 da solo.

Se scegli Ollama, il riassunto dei comandi CLI 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 pone 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
  • instrada la richiesta una volta che il modello è pronto

Per una configurazione pratica, vedi la guida rapida a llama-swap.

Differenza chiave

Aspetto modalità router llama-swap
Incorporato No (binario separato)
Maturità Sperimentale Più stabile
Flessibilità Limitata Alta
Livello controllo Interno Proxy esterno
Configurazione 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 modello non influenza gli altri. Consente anche a ogni modello di eseguire con flag llama-server completamente indipendenti.

Usalo se hai bisogno di:

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

Quando la modalità router nativa è sufficiente

Usa il router incorporato se vuoi:

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

Pensieri finali

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

Risponde alla domanda a lungo attesa:

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

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

Ma non è finito.

Oggi è:

  • abbastanza potente per carichi di lavoro reali
  • promettente come fondamento per un instradamento più sofisticato
  • 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, usa llama-swap mentre l’implementazione nativa matura.

In ogni caso, ottieni comportamento simile a Ollama, senza nascondere la meccanica.

Iscriviti

Ricevi nuovi articoli su sistemi, infrastruttura e ingegneria AI.