LLM su dgx01 — guida

← torna alla consoleIT | EN

Per iniziare

  1. Accedi alla console con le credenziali del cluster HPC (serve essere nel gruppo Hpc.Users).
  2. Guarda se il modello che ti serve è già in esecuzione: i modelli condivisi li può usare chiunque, senza avviarne un altro.
  3. Se no, usa il picker ("Quale modello?"): scegli il tipo di lavoro e avvia il primo suggerito.
  4. Usalo dalla console, oppure dai tuoi programmi con una API key (sezione Uso dai programmi).
  5. Quando hai finito, fermalo: le GPU sono poche e condivise.

Indirizzo unico: — compatibile OpenAI (/v1), Anthropic (/v1/messages) e Jev (/v1/systemone).

Concetti

Quota GPU

dgx01 ha 7 GPU Tesla V100 da 32 GB, condivise con tutto il cluster. Il servizio LLM può usarne al massimo 2 alla volta in totale (non 2 per utente: la quota è unica, perché tutti i job girano come utente di servizio hpc.cluster). Se la quota è piena, una nuova richiesta va in coda in SLURM finché una GPU si libera.

Job dedicato e pod

  • Job dedicato: un modello con le sue 1 o 2 GPU tutte per sé. È la scelta per i modelli grandi e per i motori "esclusivi".
  • Pod: un job con 1 o 2 GPU dentro cui si avviano più modelli, anche di utenti diversi, finché c'è memoria sulla GPU. Esempio: Qwen3.6 su llama.cpp (22 GB) + d1-3B (6 GB) sulla stessa V100, una sola GPU di quota. Avviare un modello dentro un pod esistente non consuma quota.
  • Un pod rimasto senza modelli per 5 minuti si chiude da solo e restituisce le GPU.
  • La GPU fisica di un pod o di un job dedicato la sceglie SLURM tra quelle libere; dentro i pod scegli tu pod e GPU, oppure "automatico" (la GPU più piena in cui il modello entra ancora, per lasciare libere le altre).
  • Motori esclusivi (vLLM, strata, ds4) occupano tutta la memoria libera della scheda: vanno su una GPU vuota. llama.cpp, ollama, colibri e i modelli decisionali condividono.

Condiviso o privato

Un modello avviato è visibile a tutti. Se è condiviso (predefinito) chiunque sia loggato lo può usare; se lo avvii come privato lo usi solo tu (e gli amministratori); un modello privato può usare al massimo 1 GPU. Solo chi l'ha avviato, o un amministratore, lo può fermare.

Durata (walltime)

Avvio di giorno (08–20): massimo 4 ore. Avvio la sera o di notte: massimo 12 ore. Alla scadenza il job termina e il modello si spegne.

Quale modello usare

LavoroPrima sceltaAlternativePerché
Chat generale, assistente, traduzioniGemma 4 26B (llama.cpp)gpt-oss-20b, Qwen3.6-35B~140 token/s su una GPU, buona qualità
Massima qualità, problemi difficiliQwen3.8-Flash-Next (strata)Qwen3.8-27B Q8 (2 GPU)il modello più forte che sta su dgx01 (~50–64 token/s)
CodiceQwen3.8-27B (llama.cpp)Qwen3.8-Flash-Next, gpt-oss-20bdenso, preciso; Qwen3-Coder su colibri è lento
Ragionamento, matematicagpt-oss-20bQwen3.8-Flash-Nextpensato per il ragionamento passo-passo, veloce
Documenti lunghi, RAG, riassuntiQwen3.6-35B su stratavLLM per modelli supportatilegge il prompt 5× più veloce degli altri motori (3400 token/s)
Immagini (grafici, documenti scansionati)Qwen2.5-VL-7B (vLLM)Gemma 4modello visione-linguaggio
Immagini cliniche, quesiti mediciLingshu-7B (vLLM)Qwen2.5-VL-7Baddestrato su dati medici; uso di ricerca, non diagnostico
Classificare, instradare, sì/no, estrarre campiLiquid d1-3Bd1-2B (anche CPU), GLiNER, Laya (CPU)una passata, probabilità calibrate, ~60 ms
Molti utenti insieme sullo stesso modelloun modello su vLLM—gli altri motori servono una richiesta alla volta
Nessuna GPU liberaQwen3.6-35B su CPU (llama.cpp)d1-2B su CPUlento (~9 token/s) ma non usa quota GPU

