Self-distillation semplice: un LLM che migliora nel codice imparando dai propri output

Ricercatori di Apple mostrano che un modello può migliorare a scrivere codice riaddestrandosi sui propri output grezzi, senza verificatore, insegnante o reinforcement learning. Rileggiamo il metodo e, soprattutto, perché funziona.

Immaginate uno studente che, alla vigilia dell’esame, non ha più esercizi svolti da nessuno: niente soluzioni ufficiali, niente professore che corregga, nessun modo di sapere quali dei suoi tentativi siano giusti. Fa comunque una cosa apparentemente inutile: risolve di nuovo i problemi che ha già affrontato, ricopia in bella i propri svolgimenti così come gli vengono, e li rilegge. L’intuizione dice che da questo giro a vuoto non dovrebbe imparare nulla di nuovo. Eppure, al banco, va meglio di prima. È più o meno quello che descrive un paper firmato da un gruppo di Apple, con un titolo che rinuncia a ogni solennità: Embarrassingly Simple Self-Distillation Improves Code Generation. Un modello linguistico migliora a scrivere codice riaddestrandosi sui propri output grezzi, senza che nessuno gli dica quali fossero corretti.

Cosa prova a sostituire

Per capire perché la cosa sia notevole bisogna sapere contro cosa si misura. Man mano che ai modelli si chiedono compiti di programmazione più difficili, il vero collo di bottiglia diventa il segnale di addestramento: le soluzioni scritte da esseri umani sono costose, e le alternative automatiche hanno tutte un prezzo. La distillazione da un insegnante richiede un modello più forte da cui copiare, e per costruzione non può superarne il tetto. Il reinforcement learning con reward verificabile — la ricetta dietro molti modelli di reasoning recenti — pretende un verificatore che esegua il codice su casi di test per ogni problema, ed è una macchina operativamente complessa e a volte instabile. Le scorciatoie non supervisionate, come premiare il voto di maggioranza o minimizzare l’entropia, mostrano promesse iniziali ma tendono a barare sul premio e a collassare se le si spinge troppo a lungo.

La domanda del paper taglia corto: un modello può migliorare senza nessun dato etichettato e nessuna verifica esterna? Il metodo proposto, simple self-distillation (SSD), è disarmante nella sua economia. Serve solo un insieme di problemi e il modello stesso. Niente soluzioni scritte a mano, niente risposte di riferimento, niente insegnante, niente reward model, niente verificatore, nessun ambiente di esecuzione, nessuna forma di reinforcement learning.

Il meccanismo: tre passi e nessun giudice

La procedura sta in tre mosse. Primo: si campiona dal modello di partenza una soluzione per ogni problema, usando una certa temperatura di campionamento $T_{\text{train}}$ e un troncamento del vocabolario (top-k, top-p). Secondo: si fa fine-tuning supervisionato standard su quegli output grezzi, minimizzando la solita cross-entropy sui token generati.

