Architettura · Sistema
2026-10-05
MoE architetturale vs. Mixture of Specialists
Quando si parla di modelli "a esperti", si confondono spesso due cose molto diverse:
il Mixture of Experts (MoE) come tecnica interna a un singolo modello, e il Mixture of Specialists
come architettura di sistema composta da più modelli distinti. La differenza è sostanziale.
MoE architetturale
In un modello MoE come Mixtral 8×7B, ogni layer del transformer
contiene N reti feed-forward in parallelo, chiamate esperti. Un meccanismo di gating
(una piccola rete che apprende anch'essa) valuta ogni token in ingresso e lo instrada
verso k-di-N esperti, tipicamente 2 su 8. Il calcolo è quindi sparso: molti
parametri totali, pochi attivi per ogni token.
Il risultato pratico è che Mixtral 8×7B ha circa 47 miliardi di parametri totali
ma usa attivamente circa 14 miliardi per ogni forward pass. Il costo di inferenza
è simile a un modello da 14B, con la capacità di un modello da 47B.
Questa architettura vive interamente dentro un singolo file di pesi: non è separabile,
non è modulabile, non può essere estesa senza riaddestrare tutto.
Mixture of Specialists
Il Mixture of Specialists è un'architettura di sistema, non di modello.
N modelli distinti, ognuno addestrato o fine-tuned per un dominio specifico,
vengono coordinati da un componente di routing che riceve l'input dell'utente
e decide quale specialista chiamare.
È una tecnica usata in produzione da anni, spesso senza darle un nome formale.
I vantaggi rispetto a un singolo modello generalista della stessa dimensione totale sono concreti:
ogni specialista lavora su una distribuzione molto più stretta, raggiunge performance
più alte sul proprio dominio, e può essere aggiornato o sostituito senza toccare gli altri.
La distinzione chiave: MoE è un'ottimizzazione interna a un singolo modello,
non separabile. Mixture of Specialists è un pattern architetturale a livello di sistema,
componibile e modificabile nel tempo.
Fine-tuning · Efficienza
2026-10-05
LoRA adapters — la chiave per la modularità efficiente
LoRA (Low-Rank Adaptation) è la tecnica che rende economicamente sostenibile
il Mixture of Specialists applicato a modelli piccoli. L'idea di base è semplice:
invece di modificare tutti i parametri
del modello durante il fine-tuning, si congelano i pesi originali e si aggiungono
due piccole matrici per ogni layer.
Come funziona
Per ogni layer del transformer, LoRA introduce due matrici: A di dimensioni
d_model × r e B di dimensioni r × d_model, dove r è il rank,
un iperparametro tipicamente tra 4 e 64. Il delta di pesi che il fine-tuning
introdurrebbe viene approssimato dal prodotto A × B.
Durante il fine-tuning, solo A e B vengono aggiornati. Il modello base rimane
congelato. Questo riduce il numero di parametri allenabili da decine di milioni
a poche centinaia di migliaia, con un impatto minimo sulla qualità finale
per task ben definiti e distribuzioni strette.
Dimensioni concrete per questo modello
Per il modello SLM da 46M parametri in fp16, con rank r=16:
| Componente |
Memoria (fp16) |
Note |
| Modello base (condiviso) |
~92 MB |
Sempre in memoria, non modificato |
| LoRA adapter per specialista (r=16) |
~8–15 MB |
Swappato in millisecondi |
| Router (46M fine-tuned completo) |
~92 MB |
Classificatore intent |
| Verifier (46M fine-tuned completo) |
~92 MB |
Validazione strutturale output |
| Sistema completo (5 specialist + router + verifier) |
~340 MB totali |
Su 8 GB RAM unificata: ampio margine |
A differenza di N copie complete del modello base, il sistema condivide un unico
modello base in memoria e swappa solo gli adapter. Il costo di switching tra specialisti
è dell'ordine dei millisecondi, non dei secondi.
Costo del fine-tuning
Con LoRA, fine-tunare uno specialista richiede in genere 200–500 esempi annotati
per task ben definiti (classificazione, estrazione di entità con schema fisso, routing).
Su hardware M2 con MPS, il fine-tuning di un adapter per questo modello richiede
ore, non giorni. Il prerequisito fondamentale è un base model già buono:
un modello pre-trained a Chinchilla parity
riduce il dato necessario per ogni fine-tuning di circa un ordine di grandezza
rispetto a un modello pre-trained su corpus ridotto.
Il costo del sistema si concentra nel base model.
Il pre-training fino a Chinchilla parity è il pezzo costoso e non ripetibile.
Tutto il resto — specialisti, router, verifier — si costruisce sopra in modo incrementale.
Architettura · Sistema · Produzione
2026-10-05
Il Modular LLM Stack
Un Modular LLM Stack è un sistema composto da più modelli linguistici piccoli,
ognuno con un ruolo preciso, coordinati da un layer Python che gestisce il flusso
dei dati, le chiamate API esterne e la logica applicativa. È l'alternativa
pratica all'uso di un singolo modello grande per ogni task.
Architettura del sistema
Messaggio utente (italiano)
↓
[Router 46M] ← classifica l'intent: 3–8 categorie
↓
[Base 46M + LoRA_X] ← specialista del dominio appropriato
genera risposta
↓
[Verifier 46M] ← validazione strutturale dell'output
approva / rigetta
↓
Risposta finale ← o escalation a modello più grande
Il layer Python che coordina il sistema si occupa di tutto ciò che non è linguaggio:
chiamate API esterne, conversione di formati, gestione degli errori, escalation,
logging. Il modello non ragiona su questi aspetti — esegue solo la parte linguistica
del task (classificazione, estrazione, generazione di testo strutturato).
Cosa può fare un componente da 46M (con fine-tuning specifico)
| Task |
Affidabilità a 46M |
Note |
| Classificare intent (3–8 classi coarse) |
Alta |
Task binario o multiclasse semplice |
| Estrarre entità nominate (date, importi, nomi) |
Alta su schema fisso |
Con grammar-constrained decoding |
| Convertire linguaggio naturale in JSON (schema fisso) |
Media/Alta con vincoli |
Richiede librerie come outlines |
| Classificare tono, urgenza, rilevanza |
Alta |
Con fine-tuning dominio-specifico |
| Ragionamento multi-step complesso |
Bassa |
Limite architetturale della dimensione |
| Verifica logica profonda dell'output |
Bassa |
Solo sanity check strutturale |
Il problema della metacognizione
Un componente critico di qualsiasi sistema agentico è la capacità di decidere
quando escalare: riconoscere che un task supera le proprie capacità e passarlo
a un modello più grande o a un sistema diverso. Questa è metacognizione,
e i modelli da 46M non la possiedono in modo affidabile.
La soluzione pratica è spostare questa logica nel layer Python: soglie di confidenza
esplicite sull'output del classificatore, lunghezza massima dell'input, complessità
stimata del task. Il modello non decide di escalare — il codice lo decide per lui,
in base a regole esplicite.
Taglie minime per task più complessi
| Task |
Modello minimo pratico |
Opzioni |
| Classificazione intent (3–8 classi) |
46M fine-tuned |
Questo modello |
| Entity extraction (output semi-strutturato) |
1–3B fine-tuned |
LoRA su modello più grande |
| Dialogo multi-turno + JSON affidabile |
7B con function calling |
Mistral 7B, LLaMA 3 8B Instruct |
| Ragionamento complesso, contesti lunghi |
13B+ |
Self-hosted |
| Zero margine di errore in produzione |
API esterna |
Claude, GPT-4 |
Il ruolo di questo progetto nel sistema
Il base model pre-trained a Chinchilla parity
su italiano è il fondamento dell'intero stack. Il fine-tuning degli adapter LoRA
è economico solo se il base model è già buono: una base solida riduce il dato
necessario per ogni specializzazione di circa un ordine di grandezza, e migliora
la qualità dell'output anche con fine-tuning ridotto. Costruire il base model
è il pezzo costoso e non ripetibile. Tutto il resto si aggiunge in modo incrementale.
Grammar-constrained decoding: per ottenere output JSON affidabile
da modelli piccoli, librerie come outlines o lm-format-enforcer
costringono il campionamento a produrre solo token compatibili con uno schema JSON
valido. Questo risolve il problema dell'output malformato senza richiedere
un modello più grande.