Velocità misurate su dgx01 con un utente alla volta: "prefill" è la lettura del prompt, "decode" la scrittura della risposta. Un token è circa ¾ di parola inglese, meno in italiano.

Schede dei modelli

Accedi alla console per vedere qui il catalogo aggiornato.

Motori

Lo stesso modello può girare su motori diversi, con prestazioni molto diverse (es. Qwen3.6-35B: prefill 3386 token/s su strata, 638 su llama.cpp, 17 su colibri). Il profilo scelto all'avvio decide il motore.

MotoreCome lavoraSpeculative decodingQuantizzazioniCPUCondivide la GPU

Uso dai programmi

Crea una API key nella console (sezione "Usarli da programmi" → Nuova API key) oppure con llm-serve key create <nome>. La chiave si vede una sola volta: salvala. Non scade con i login; la revochi dalla console.

curl


Python (libreria openai)


opencode


Il campo model è l'id del modello in esecuzione (es. qwen3.8-27b), oppure id@profilo per un'istanza precisa, oppure auto (il miglior modello di chat attivo). GET /v1/models elenca quelli che puoi usare. Il certificato è per ora autofirmato: nei client va accettato (es. curl -k, verify=False).

Da terminale sul cluster

/opt/common/tools/llm-serve/bin/llm-serve login        # credenziali del cluster HPC
llm-serve gpus                 # le 7 GPU, chi le usa, i pod
llm-serve pick documents       # cosa usare per documenti lunghi
llm-serve start gemma-4-26b-a4b            # automatico: in un pod se c'è spazio, altrimenti job dedicato
llm-serve start d1-3b --pod <id> --gpu 3   # in un pod/GPU preciso
llm-serve start qwen3.8-27b --dedicated --private
llm-serve status ; llm-serve stop <job> ; llm-serve logs <job>
eval $(llm-serve env)          # OPENAI_BASE_URL e OPENAI_API_KEY per altri programmi

Modelli decisionali (FDM)

d1, GLiNER2.5-Decide e Laya non scrivono testo: ricevono uno stato (testo, JSON, immagini per d1) e delle domande tipizzate, e rispondono in una sola passata con probabilità calibrate. Ideali per classificare, instradare, fare triage, estrarre campi. L'API è POST /v1/systemone, la stessa di Jev (TypeSafe): un client Jev funziona cambiando solo l'URL base.


Tipo di domandaRispostaModelli
noul (sì/no)probabilità che sia verotutti
choice (anche multiple: true)opzione scelta + probabilità di ciascunatutti
scorelivello su una scala datatutti
text, number, datevalore estratto dal testod1
box, boxesposizione di oggetti in un'immagined1

Prefill e decode

Ogni risposta ha due fasi: il prefill (il modello legge tutto il prompt, conta per documenti lunghi e RAG) e il decode (scrive la risposta un token alla volta, conta per la velocità percepita). I motori sono più o meno bravi nelle due fasi.

Si possono usare due motori diversi, uno per fase?

