SLM nel 2026: Panoramica dei Small Language Models e Benchmark
Nel 2023 "modello AI" significava quasi sempre GPT-4 o Claude. Nel 2026, il panorama e radicalmente diverso: Phi-4-mini (3.8 miliardi di parametri) supera Mixtral 8x7B (46B) su benchmark di ragionamento matematico, SmolLM2 da 135 milioni di parametri gira su Raspberry Pi 4, e Gemma 3n E4B ha un LMArena Elo superiore a 1300 - piu alto di molti modelli da 70B di un anno fa. L'era dei Small Language Models e arrivata, e ha implicazioni concrete per chi sviluppa applicazioni AI.
Cosa Imparerai
- La mappa dei principali SLM nel 2026: Phi-4-mini, Gemma 3n, Qwen 3, SmolLM2, DeepSeek
- Come interpretare i benchmark: MMLU, HumanEval, MATH, GPQA
- Quale modello scegliere per task di coding, ragionamento, chat e classificazione
- Hardware richiesto per inferenza locale con ciascun modello
- Come eseguire benchmark personalizzati sul proprio use case
Cosa Definisce un "Small" Language Model nel 2026
La definizione di "small" e cambiata nel tempo. Nel 2024, "piccolo" significava sotto 7B parametri. Nel 2026, con modelli da 1B che competono con i 13B di due anni fa, la soglia pratica si e spostata: consideriamo SLM i modelli sotto i 10B parametri che possono girare su hardware consumer senza quantizzazione aggressiva.
| Modello | Parametri | Creatore | Licenza | VRAM (fp16) |
|---|---|---|---|---|
| SmolLM2 | 135M - 1.7B | HuggingFace | Apache 2.0 | 0.3 - 3.5 GB |
| Phi-4-mini | 3.8B | Microsoft | MIT | 7.6 GB |
| Gemma 3n E4B | 4B eff. | Gemma ToS | 8 GB | |
| Qwen 3 (1.7B) | 1.7B | Alibaba | Apache 2.0 | 3.4 GB |
| Qwen 3 (7B) | 7B | Alibaba | Apache 2.0 | 14 GB |
| DeepSeek-R1 (7B) | 7B distilled | DeepSeek | MIT | 14 GB |
| Mistral 7B v0.3 | 7B | Mistral AI | Apache 2.0 | 14 GB |
| Llama 3.2 (3B) | 3B | Meta | Llama 3.2 | 6 GB |
Benchmark: Come Interpretarli Correttamente
I benchmark accademici sono utili ma vanno interpretati con cautela. Un modello che eccelle su MMLU (conoscenza generale) potrebbe essere inadeguato per generare codice Python pulito. Ecco i principali benchmark e cosa misurano realmente.
Benchmark Accademici Principali
# Confronto benchmark principali (valori approssimativi, Febbraio 2026)
benchmarks = {
"Phi-4-mini (3.8B)": {
"MMLU": 72.8, # Conoscenza generale, 57 soggetti
"HumanEval": 62.3, # Completamento codice Python
"MATH": 70.5, # Ragionamento matematico (AMC/AIME)
"GPQA Diamond": 36.2, # PhD-level science questions
"MT-Bench": 7.8, # Conversazione multi-turno (1-10)
},
"Gemma 3n E4B": {
"MMLU": 74.1,
"HumanEval": 58.7,
"MATH": 65.3,
"GPQA Diamond": 34.8,
"MT-Bench": 8.1,
"LMArena Elo": 1312, # Confronto umano (stile chess ELO)
},
"Qwen 3 7B": {
"MMLU": 78.3,
"HumanEval": 72.1,
"MATH": 78.9,
"GPQA Diamond": 41.2,
"MT-Bench": 8.4,
},
"DeepSeek-R1 7B distilled": {
"MMLU": 75.2,
"HumanEval": 68.4,
"MATH": 82.3, # Eccelle nel ragionamento matematico
"GPQA Diamond": 38.7,
"MT-Bench": 8.0,
},
# Per confronto: modelli piu grandi
"Mixtral 8x7B (46B)": {
"MMLU": 71.4, # Phi-4-mini (3.8B) lo supera!
"HumanEval": 60.1,
"MATH": 66.8,
},
}
# NOTA IMPORTANTE: i benchmark non misurano tutto
# - Hallucination rate (frequenza di invenzioni plausibili)
# - Instruction following su task complessi
# - Context handling su documenti lunghi
# - Velocita di inferenza su hardware specifico
# - Consumo energetico
Come Costruire un Benchmark sul Proprio Use Case
from lm_eval.api.model import LM
from lm_eval import evaluator
import json
def benchmark_slm_for_custom_task(
model_name: str,
task_examples: list[dict],
metric_fn: callable
) -> dict:
"""
Benchmark di un SLM su un task personalizzato.
task_examples: lista di {"input": str, "expected": str}
metric_fn: funzione che restituisce float 0-1 (accuracy, F1, etc.)
"""
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16,
device_map="auto"
)
results = []
total_time = 0
for example in task_examples:
import time
start = time.time()
inputs = tokenizer(example["input"], return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=256,
temperature=0.1, # bassa temperatura per task deterministici
do_sample=False
)
elapsed = time.time() - start
generated = tokenizer.decode(
outputs[0][inputs.input_ids.shape[1]:],
skip_special_tokens=True
)
score = metric_fn(generated, example["expected"])
results.append({
"input": example["input"][:50],
"expected": example["expected"],
"generated": generated,
"score": score,
"latency_ms": elapsed * 1000
})
total_time += elapsed
avg_score = sum(r["score"] for r in results) / len(results)
avg_latency = sum(r["latency_ms"] for r in results) / len(results)
return {
"model": model_name,
"task_score": round(avg_score, 4),
"avg_latency_ms": round(avg_latency, 1),
"total_examples": len(results),
"hardware": torch.cuda.get_device_name(0) if torch.cuda.is_available() else "CPU",
"detail": results
}
# Esempio di uso per classificazione del sentiment in italiano
sentiment_examples = [
{"input": "Classifica il sentiment: 'Il prodotto e eccellente!' -> ", "expected": "positivo"},
{"input": "Classifica il sentiment: 'Esperienza terribile, non lo raccomando' -> ", "expected": "negativo"},
# ... 100 esempi dal proprio dataset reale ...
]
def exact_match(generated: str, expected: str) -> float:
return 1.0 if expected.lower() in generated.lower() else 0.0
# Eseguire il benchmark su piu modelli
for model in ["microsoft/phi-4-mini", "Qwen/Qwen3-7B", "google/gemma-3n-e4b"]:
result = benchmark_slm_for_custom_task(model, sentiment_examples, exact_match)
print(f"{model}: score={result['task_score']}, latency={result['avg_latency_ms']}ms")
Hardware Requirements: Cosa Serve per Girare i SLM
Uno dei vantaggi principali dei SLM e che girano su hardware consumer. Ecco la guida pratica.
| Hardware | VRAM / RAM | Modelli Compatibili (fp16) | Tokens/sec (aprox) |
|---|---|---|---|
| MacBook M3 Pro (18GB) | 18 GB unified | Phi-4-mini, Gemma 3n, Llama 3.2 3B | 25-40 tok/s |
| MacBook M4 Max (48GB) | 48 GB unified | Tutti i 7B, Llama 3 8B | 60-80 tok/s |
| RTX 4060 (8GB) | 8 GB VRAM | Phi-4-mini q4, SmolLM2 1.7B | 35-55 tok/s |
| RTX 4070 (12GB) | 12 GB VRAM | Phi-4-mini fp16, Qwen 3 7B q4 | 50-70 tok/s |
| RTX 4090 (24GB) | 24 GB VRAM | Tutti i 7B fp16, Llama 3 8B | 100-130 tok/s |
| Server A100 (80GB) | 80 GB VRAM | Modelli fino a 40B | 200-400 tok/s |
# Verificare se un modello entra nella VRAM disponibile
def check_model_fits_vram(
model_name: str,
quantization: str = "fp16",
safety_margin: float = 0.85
) -> dict:
"""
Stima il VRAM necessario e verifica la compatibilita.
quantization: 'fp32', 'fp16', 'int8', 'int4' (gguf q4)
"""
import torch
# Stima parametri del modello
param_counts = {
"microsoft/phi-4-mini": 3.8e9,
"google/gemma-3n-E4B": 4.0e9,
"Qwen/Qwen3-7B": 7.6e9,
"deepseek-ai/DeepSeek-R1-Distill-Qwen-7B": 7.6e9,
"meta-llama/Llama-3.2-3B": 3.2e9,
"HuggingFaceTB/SmolLM2-1.7B": 1.7e9,
}
bytes_per_param = {
"fp32": 4, "fp16": 2, "bf16": 2, "int8": 1, "int4": 0.5
}
params = param_counts.get(model_name, 0)
if params == 0:
return {"error": f"Model {model_name} not in database"}
model_vram_gb = (params * bytes_per_param.get(quantization, 2)) / 1e9
overhead_gb = 1.5 # KV cache + activations
total_vram_gb = model_vram_gb + overhead_gb
available_vram = 0
if torch.cuda.is_available():
available_vram = torch.cuda.get_device_properties(0).total_memory / 1e9
elif hasattr(torch.backends, 'mps') and torch.backends.mps.is_available():
# Apple Silicon: usare la memoria di sistema disponibile
import psutil
available_vram = psutil.virtual_memory().available / 1e9 * 0.7
fits = total_vram_gb <= available_vram * safety_margin
return {
"model": model_name,
"quantization": quantization,
"model_vram_gb": round(model_vram_gb, 2),
"total_with_overhead_gb": round(total_vram_gb, 2),
"available_gb": round(available_vram, 2),
"fits": fits,
"recommendation": "OK" if fits else
f"Insufficiente: prova int4 o un modello piu piccolo"
}
# Test
for model in ["microsoft/phi-4-mini", "Qwen/Qwen3-7B"]:
for quant in ["fp16", "int8", "int4"]:
result = check_model_fits_vram(model, quant)
status = "OK" if result["fits"] else "NO"
print(f"[{status}] {model} ({quant}): {result['total_with_overhead_gb']:.1f}GB needed")
Quale SLM Scegliere per il Tuo Use Case
La scelta del modello dipende principalmente dal task. Ecco la guida pratica basata sui benchmark e sui test della community nel 2026.
Raccomandazioni per Use Case
- Coding (Python, TypeScript, SQL): Qwen 3 7B o DeepSeek-R1 7B - best in class per i 7B
- Ragionamento matematico/logico: DeepSeek-R1 7B distillato - enorme miglioramento rispetto al base
- Chat e assistente generico: Phi-4-mini o Gemma 3n - miglior quality/size ratio
- Classificazione e NLU semplice: SmolLM2 1.7B - gia oltre la soglia per molti task
- On-device mobile: Gemma 3n E4B (ottimizzato per NPU) o SmolLM2 135M
- RAG italiano: Phi-4-mini (multilingual forte) o Mistral 7B v0.3
Conclusioni
Il 2026 ha definitivamente validato l'era dei Small Language Models: modelli da 3-7B con la giusta architettura e il giusto training data battono modelli 10x piu grandi di due anni fa. La scelta non e piu "LLM vs SLM" ma "quale SLM per quale task su quale hardware".
Il prossimo articolo della serie confronta in dettaglio Phi-4-mini e Gemma 3n: le due scelte piu interessanti per l'edge deployment nel 2026, con benchmark side-by-side su coding, ragionamento e task conversazionali in italiano e inglese.
Serie: Small Language Models
- Articolo 1 (questo): SLM nel 2026 - Panoramica e Benchmark
- Articolo 2: Phi-4-mini vs Gemma 3n - Confronto Dettagliato
- Articolo 3: Fine-tuning con LoRA e QLoRA
- Articolo 4: Quantizzazione per Edge - GGUF, ONNX, INT4
- Articolo 5: Ollama - SLM Localmente in 5 Minuti

Commenti
Caricamento commenti...
Accedi per commentare