← Tutti gli articoli

Che cos'è un modello abliterated?

20 ago 2026 · 6 min di lettura · abliteration, uncensored-models

Un modello abliterated è un normale modello open-weight a cui il comportamento di rifiuto è stato rimosso chirurgicamente modificandone i pesi — non riaddestrandolo, e non avvolgendolo in un prompt ingegnoso. Il nome è una fusione di ablate (asportare) e obliterate (cancellare), e descrive il meccanismo con precisione: si individua la singola direzione nello spazio delle attivazioni che trasporta il segnale "questa dovrei rifiutarla", e poi si fa in modo che la rete non possa mai più scrivere quella direzione.

La tecnica nasce dal lavoro di interpretabilità che mostra come, nei transformer con tuning per la chat, il rifiuto sia mediato in larga parte da una sola direzione lineare. È questo risultato a rendere l'intera operazione economica. Se il rifiuto fosse spalmato su migliaia di feature che interagiscono tra loro, rimuoverlo richiederebbe la discesa del gradiente. Poiché invece si concentra, rimuoverlo richiede algebra lineare.

Il rifiuto vive nel residual stream

Il residual stream di un transformer è il vettore che si porta avanti lungo tutta la rete, uno per ogni posizione di token, da cui ogni blocco legge e in cui ogni blocco riscrive. Le teste di attenzione e gli MLP vi sommano i propri output; niente lo sovrascrive. Grazie a questa struttura additiva, una direzione nel residual stream significa più o meno la stessa cosa al layer 10 e al layer 40, ed è esattamente la proprietà che permette di parlare della "direzione del rifiuto" come di un singolo oggetto invece che di quaranta oggetti scorrelati.

Per trovarla servono due insiemi di prompt: uno che il modello rifiuta in modo affidabile, uno a cui risponde in modo affidabile. Si eseguono entrambi, si catturano le attivazioni del residual stream a un layer e a una posizione di token fissati (gli ultimi token dell'istruzione funzionano bene, perché è lì che il modello ha finito di leggere la richiesta e non ha ancora iniziato a rispondere), e si prende la differenza delle medie.

python
import torch

def refusal_direction(harmful: torch.Tensor, harmless: torch.Tensor) -> torch.Tensor:
    """Difference-in-means estimate of the refusal direction, unit-normalised.

    Both tensors are [n_prompts, d_model] residual-stream activations captured at
    the same layer and token position. Difference-in-means beats a trained probe
    here: with a few hundred prompts a probe overfits, a mean shift does not.
    """
    r = harmful.mean(dim=0) - harmless.mean(dim=0)
    return r / r.norm()

Si ripete a ogni layer e posizione candidati, ottenendo decine di direzioni candidate, e poi se ne sceglie una. La selezione conta più dell'estrazione: il criterio giusto è ablare questa candidata, poi misurare sia di quanto cala il rifiuto su prompt dannosi tenuti fuori dal campione, sia di quanto si sposta la distribuzione del token successivo sui prompt innocui. Quel secondo numero — tipicamente una divergenza KL rispetto al modello non modificato — è il tuo misuratore di danni. Una candidata che azzera il rifiuto ma sposta pesantemente la distribuzione sugli innocui è una scelta peggiore di una che elimina un po' meno rifiuto per una frazione del danno collaterale.

Come si costruisce un modello abliterated

Una volta ottenuto un vettore unitario r, ci sono due modi per usarlo. Il primo è un hook a tempo di inferenza: a ogni layer, si sottrae la componente dell'attivazione lungo r prima di passarla avanti. Funziona, ma costa un hook a runtime, quindi il modello non è più un semplice checkpoint.

Il secondo — l'abliteration vera e propria — lo incorpora nei pesi. Ogni matrice che scrive nel residual stream riceve un aggiornamento di rango uno che rimuove r dal suo spazio di output: la matrice di embedding, ogni proiezione di output dell'attenzione, ogni down-projection degli MLP.

python
def orthogonalize_(weight: torch.Tensor, r: torch.Tensor) -> None:
    """Project r out of a matrix that writes into the residual stream, in place.

    weight is [d_model, d_in]. After W <- (I - r rT) W, the product W @ x has zero
    component along r for every possible x, so no amount of prompting can put the
    direction back. Rank-one per matrix; no gradients, no optimiser, no dataset of
    answers — only the few hundred prompts used to estimate r.
    """
    weight -= torch.outer(r, r @ weight)

Il risultato è un checkpoint ordinario. Stessa architettura, stesso formato di file, stesso costo di inferenza, si carica in vLLM o llama.cpp senza modifiche. Su una singola GPU l'intera procedura gira in pochi minuti, e la parte costosa è la ricerca delle candidate, non la modifica.

In cosa differisce dal fine-tuning

Il fine-tuning per rimuovere i rifiuti — SFT o DPO su un corpus di risposte accondiscendenti — è un'operazione fondamentalmente diversa. Sposta ogni peso tramite discesa del gradiente, richiede un dataset di risposte e non di soli prompt, costa ore di GPU, e insegna un comportamento nuovo invece di cancellarne uno esistente. Si porta dietro anche lo stile, i bias di lunghezza e le stranezze fattuali che vivono nel corpus di fine-tuning, e rischia il catastrophic forgetting di capacità non correlate.

L'abliteration tocca un sottospazio di rango uno e nient'altro. Questa precisione è il suo principale punto di forza e l'origine della sua principale modalità di fallimento: se lungo r vive qualcos'altro oltre al rifiuto, viene distrutto anch'esso, e nessuna cura nella ricerca delle candidate lo evita del tutto.

In cosa differisce dal jailbreak via prompt

Un jailbreak lascia i pesi intatti e invece guida le attivazioni in una regione in cui il circuito del rifiuto non scatta. È fragile in modi che contano per l'automazione. Brucia token di contesto a ogni chiamata. È non deterministico — lo stesso prompt può passare in un campione ed essere rifiutato in quello successivo. Si rompe in silenzio quando il provider aggiorna il modello o applica una patch a quella specifica formulazione. E poiché il meccanismo di rifiuto è ancora completamente presente, può riaffermarsi a metà generazione, dandoti tre paragrafi di output utile seguiti da "in realtà, non posso continuare".

Un modello abliterated non ha nulla da riaffermare. Il comportamento è stabile lungo l'intera generazione e tra diverse formulazioni del prompt, ed è questa la proprietà che lo rende utilizzabile in una pipeline batch.

Siamo onesti sui compromessi

Un modello abliterated non è un modello migliore. È un modello che ha smesso di dire di no, ed è un'affermazione più ristretta di quanto sembri.

Molti modelli abliterated pubblicati ricevono in seguito un leggero fine-tuning di riparazione per recuperare le capacità degradate — il che reintroduce silenziosamente il costo che la tecnica doveva evitare.

Dove è utile

Il caso d'uso onesto è il lavoro in cui un rifiuto è un errore di misura e non un successo per la sicurezza: harness di red teaming, baseline del tasso di rifiuto, valutazione della robustezza, e analisi di sicurezza in cui l'argomento fa scattare un guardrail anche se il compito è difensivo. unbleep serve modelli abliterated dietro un endpoint compatibile con OpenAI, così puoi puntarci un client esistente e ottenere una baseline stabile. Cosa ci costruisci sopra è responsabilità tua — consulta la policy di uso accettabile per le linee che non superiamo.

Ottieni una chiave API e misura la differenza tu stesso.