Su una stessa richiesta no: lo stato interno prodotto dal prefill (la "KV cache") ha un formato diverso per ogni motore e non si passa da uno all'altro. Le alternative, in ordine di utilità su dgx01:

  1. Un motore bravo in entrambe le fasi. strata con Qwen3.6-35B ha il prefill migliore (3386 token/s) e un decode quasi pari al migliore (98 contro 106 di llama.cpp). Per documenti lunghi è la scelta da fare: profilo strata-1gpu.
  2. strata con prefill e decode su due GPU (--split-serve PREFILL,DECODE): lo stesso motore avvia due processi, uno legge il prompt su una scheda e l'altro scrive la risposta sull'altra; la sessione passa dall'uno all'altro in RAM, in automatico. Usa entrambe le GPU della quota per un solo modello. Profilo strata-split-2gpu di Qwen3.6-35B: in test.
  3. Due istanze dello stesso modello e smistamento automatico. Se lo stesso modello è attivo due volte (es. Qwen3.6 su strata e su llama.cpp), il gateway manda le richieste con prompt lunghi (oltre ~4000 token) all'istanza con il prefill più veloce e le altre a quella con il decode più veloce. Ogni richiesta è servita per intero da un motore. Come fare: avvia lo stesso modello con due profili diversi e usa come model l'id senza profilo (qwen3.6-35b-a3b). Costa 2 GPU di quota, oppure 1 GPU + CPU se la seconda istanza è llamacpp-cpu.
  4. Speculative decoding: un modello piccolo "propone" i token e quello grande li verifica a gruppi; accelera il decode senza cambiare il risultato. È già attivo, in automatico, su strata (MTP) per Qwen3.6 e Qwen3.8-Flash-Next. llama.cpp (-md <modello-draft.gguf>) e vLLM lo supportano ma non sono ancora configurati nel catalogo.

Speculative decoding

Un modello piccolo (o le teste MTP già presenti nel modello) propone alcuni token; il modello grande li controlla tutti in una sola passata e tiene quelli giusti. La risposta è identica a quella senza speculazione: cambia solo la velocità con cui viene scritta (decode). Il prefill non cambia.

ModelloProfiloSenzaCon MTPGuadagno
Qwen3.6-35B-A3Bllamacpp-1gpu-mtp99 tok/s150 tok/s+51%
Qwen3.8-27B Q4llamacpp-q4-1gpu-mtp33 tok/s61 tok/s+84%
Gemma-4-26B-A4Bllamacpp-1gpu-mtp109 tok/s151 tok/s+39%

Media su quattro testi (codice, riassunto, testo libero, traduzione), un utente. I profili -mtp usano 1–5 GB di VRAM in più. Le altre tecniche provate servono poco sulle V100: EAGLE3 +10% su gpt-oss-20b e −10% su gpt-oss-120b (esperti in RAM); n-gram aiuta solo quando la risposta ripete il prompt; vLLM 0.8.5 con un draft model +27% in media ma molto variabile. Dettagli: BENCHMARK-dgx01.md §14 e i test nel catalogo (clic sul modello).

Con più utenti insieme (MTP, 16 slot): il guadagno cala con il carico. Qwen3.6 +46% con 1 utente, +4% con 4, −38% con 16; Gemma +52% → +9% → −27%; Qwen3.8-27B (denso) +88% → +33% → +25% con 8 utenti (con 16 utenti e MTP va fuori memoria GPU). Quindi: profili -mtp per uso privato o con pochi utenti (fino a ~4); per un modello condiviso molto usato meglio il profilo senza speculazione.

Sottotipi

MotoreUsabiliAttivo nei profili
llama.cppMTP, EAGLE3, draft model, DFlash, DSpark, n-gramMTP nei profili -mtp
vLLM 0.8.5draft model, n-gram, EAGLE, Medusa, MLP speculator, MTP DeepSeeknessuno
strataMTPMTP in tutti i profili strata
ds4MTP, DSparknessuno
colibriMTP (solo GLM-5.2, Qwen3.8-Flash-Next)nessuno
ollama, fdmnessuno—

Nel catalogo la colonna Speculative indica il sottotipo attivo di ogni profilo.

Come sono misurati i dati