$$\mathcal{L}(\theta) = -\,\mathbb{E}_{(x,y)\sim\mathcal{D}_{\text{SSD}}}\sum_{t=1}^{|y|} \log p_\theta\!\left(y_t \mid x,\, y_{Terzo: si mette in produzione il modello riaddestrato, decodificando a una temperatura $T_{\text{eval}}$. Il punto delicato è nel primo passo: gli output non vengono verificati in alcun modo. Nessuna esecuzione, nessun test, nessun filtro per correttezza — solo una pulizia sintattica minima per togliere risposte vuote o abbozzi di una riga. E basta un singolo campione per problema: gli autori partono dal sottoinsieme seed del dataset rSTARcoder, circa 10 000 problemi di programmazione competitiva, con una sola soluzione campionata ciascuno.

Simple self-distillation: il modello impara da se stesso Modello base campiona Ttrain I propri output grezzi non verificati fine-tune SFT Modello pθ* riaddestrato decodifica Teval pass@1 più alto Senza: verificatore insegnante reward / RL esecuzione

Il ciclo completo: campiona una soluzione per problema, riaddestra sul risultato grezzo, decodifica. Nessun giudice interviene mai a dire cosa era corretto.

Perché mai dovrebbe funzionare

Qui il paper diventa interessante, perché non si accontenta di mostrare che funziona: prova a spiegare il perché. La chiave è quella che gli autori chiamano il conflitto tra precisione ed esplorazione. Il codice, sostengono, alterna due tipi di posizioni. Ci sono i lock, punti in cui sintassi e contesto lasciano pochissima ambiguità: dopo if len(arr) il modello sa quasi con certezza cosa scrivere, ma una lunga coda di alternative plausibili conserva comunque un po’ di probabilità. E ci sono i fork, punti in cui più continuazioni sono genuinamente valide: iniziando il corpo di una funzione si può aprire con un ciclo, una ricorsione o l’inizializzazione di una struttura dati, e ciascuna scelta porta a un algoritmo diverso.

Il problema è che una singola temperatura di decodifica deve servirli entrambi, e le loro richieste sono opposte. La temperatura riscala l’intera distribuzione secondo la legge $p_T(v) \propto p(v)^{1/T}$: alzarla appiattisce le differenze e dà una chance alle alternative, abbassarla accentua il picco dominante. Ma abbassare la temperatura per blindare un lock affama i fork della diversità che gli serve; alzarla per esplorare ai fork fa riemergere la coda di distrattori ai lock. Qualunque impostazione globale è quindi un compromesso: la temperatura che aiuta i bivi è esattamente quella che lascia rientrare gli errori dove servirebbe precisione.

SSD, argomentano gli autori, scioglie proprio questo nodo. Riaddestrare su campioni presi a temperatura alterata e con la coda troncata rimodella le distribuzioni in modo dipendente dal contesto: comprime il supporto — taglia via la coda diffusa di token inutili — e ridistribuisce la massa nella testa che resta. Ai lock la compressione domina, il distrattore sparisce e il token dominante diventa difficile da spodestare, formando un picco netto. Ai fork sopravvivono più continuazioni valide, che si appiattiscono in un plateau: il modello resta esplorabile dove l’esplorazione paga. È un riassestamento locale, non un affilamento uniforme — ed è per questo che nessuna regolazione della sola decodifica può replicarlo.

Come SSD rimodella le due posizioni LOCK · serve precisione token ordinati per probabilità FORK · serve esplorazione token ordinati per probabilità modello base dopo SSD

Ai lock la coda di distrattori viene rasa e la massa si concentra in una spiga. Ai fork la coda inutile si accorcia, ma le prime continuazioni valide restano e si livellano in un plateau. Stessa regola, effetti opposti a seconda del contesto.

I numeri, senza arrotondare per eccesso

Il risultato di punta: su LiveCodeBench v6, Qwen3-30B-Instruct passa dal 42,4% al 55,3% di pass@1 — quasi tredici punti, circa il 30% in più in termini relativi. Il guadagno non è uniforme, e questo è forse il dato più onesto: si concentra sui problemi difficili. Sempre per lo stesso modello, il pass@5 sui problemi hard sale dal 31,1% al 54,1%, segno che SSD non si limita ad affilare una sola risposta dominante ma preserva diramazioni utili. L’effetto non è un capriccio di un singolo modello: si ripete su cinque modelli di due famiglie diverse (Llama e Qwen), tre scale (4B, 8B, 30B) e sia nelle varianti instruct sia in quelle thinking. Ogni modello valutato migliora.

La verifica più importante è però un’altra: e se bastasse ritoccare la temperatura di decodifica del modello originale, senza riaddestrare nulla? Gli autori spazzano le impostazioni di decodifica del modello base e trovano curve sorprendentemente piatte — per Qwen3-30B-Instruct il pass@1 oscilla tra 41,3% e 43,5%, appena 2,2 punti di escursione. Contro il miglior punto raggiungibile solo con la decodifica, SSD resta avanti di 11,8 punti sul totale, e il margine si allarga sui problemi difficili (+13,3 punti sul pass@1 hard, +19,4 sul pass@5 hard). È l’argomento più solido del paper: il cambiamento avviene dentro il modello, in un modo che nessuna configurazione di decodifica sa imitare. Un’osservazione secondaria, ma elegante: le due temperature si compongono. Definendo una temperatura efficace $T_{\text{eff}} = T_{\text{train}} \cdot T_{\text{eval}}$, le prestazioni seguono bene questa singola grandezza, con un massimo intorno a $T_{\text{eff}} \approx 1{,}2$.

Cosa il paper non promette

Vale la pena tenere i piedi per terra. Lo studio è circoscritto alla generazione di codice, scelta non casuale: è proprio la struttura del compito — l’alternanza netta di lock e fork — a rendere il meccanismo visibile e misurabile. Che lo stesso si trasferisca ad altri domini è plausibile ma non dimostrato qui. La conclusione degli autori è cauta e vale la pena riportarla nei loro termini: SSD non insegna al modello qualcosa che non sapeva, ma suggerisce che i modelli di codice contengono capacità latenti non sfruttate dalla sola decodifica a impostazione fissa. È liberazione di potenziale già presente, non creazione di conoscenza nuova.

Restano poi le ombre note dei metodi senza verifica. Gli stessi autori ricordano che le tecniche non supervisionate rischiano il collasso e il reward hacking se spinte a oltranza, e collocano SSD accanto ma non dentro quella famiglia — resta un punto da sorvegliare in un uso ripetuto. Addestrare su output non verificati significa, in teoria, poter rinforzare anche gli errori: che i numeri migliorino comunque è la sorpresa, non la garanzia. E l’esperimento è sostanzioso — fine-tuning con Megatron-LM su otto GPU B200 — quindi «semplice» descrive l’idea, non il costo di riproduzione.

Perché tenerlo d’occhio

Al netto delle cautele, la posta in gioco è chiara. Se un modello può migliorare su un compito difficile riordinando le proprie distribuzioni a partire dai propri output, allora una parte del lavoro che oggi affidiamo a verificatori, insegnanti e reinforcement learning potrebbe essere già disponibile a costo quasi nullo. La lezione ha il sapore controintuitivo dei risultati che restano: il progresso, qui, non arriva aggiungendo un giudice esterno più sofisticato, ma togliendo il vincolo che una singola temperatura imponeva a tutta la frase. Vale la pena ricordarlo la prossima volta che una pipeline promette guadagni solo in cambio di più infrastruttura.

Il paper

Ruixiang Zhang, Richard He Bai, Huangjie Zheng, Navdeep Jaitly, Ronan Collobert, Yizhe Zhang, Embarrassingly Simple Self-Distillation Improves Code Generation, Apple, aprile 2026. Codice: github.com/apple/ml-ssd. Preprint arXiv: arxiv.org/abs/2604.01193.

I commenti sono riservati agli iscritti.

Accedi per commentare