Model Editing
モデル編集は、再学習せず、無関係な出力に影響を与えることなく、特定の事実や挙動(たとえばLLMの1つの回答)を変更します。
モデル編集とは、モデルを再学習させず、無関係な入力に対する出力を変えずに、学習済みモデルの特定の事実や振る舞いを狙って変更することです。たとえば、大規模言語モデル(LLM)が「スペースニードルはどの都市にありますか」という質問に答える内容を変更します。LLMの事実知識を修正、更新、追加するために主に使われます。全面的な再学習は費用がかかり、単一の例での単純なファインチューニングは過学習したり、ほかの知識を損なったりしやすいためです。編集手法は、モデルの重みに小規模で局所的な変更を計算するか、重みの外部に編集内容を保存し、関連する入力をそこへルーティングします。最もよく知られた手法であるRank-One Model Editing(ROME)は、Kevin Meng、David Bau、Alex Andonian、Yonatan Belinkovが考案し、NeurIPS 2022で発表したLocating and Editing Factual Associations in GPTで紹介されました。
モデル編集の仕組み#
編集リクエストでは入力(多くの場合、対象と関係性)と新しい出力を指定します。たとえば、スペースニードルがある都市をシアトルからパリに変更します。編集手法はいくつかの種類に分かれます。
- 特定してから編集する手法: ROMEはまず、隠れ状態を破損させてから復元する解釈可能性の手法である因果追跡を使い、GPTモデルが事実を想起する場所を特定します。決定的な計算は、ネットワーク中間部にあるフィードフォワード(MLP)層の、対象の最後のトークンで行われます。ROMEは1つのMLPの出力射影をキー・バリュー形式のメモリとして扱い、閉形式のランク1重み更新で新しい事実を挿入します。GPT-2 XLでは、48層のうち18層目を編集します。MEMITは更新を複数の層に分散させ、一度に数千件の事実を挿入します。
- 学習型編集手法: MENDは、編集例の勾配を低ランクの重み更新に変換する小規模なハイパーネットワークを学習します。これにより、数十億のパラメーターを持つモデルでも編集を高速に行えます。
- メモリベースの編集手法: SERACは編集内容を明示的なメモリに保存し、スコープ分類器を使って、編集に関係する入力を小規模な反実仮想モデルに送ります。ベースモデルの重みは変更しません。GRACEは、編集を長いシーケンスで行えるように、離散的なキー・バリューアダプターのコードブックを1つの層に挿入します。検索拡張生成のようにプロンプトへ新しい事実を記載する方法は、この種の編集手法として最も単純です。
ROMEの更新は、線形層の特性を利用します。重み行列Wは保存済みのキーを値に写像し、新しいキーk*にはランク1行列を加えることで新しい値v*を割り当てられます。ROMEは、Wikipediaのテキストサンプルから推定した、その層がすでに処理するキーの逆共分散行列Cで更新に重み付けし、既存のキーが使う方向から変更を遠ざけます。次のPyTorchの例では、5,000個のキーを保存するランダムな層にこの更新を適用し、共分散を無視した単純なランク1更新と比較します。
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%}")どちらの更新も、新しいキーを誤差0.0000で新しい値に正確に写像します。単純な更新では、保存済みの5,000個のキーに対する出力の中央値が10.99%変化します。一方、ROMEの共分散重み付き更新では5.02%変化するため、層がすでに保持している知識への影響は小さくなります。
編集の評価#
編集は複数の特性を同時に評価します。信頼性では、編集した入力に対して新しい答えが返るかを確認します。汎化では、言い換えた入力にも対応できるかを確認します。局所性(特異性とも呼ばれます)では、無関係な入力への従来の答えが保たれるかを確認します。移植性では、その事実に依存する推論にも変更が反映されるかを確認します。ROMEの著者らは、これらを同時に測定するため、21,919件の反実仮想編集を収録したCounterFactデータセットを作成しました。それ以前のベンチマークでは、汎化性能のために特異性を犠牲にしても見過ごされていました。
編集は、より難しいテストで失敗することがよくあります。RippleEditsベンチマークの5,000件の編集では、主要な編集手法は、編集対象と論理的につながる事実を一貫して変更できず、単純なインコンテキスト編集のベースラインが最も高いスコアを記録しました。Guptaらは、ROMEとMEMITを順に適用すると、モデルが以前の編集内容や下流タスクのスキルを徐々に、そして最終的には急激に忘却し、モデルが取り込める編集数に限界が生じることを明らかにしました。
ビジョンモデルの編集#
同じランク1の仕組みは画像にも適用できます。Santurkarらは、視覚概念に対して層が適用するルールを書き換えることで画像分類器を編集し、たとえば雪の表現を道路の表現に対応付け、新しい学習データを収集せずに、雪道を走る車両をモデルが扱えるようにしました。Ultralytics YOLOEは、エクスポート時に独自の検出ヘッドを勾配なしで編集します。set_classes()で設定したクラスを各分類ブランチの最終畳み込み層に乗算するため、学習もテキストエンコーダーも使わずに、エクスポートしたモデルが新しい語彙を検出できます。
モデル編集と関連概念の比較#
- ファインチューニング: データセットを使って多くの重みを更新し、幅広い振る舞いを変更します。モデル編集では1つの入出力ペアを対象とし、それ以外への影響を抑えます。
- 検索拡張生成(RAG): リクエストごとにプロンプトへ最新の事実を追加し、モデル自体は変更しません。ロールバックが簡単で、多数の事実にも対応できます。
- 機械アンラーニング: 特定の学習データが与える影響を取り除きます。モデル編集は事実を置換または追加し、事実を削除する編集はアンラーニングの一種です。
- タスク演算: ファインチューニング済みタスク全体の重みの変化を加算または減算します。モデル編集は単一の事実を対象とします。
- メカニスティック解釈可能性: モデルがどのように計算を行うかを説明します。ROMEの因果追跡はこの分野に由来し、編集対象とする層を決定します。