Tutte le misure sono state fatte su dgx01 tra il 27 ottobre e il 2 novembre 2026, con i comandi e i profili del catalogo. Il dettaglio completo (comandi esatti, date, job SLURM) è nel file BENCHMARK-dgx01.md in /opt/common/tools/llm-serve/.

MisuraCome
Prefill (token/s)prompt di ~2000 token, risposta di 1 token: token del prompt ÷ tempo
Decode (token/s)prompt breve, 256 token generati: token generati ÷ (tempo − tempo del solo prompt). I token di "ragionamento" contano
TTFT (s)tempo al primo token: con prompt breve (misurato) e con ~2000 token (= 2000 ÷ prefill)
Avvio (s)dal lancio del container a quando il modello risponde; "freddo" = file del modello tolti dalla RAM del nodo, "caldo" = ancora in RAM
Concorrenzavalori della tabella con 1 utente alla volta; prove separate con 1–16 utenti (vedi "Prefill e decode" e il file dei benchmark)
Finestra di contestodurante le misure: 4096 token (vLLM, llama.cpp), 8192 (strata, colibri, ds4); in servizio vale la colonna "Contesto" del catalogo
VRAMletta da nvidia-smi a modello caricato; per vLLM è la memoria riservata in anticipo

Documenti lunghi (16k–256k token)

Ogni modello è stato provato con prompt da 16k, 32k, 64k, 128k token e fino al suo massimo: i risultati sono nella tendina che si apre cliccando sul nome del modello nel catalogo (riga "contesto lungo"). In sintesi: più il testo è lungo, più lenta è la lettura (un documento da 128k richiede da 1,5 a 6 minuti prima della risposta); per testi oltre 64k vanno meglio Qwen3.8-Flash-Next su strata (oltre 1100 token/s di lettura fino a 256k) e Lingshu / Qwen2.5-VL su vLLM con 2 GPU (fino a 128k); Qwen3.6 oltre 32k conviene su llama.cpp. Su una sola GPU i modelli vLLM arrivano a ~32k, i modelli decisionali d1 a 8k (d1-3B) e 32k (d1-2B).

Finestra di contesto

Ogni modello ha una finestra massima (letta dai suoi metadati: da 32k a 1M token) e ogni profilo una finestra configurata, cioè quanti token (prompt + risposta) può usare una richiesta in quel servizio: di solito 32k, perché finestre più grandi tolgono memoria alla GPU. Nel catalogo la colonna "Contesto" mostra configurata / massima. Una richiesta più lunga della finestra configurata viene rifiutata dal motore.

Avvio a freddo, avvio a caldo e primo token

"A freddo" si usa con due significati diversi; conviene tenerli separati.

1. Il modello non è in esecuzione: bisogna avviarlo

Se il modello che ti serve non è già attivo, prima di poterlo usare va avviato (dalla console o con llm-serve start): questo richiede da pochi secondi a qualche minuto. Il servizio non avvia i modelli da solo alla prima richiesta: una chiamata a un modello spento riceve un errore che dice di avviarlo. Se invece il modello è già attivo (anche avviato da un collega), la richiesta parte subito e conta solo il tempo al primo token.

2. Avvio "a freddo" o "a caldo": dove si trovano i file del modello

Nel catalogo le due colonne dell'avvio si riferiscono a questo:

  • Avvio a freddo: i file del modello non sono nella memoria (RAM) del nodo e vanno letti dallo storage BeeGFS. Succede quando il modello non è stato usato da tempo, o quando la RAM è servita ad altro.
  • Avvio a caldo: il modello è stato usato da poco, quindi il sistema operativo ne tiene ancora i file in RAM e li rilegge da lì, senza passare dallo storage. Avviene in automatico; i file restano in RAM finché la memoria non serve ad altri programmi.

Cosa succede durante un avvio

