SLM — Small Language Model

Architetture Modulari

MoE, LoRA adapters e Modular LLM Stack: come costruire sistemi capaci partendo da modelli piccoli.

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.

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.

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.