Scegliere una famiglia di modelli con ciò che si può verificare
Confrontare Llama, Mistral, Qwen e Gemma con una classifica di punteggi è il modo più rapido di scegliere male: i punteggi pubblici misurano compiti generali, in prevalenza in inglese, e non dicono nulla sui tuoi documenti. Questo articolo confronta le quattro famiglie su ciò che si può leggere in una configurazione o in una licenza e si può calcolare: l'architettura, la memoria della cache, il contesto che entra davvero in una macchina, la licenza, il supporto agli strumenti. La qualità sul tuo compito resta una misura da fare, con il metodo dell'articolo sulla scelta della taglia.
Il risultato, anticipato: per una PMI con una macchina da 16 GB, la differenza più concreta fra le quattro famiglie non è la classifica ma il contesto utilizzabile. A parità di taglia, una famiglia può permetterti di dare al modello un contratto intero, un'altra solo un capitolo, per un fatto di architettura che si calcola in tre righe.
Che cosa dicono le configurazioni
Ogni modello pubblica un file di configurazione con le dimensioni dell'architettura. Quattro numeri bastano a stimare la memoria della cache: il numero di strati, il numero di teste di attenzione per le chiavi e i valori (teste KV), la dimensione di ciascuna testa e il contesto massimo. Quello che segue viene dalle configurazioni lette il 2026-11-13.
- Llama 3.1 8B: 32 strati, 32 teste di attenzione e 8 teste KV, testa da 128, contesto fino a 131.072 token.
- Mistral 7B v0.3: 32 strati, 32 teste e 8 teste KV, testa da 128, contesto massimo 32.768 token.
- Qwen2.5 7B: 28 strati, 28 teste e solo 4 teste KV, testa da 128, contesto massimo 32.768 token.
- Gemma 2 9B: 42 strati, 16 teste e 8 teste KV, testa da 256, contesto massimo 8.192 token, con una finestra scorrevole di 4096.
Il rapporto fra teste di attenzione e teste KV è l'idea dell'attenzione a gruppi (GQA): più teste di domanda condividono la stessa testa di chiavi e valori, e la cache, che memorizza proprio chiavi e valori, si riduce in proporzione. Llama e Mistral condividono ogni testa KV fra quattro teste, Qwen fra sette, e per questo Qwen ha la cache più piccola per token; Gemma ha una testa doppia e più strati, quindi la più grande. È una differenza progettuale che si calcola, non un giudizio di qualità.
La cache per token e il contesto che entra in memoria
La cache per token si calcola moltiplicando due matrici (chiavi e valori) per strati, teste KV, dimensione della testa e due byte per valore in virgola mobile a 16 bit. Il programma seguente lo fa per le quattro famiglie, e poi risponde alla domanda pratica: dato un server con 16 o 32 GB di RAM, dopo aver tolto i pesi del file (dalla pagina della libreria di Ollama), l'overhead e la riserva per il sistema, quanti token di contesto entrano per ciascuna richiesta, con una, due o quattro richieste in parallelo.
Le ipotesi sono tre costanti in testa al codice, da sostituire con le tue misure: la cache a 16 bit, un gibibyte di overhead, un gibibyte e mezzo per il sistema. Per Gemma il calcolo è un tetto, perché la finestra scorrevole riduce la cache reale e il programma non la modella. Il contesto è limitato al massimo dichiarato da ciascun modello.
"""Che contesto entra in una macchina, per quattro famiglie di modelli.
Architettura: config.json dei modelli su Hugging Face (copie dichiarate nell'articolo).
Dimensione del file e finestra di contesto: pagine della libreria Ollama.
Per Gemma 2 la cache e' un TETTO: la sua attenzione a finestra scorrevole di 4096
token su una parte degli strati ridurrebbe la cache reale, e qui non e' modellata.
IPOTESI: cache in f16, 1 GiB di overhead, 1,5 GiB per il sistema.
"""
GIB = 1024 ** 3
OVERHEAD = 1.0 * GIB
SISTEMA = 1.5 * GIB
# nome: (strati, teste KV, dim. testa, contesto massimo dichiarato, GB file Ollama)
M = {
"llama3.1:8b": (32, 8, 128, 131072, 4.9),
"mistral:7b": (32, 8, 128, 32768, 4.4),
"qwen2.5:7b": (28, 4, 128, 32768, 4.7),
"gemma2:9b": (42, 8, 256, 8192, 5.4),
}
def kv_token(strati, kv, hd):
return 2 * strati * kv * hd * 2
print(f"{'modello':13s} {'KiB/token':>9s} {'ctx max':>8s} {'cache al massimo':>17s}")
for n, (st, kv, hd, cmax, gb) in M.items():
b = kv_token(st, kv, hd)
print(f"{n:13s} {b // 1024:9d} {cmax:8d} {b * cmax / GIB:14.1f} GiB")
def contesto_massimo(ram_gb, n, parallele):
st, kv, hd, cmax, gb = M[n]
libero = ram_gb * 1e9 - SISTEMA - OVERHEAD - gb * 1e9
if libero <= 0:
return 0
return min(cmax, int(libero / (kv_token(st, kv, hd) * parallele)))
for ram in (16, 32):
print(f"\ncontesto massimo che entra in {ram} GB di RAM (token, per richiesta)")
for par in (1, 2, 4):
celle = " ".join(f"{n}: {contesto_massimo(ram, n, par):6d}" for n in M)
print(f" {par} in parallelo -> {celle}")
# Output:
# modello KiB/token ctx max cache al massimo
# llama3.1:8b 128 131072 16.0 GiB
# mistral:7b 128 32768 4.0 GiB
# qwen2.5:7b 56 32768 1.8 GiB
# gemma2:9b 336 8192 2.6 GiB
#
# contesto massimo che entra in 16 GB di RAM (token, per richiesta)
# 1 in parallelo -> llama3.1:8b: 64206 mistral:7b: 32768 qwen2.5:7b: 32768 gemma2:9b: 8192
# 2 in parallelo -> llama3.1:8b: 32103 mistral:7b: 32768 qwen2.5:7b: 32768 gemma2:9b: 8192
# 4 in parallelo -> llama3.1:8b: 16051 mistral:7b: 17005 qwen2.5:7b: 32768 gemma2:9b: 5751
#
# contesto massimo che entra in 32 GB di RAM (token, per richiesta)
# 1 in parallelo -> llama3.1:8b: 131072 mistral:7b: 32768 qwen2.5:7b: 32768 gemma2:9b: 8192
# 2 in parallelo -> llama3.1:8b: 93138 mistral:7b: 32768 qwen2.5:7b: 32768 gemma2:9b: 8192
# 4 in parallelo -> llama3.1:8b: 46569 mistral:7b: 32768 qwen2.5:7b: 32768 gemma2:9b: 8192
Si leggono tre fatti. Il primo: la cache di Llama 3.1 al contesto massimo da 131.072 token vale 16 GiB, più di tutta la RAM di una macchina da 16 GB: il contesto «da 128K» del catalogo non è utilizzabile sulla macchina piccola, e con una richiesta alla volta entrano circa 64.000 token. Il secondo: Qwen resta a 32.768 token anche con quattro richieste in parallelo, perché la sua cache è la più piccola. Il terzo: con quattro richieste in parallelo su 16 GB, Mistral scende a circa 17.000 token e Llama a circa 16.000; il parallelismo si paga in contesto.
Il contesto che entra non è il contesto che conviene usare: più il testo è lungo, più il modello impiega a leggerlo prima di rispondere, e la lettura del prompt è la parte più lenta su CPU. Per un assistente documentale, dove l'indice sceglie i passaggi pertinenti (come descritto nell'articolo sul recupero ibrido), bastano di solito poche migliaia di token, e il contesto massimo conta meno della cache per richiesta. Se invece devi dare al modello un documento intero, il contesto è il vincolo da cui partire. La documentazione di Ollama indica che il contesto predefinito è di 4k token sotto i 24 GiB di VRAM; la pagina parla di VRAM e non ho verificato il valore per l'esecuzione solo su CPU, quindi imposta la variabile OLLAMA_CONTEXT_LENGTH in modo esplicito.
Licenze: la riga che cambia con la taglia
La licenza si legge dalla scheda del modello, taglia per taglia, perché può cambiare dentro la stessa famiglia. Dalle schede di Hugging Face del 2026-11-13: Mistral 7B Instruct v0.3 è Apache-2.0; Qwen2.5 7B e 14B sono Apache-2.0, mentre Qwen2.5 3B ha una licenza di ricerca che richiede di chiedere una licenza per l'uso commerciale; Llama 3.1 ha la licenza propria di Meta, con la soglia di 700 milioni di utenti attivi mensili, l'obbligo di riportare «Built with Llama» e il rinvio alla politica d'uso accettabile; Gemma 2 ha una licenza propria di Google, che qui non ho letto per intero.
La conseguenza è un filtro da applicare per primo: se la tua azienda non può accettare una licenza con condizioni (per esempio perché distribuisci il modello dentro un prodotto), le uniche scelte pulite sono quelle con Apache-2.0. Per un uso interno la questione è meno stringente, ma leggere il testo resta necessario: una licenza non si deduce dal nome della famiglia.
Strumenti e italiano: che cosa non si può dire da qui
Due domande tipiche, «funziona bene in italiano?» e «sa chiamare funzioni?», non hanno una risposta verificabile da fonti primarie nello spazio di un articolo. Sul secondo punto c'è un dato parziale: nella libreria di Ollama le pagine di llama3.1, mistral e qwen2.5 riportano il marcatore «tools», mentre quella di gemma2 non lo riporta. È l'indicazione che il formato di chiamata di funzioni è supportato dal modello in quella libreria, non una misura di quanto sia affidabile: un modello può avere il marcatore e sbagliare un argomento una volta su dieci.
Per l'italiano e per l'affidabilità degli strumenti serve una prova sul tuo caso. Prepara venti domande vere con la risposta attesa, falle girare sui candidati rimasti dopo i filtri di licenza e memoria, e conta gli errori; ricorda dall'altro articolo che con poche domande un risultato è troppo incerto per dichiarare un vincitore, e che le differenze piccole fra modelli simili sono quasi indimostrabili. Se due modelli sono pari sul tuo insieme, vince quello che ha la licenza più semplice e la cache più piccola.
Una procedura di scelta in quattro passi
L'ordine dei passi non è casuale: ciascuno elimina candidati con un controllo più economico di quello successivo.
- Licenza: scarta i modelli le cui condizioni non puoi accettare.
- Memoria e contesto: con il programma sopra, scarta quelli che non danno il contesto che ti serve nella macchina che hai.
- Capacità sul tuo compito: prova i rimasti sul tuo insieme di domande, con la funzionalità che ti serve (strumenti, lingua).
- Costo e velocità: fra i pari, prendi il più piccolo; il confronto dei costi è nell'articolo sui costi, e la velocità dipende dalla banda di memoria come mostra il pezzo sul server.
Il vantaggio dell'ordine è che i primi due passi non richiedono nessuna esecuzione e non costano tempo. La prova del terzo passo, che costa tempo, si fa su pochi modelli. E il quarto vale solo se il terzo non ha già designato un vincitore: un modello più grande che sbaglia meno vale spesso la differenza di costo, e lo dice il costo, non la classifica; per capire che cosa succede sotto carico c'è l'articolo sulla scalabilità (da 1 a 50 utenti).
Domande frequenti
Quale modello aperto è il migliore per una PMI?
Nessuno in assoluto: dipende dalla licenza che puoi accettare, dalla memoria della macchina e dalla qualità sul tuo compito. L'articolo ordina i controlli dal più economico al più costoso, in modo da provare solo i candidati sopravvissuti.
Perché la cache di Qwen2.5 7B è più piccola di quella di Llama 3.1 8B?
Perché ha 4 teste KV e 28 strati contro 8 teste e 32 strati. Con testa da 128 e valori a 16 bit la cache è di 56 KiB per token contro 128 KiB: meno di metà, a parità di contesto.
Un contesto di 128K token funziona su un server da 16 GB?
Non per Llama 3.1 8B con le ipotesi dell'articolo: la sola cache a quel contesto occupa 16 GiB. Con una richiesta alla volta ne entrano circa 64.000, e con quattro in parallelo circa 16.000.
Che cosa sai fare adesso
Sai leggere da una configurazione i quattro numeri che fissano la cache, sai calcolare quanto contesto entra nella tua macchina e come cala col parallelismo, e sai che la licenza cambia con la taglia dentro la stessa famiglia. Hai una procedura che applica prima i controlli economici, e sai che italiano e affidabilità degli strumenti restano da misurare sul tuo caso. Il passo seguente della serie è la valutazione della qualità del recupero e delle risposte.
Nella stessa serie trovi anche la privacy e il GDPR con un modello in casa e il riepilogo con la scheda di decisione.
Fonti
- config.json di Llama 3.1 8B (copia di NousResearch) - strati, teste KV e contesto massimo; il repository ufficiale di Meta richiede l'accettazione della licenza, per questo ho letto la copia, consultata il 2026-11-13
- config.json di Mistral 7B v0.3 e di Qwen2.5-7B-Instruct - architettura per la cache, consultate il 2026-11-13
- config.json di gemma-2-9b-it (copia di unsloth) - strati, teste, dimensione della testa e finestra scorrevole; il repository di Google richiede l'accettazione dei termini, consultata il 2026-11-13
- Ollama, libreria: gemma2 - dimensione del file (5,4 GB) e finestra di 8K; le pagine llama3.1, mistral e qwen2.5 della stessa libreria per dimensioni, contesto e marcatore «tools», consultate il 2026-11-13
- Ollama, Context length - contesti predefiniti per quantità di VRAM e variabile OLLAMA_CONTEXT_LENGTH, consultata il 2026-11-13
- Llama 3.1 Community License Agreement - soglia di 700 milioni di utenti, «Built with Llama» e politica d'uso accettabile, consultata il 2026-11-13
- API di Hugging Face, scheda di Qwen2.5-3B-Instruct - licenza «qwen-research»; stesso endpoint per le licenze degli altri modelli citati, consultati il 2026-11-13
Il programma è stato eseguito con Python 3.14.4 (python3 -I), due volte, con uscita identica. Nessun modello è stato scaricato o eseguito. La cache è calcolata dall'architettura con ipotesi dichiarate; per Gemma 2 è un tetto perché la finestra scorrevole non è modellata. La licenza di Gemma 2 non è stata letta per intero; punteggi di benchmark, qualità in italiano e affidabilità degli strumenti non sono riportati perché non verificati.

Commenti
Caricamento commenti...
Accedi per commentare