FaseTempo tipico su dgx01Dipende da freddo/caldo?
attesa di una GPU libera in SLURM (solo se la quota di 2 GPU è occupata)da 0 a oreno (non inclusa nei tempi misurati)
avvio del container1–3 sno
lettura dei pesifreddo: ~1,5 GB/s (23 GB ≈ 15 s; 90 GB ≈ 60 s)
caldo: ~4 GB/s (23 GB ≈ 6 s)
sì, è l'unica fase
copia dei pesi nella memoria della GPUpochi secondino
inizializzazione del motorellama.cpp: secondi · strata: preparazione della cache degli esperti · vLLM: 1–2 minuti (misura della memoria e preparazione dei "CUDA graph") · Qwen3.8-Flash-Next: blocco di 55 GB di esperti in RAMno

Risultato misurato: su dgx01 freddo e caldo differiscono di pochi secondi, e in qualche prova l'avvio a caldo è stato persino più lento, per il carico variabile del nodo. Il motivo è che lo storage BeeGFS è veloce e i suoi server hanno a loro volta una cache, mentre la parte lunga dell'avvio è l'inizializzazione del motore, che non dipende da dove stanno i file. La differenza diventa visibile solo con i modelli molto grandi (80–90 GB).

Tempo al primo token (TTFT)

Con il modello già attivo, una richiesta aspetta prima la lettura del prompt (prefill) e poi riceve la risposta un pezzo alla volta. Il TTFT è il tempo fino al primo pezzo: con una domanda breve è sotto il secondo per quasi tutti i modelli; con un documento di 2000 token va da 0,4 s (vLLM) e 0,7 s (strata) a 3–4 s (modelli grandi su llama.cpp). I valori sono nelle colonne "Avvio" e "TTFT" del catalogo.

In pratica: i modelli usati spesso conviene tenerli attivi e condivisi (nessun avvio, solo TTFT); un modello fermato e riavviato nella stessa giornata di solito parte "a caldo"; i tempi di avvio contano soprattutto per vLLM (2–3 minuti) e per i modelli più grandi.

Caricamento dei modelli e cache

I modelli si leggono direttamente da BeeGFS (/beegfs/datasets/models), senza copia sul disco locale. Misure su dgx01:

Lettura di un modelloVelocità
BeeGFS, file mai letto di recente1,5 GB/s
BeeGFS, file letto di recente (cache dei server di storage)3,0–3,5 GB/s
disco SSD locale di dgx01 (/raid, 7 TB)1,8 GB/s
RAM del nodo (file già letto)3,9 GB/s

Una cache sul disco locale farebbe guadagnare al massimo pochi secondi (Qwen3.6, 23 GB: ~3 s su un avvio di 25–35 s) e richiederebbe la copia preventiva (~80 s per 23 GB). Per questo non c'è: la cache efficace esiste già ed è automatica — la RAM del nodo (503 GB) tiene i modelli usati di recente e libera da sola quelli non usati da più tempo, e i server BeeGFS fanno lo stesso.

Benchmark SWE (qualità sul codice)

Due classifiche pubbliche misurano quanto un modello sa risolvere compiti reali di sviluppo software:

  • SWE-bench Verified (llm-stats.com): percentuale di 500 problemi reali di GitHub risolti; i valori sono dichiarati dai produttori, non verificati.
  • DeepSWE (deepswe.datacurve.ai): pass@1 su 113 compiti lunghi, tutti con lo stesso agente (mini-swe-agent).

Nel catalogo la colonna "SWE %" riporta SWE-bench Verified / DeepSWE. Consultate il 2 novembre 2026, le due classifiche riportano solo Qwen3.6-35B-A3B (73,4 / n.d.), DeepSeek-V4-Flash (79,0 / 53) e GLM-5.3-Flash (n.d. / 63); gli altri modelli del pool non compaiono (le pagine mostrano solo una parte delle voci). Attenzione: sono i risultati dei modelli originali a piena precisione con agenti e impostazioni del produttore, non misure fatte su dgx01 né sulle versioni quantizzate che usiamo.

Caricare e testare un nuovo modello (LOAD/TEST)

