Model Editing
La modifica del modello cambia un fatto o un comportamento specifico di un modello addestrato, per esempio una risposta di un LLM, senza riaddestrarlo né alterare output non correlati.
La modifica dei modelli consiste nel modificare in modo mirato un fatto o un comportamento specifico di un modello addestrato, per esempio la risposta che un modello linguistico di grandi dimensioni (LLM) dà a «The Space Needle is located in the city of», senza riaddestrare il modello e senza cambiare le sue risposte a input non correlati. Viene usata soprattutto per correggere, aggiornare o inserire conoscenze fattuali negli LLM, quando il riaddestramento completo è troppo costoso e il semplice fine-tuning su un singolo esempio tende a causare overfitting o a danneggiare altre conoscenze. Un editor calcola una piccola modifica localizzata ai pesi del modello oppure memorizza la modifica al di fuori dei pesi e vi indirizza gli input pertinenti. Il metodo più noto, Rank-One Model Editing (ROME), è stato presentato da Kevin Meng, David Bau, Alex Andonian e Yonatan Belinkov in Locating and Editing Factual Associations in GPT, presentato a NeurIPS 2022.
Come funziona la modifica dei modelli#
Una richiesta di modifica specifica un input, spesso un soggetto e una relazione, e il nuovo output; per esempio, cambiare la città dello Space Needle da Seattle a Parigi. Gli editor si dividono in alcune famiglie:
- Individua e modifica: ROME usa innanzitutto il tracciamento causale, una tecnica di interpretabilità che corrompe e ripristina gli stati nascosti, per individuare dove i modelli GPT recuperano un fatto. Il calcolo determinante si trova negli strati feed-forward (MLP) al centro della rete, in corrispondenza dell'ultimo token del soggetto. ROME tratta la proiezione di output di un MLP come una memoria chiave-valore e inserisce il nuovo fatto con un aggiornamento dei pesi di rango uno in forma chiusa; in GPT-2 XL modifica il livello 18 su 48. MEMIT distribuisce l'aggiornamento su più livelli per inserire migliaia di fatti contemporaneamente.
- Editor appresi: MEND addestra una piccola iper-rete che converte il gradiente dell'esempio di modifica in un aggiornamento dei pesi a basso rango, mantenendo rapide le modifiche anche per i modelli con miliardi di parametri.
- Editor basati sulla memoria: SERAC memorizza le modifiche in una memoria esplicita e usa un classificatore di ambito per inviare gli input relativi a una modifica a un piccolo modello controfattuale, lasciando invariati i pesi di base. GRACE inserisce un codebook di adattatori discreti chiave-valore in un livello per gestire lunghe sequenze di modifiche. Inserire il nuovo fatto nel prompt, come fa la generazione aumentata dal recupero, è l'editor più semplice di questo tipo.
L'aggiornamento di ROME si basa su una proprietà dei livelli lineari: una matrice dei pesi W mappa le chiavi memorizzate ai valori e si può assegnare a una nuova chiave k* un nuovo valore v* aggiungendo una matrice di rango uno. ROME pondera l'aggiornamento con la matrice di covarianza inversa C delle chiavi già viste dal livello, stimata a partire da un campione di testo di Wikipedia; così la modifica viene allontanata dalle direzioni usate dalle chiavi esistenti. Questo esempio PyTorch applica l'aggiornamento a un livello casuale che memorizza 5.000 chiavi e lo confronta con un semplice aggiornamento di rango uno che ignora la covarianza:
import torch
torch.manual_seed(0)
scales = torch.logspace(0, -2, 256) # key dimensions with very different variances, as in real activations
keys = torch.randn(5000, 256) * scales # keys of 5,000 facts the layer already stores
W = torch.randn(128, 256) # the layer maps each key to a value
C = keys.T @ keys / len(keys) # second-moment statistics of the stored keys
k_new = torch.randn(256) * scales # key of the subject to edit
v_new = W @ keys[0] # new value: one already stored for another subject, as in "Seattle" -> "Paris"
# Plain rank-one update vs. ROME's update, which steers the change away from directions stored keys use
plain = W + torch.outer(v_new - W @ k_new, k_new) / (k_new @ k_new)
c_inv_k = torch.linalg.solve(C, k_new)
rome = W + torch.outer(v_new - W @ k_new, c_inv_k) / (k_new @ c_inv_k)
for name, edited in [("Plain rank-one", plain), ("ROME", rome)]:
error = (edited @ k_new - v_new).norm() / v_new.norm()
drift = ((keys @ (edited - W).T).norm(dim=1) / (keys @ W.T).norm(dim=1)).median()
print(f"{name}: new-fact error {error:.4f}, median change on stored facts {drift:.2%}")Entrambi gli aggiornamenti mappano esattamente la nuova chiave sul nuovo valore, con un errore pari a 0.0000. L'aggiornamento semplice modifica l'output mediano delle 5.000 chiavi memorizzate di 10.99%, mentre l'aggiornamento di ROME ponderato per la covarianza lo modifica di 5.02%; pertanto, la modifica altera meno ciò che il livello già sapeva.
Valutazione di una modifica#
Le modifiche vengono valutate contemporaneamente in base a diverse proprietà. L'affidabilità misura se l'input modificato ora produce la nuova risposta; la generalizzazione verifica se accade lo stesso con le parafrasi; la località, detta anche specificità, verifica se gli input non correlati mantengono le risposte precedenti; la trasferibilità misura se il ragionamento che dipende dal fatto lo segue. Gli autori di ROME hanno creato il dataset CounterFact, con 21.919 modifiche controfattuali, per misurare insieme queste proprietà, poiché i benchmark precedenti consentivano ai metodi di sacrificare la specificità a favore della generalizzazione senza che ciò fosse rilevato.
Le modifiche spesso falliscono le prove più difficili. Sulle 5.000 modifiche del benchmark RippleEdits, gli editor più noti non sono riusciti ad apportare modifiche coerenti ai fatti logicamente connessi a quello modificato, mentre una semplice baseline di modifica in-context ha ottenuto il risultato migliore. Gupta et al. hanno rilevato che l'applicazione sequenziale di ROME e MEMIT fa dimenticare al modello le modifiche precedenti e le competenze successive, prima gradualmente e poi bruscamente, limitando così il numero di modifiche che un modello può assimilare.
Modifica dei modelli di visione#
Lo stesso meccanismo di rango uno si applica alle immagini. Santurkar et al. hanno modificato classificatori di immagini riscrivendo la regola applicata da un livello a un concetto visivo; per esempio, mappando la rappresentazione della neve su quella della strada affinché il modello gestisca i veicoli su strade innevate, senza raccogliere nuovi dati di addestramento. Ultralytics YOLOE modifica il proprio head di rilevamento senza gradienti durante l'esportazione: le classi configurate con set_classes() vengono moltiplicate per la convoluzione finale di ogni ramo di classificazione, così il modello esportato rileva il nuovo vocabolario senza addestramento né encoder testuale.
Modifica dei modelli e concetti correlati#
- Fine-tuning: aggiorna molti pesi a partire da un dataset per modificare il comportamento generale. La modifica agisce su una singola coppia input-output e vincola tutto il resto.
- Generazione aumentata dal recupero (RAG): fornisce informazioni aggiornate nel prompt a ogni richiesta e lascia invariato il modello; è facile da annullare e può gestire molti fatti.
- Machine unlearning: rimuove l'influenza di specifici dati di addestramento. La modifica sostituisce o aggiunge un fatto; una modifica che elimina un fatto è una forma di unlearning.
- Aritmetica dei task: somma o sottrae le modifiche dei pesi di interi task sottoposti a fine-tuning. La modifica dei modelli opera sul singolo fatto.
- Interpretabilità meccanicistica: spiega come calcola un modello. Il tracciamento causale di ROME proviene da questo campo e determina quale livello viene modificato.