Nella console, sezione Carica / testa un modello: si incolla l'indirizzo HuggingFace del modello (per i repository GGUF si può indicare la quantizzazione, es. *Q4_K_M*; per i modelli riservati serve un token HuggingFace, usato solo per il download e non salvato).

  1. Analizza (senza scaricare nulla): legge dai metadati formato, architettura, dimensione, quantizzazione e contesto massimo, e per ogni motore dice se può funzionare sulle V100 e perché (architetture supportate da vLLM 0.8.5 e da llama.cpp, quantizzazioni non supportate, memoria necessaria).
  2. Scarica e testa: scarica il modello nel pool, lancia su ogni motore candidato lo stesso test e benchmark usato per il catalogo (un job SLURM per motore, fino a 45 minuti) e mostra esito, prefill, decode, TTFT, avvio, VRAM ed eventuali errori.
  3. I profili che superano il test vengono aggiunti al catalogo (segnati "utente") e il modello si può avviare come gli altri. I punteggi per tipo di uso sono provvisori finché un amministratore non li rivede.

Limiti: al massimo 2 test alla volta; modelli oltre 200 GB solo per gli amministratori; i test usano la stessa quota di 2 GPU dei modelli in servizio (se è piena vanno in coda). Per vLLM servono i file originali (safetensors), per llama.cpp e strata un repository GGUF.

Tecnologia

  • Sito e API: un servizio Python (FastAPI + uvicorn, HTTPS) eseguito come hpc.cluster su dgx01; pagine in HTML e JavaScript senza framework. Login del cluster HPC tramite PAM/AD.
  • Motori: tutti in container Singularity (/beegfs/datasets/llm/images/*.sif), avviati come job SLURM: vLLM e ollama da immagini ufficiali, llama.cpp, strata, colibri, DwarfStar e il server dei modelli decisionali ricompilati per le V100 (CUDA 12.4, sm_70). Nessun motore è installato sul sistema.
  • Modelli: su BeeGFS, /beegfs/datasets/models/{llm,fdm}. Catalogo: /opt/common/tools/llm-serve/catalog.yaml (+ catalog.d/ per i modelli aggiunti con LOAD/TEST).

Limiti delle V100

  • Niente bf16 né FP8 in hardware: i modelli girano in fp16 o quantizzati; i pesi FP8/NVFP4 (es. Qwen3.6-27B-FP8) non sono utilizzabili.
  • vLLM recente, SGLang e TGI non supportano più queste GPU: vLLM è fermo alla 0.8.5, quindi le architetture più nuove girano in GGUF (llama.cpp, strata).
  • I modelli enormi (DeepSeek-V4, GLM-5.3) girano solo in modo sperimentale e molto lento.

Domande frequenti

Vedo un modello avviato da un collega: posso usarlo?

Sì, se è condiviso (non segnato "privato"): basta usarne l'id. Non puoi fermarlo tu.

Posso caricare un mio modello sulla GPU dove ne gira già un altro?

Sì, se è dentro un pod e c'è memoria: la finestra "Avvia" mostra le GPU dei pod dove il modello entra. Altrimenti puoi usare un'altra GPU (pod nuovo o job dedicato), se la quota di 2 GPU non è già piena.

Dov'è la mia API key?

La crei nella console (o con llm-serve key create) e la vedi solo in quel momento. Il servizio ne conserva solo un'impronta (hash), quindi non può mostrartela di nuovo: se la perdi, revocala e creane un'altra.

Perché il mio modello è "in coda"?

La quota di 2 GPU è occupata (da te o da altri utenti del servizio), oppure SLURM non ha GPU libere su dgx01. Si avvia appena una si libera; intanto controlla se ci sta in un pod esistente.

Quanto dura un modello avviato?

Fino al walltime (4 ore di giorno, 12 di sera/notte) o finché lo fermi. I pod vuoti si chiudono dopo 5 minuti.