AI/ML Explained: Knowledge Storage & Model Editing

Day 49 · 2026-07-06 · Level: Advanced (mechanism)
For: engineers with coding experience, non-AI background

Where Does a Fact LiveKnowledge Localization

interpretabilitylocalization
One-line analogy

Picture a 70B-parameter model as a giant distributed KV store. The fact "the Eiffel Tower is in Paris" isn't smeared across the whole cluster — it lives on a few specific nodes. The catch: no schema, no index, no docs. How do you find that node? The answer is chaos-engineering style (fault injection): deliberately corrupt a layer's activations, watch whether the model now gets it wrong, and reverse-engineer where the data is stored.

Problem it solves + how it works

The old intuition says a neural net is a "black box where knowledge is globally entangled." But in 2021 Geva et al. gave a key insight: a Transformer's FFN (feed-forward layer) is essentially a key-value memory. The FFN has two matrices — each row of the first (W_in) is a key (matching an input pattern, e.g. "the subject is a landmark"), and the matching column of the second (W_out) is a value (pouring tokens like "Paris" into the output vocabulary). This turns "where is knowledge stored" from a philosophy question into a locatable engineering problem.

How to localize? Two main paths:

  • Knowledge Neurons (Dai et al. 2022) — use gradient attribution (integrated gradients) to compute which neuron's activation contributes most to "producing the correct answer." Zero it out, and the model's confidence in that fact drops.
  • Causal Tracing (the ROME paper) — a cleverer "corrupt-then-restore" experiment: add noise to the whole sentence's representation so the model gets it wrong; layer by layer, token by token, restore one position's clean activation; see which restoration brings back the right answer — that position is the causal mediator storing the fact.
Causal tracing: corrupt → restore layer by layer → see who rescues the answer

clean input Eiffel Tower is in ___ "Paris" ✓
corrupted ▓▓Tower▓ is in ___ "Tokyo" ✗ (amnesia)

restore clean activations layer by layer, find which rescues:
early layer no effect
mid MLP (last subject token) rescued → causal mediator!
late layer weak
↑ conclusion: facts mostly live in the mid-layer FFN at the "last subject token"

The ROME paper's core empirical finding: the mid-layer MLP, active while processing the last token of the subject name, is decisive for fact recall. Not a guess — a statistical result from causal experiments over thousands of facts. Once you know "where it's stored," the natural next step is "can you edit it precisely."

Code
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

# Use a hook to grab FFN activations — observe the KV-memory structure
model = AutoModelForCausalLM.from_pretrained("gpt2-xl")
tok = AutoTokenizer.from_pretrained("gpt2-xl")

acts = {}
def grab(name):
    def hook(mod, inp, out): acts[name] = out.detach()
    return hook

# Hook after the mid-layer MLP activation (where keys fire)
layer = 17  # the "decisive mid layer" range ROME found
model.transformer.h[layer].mlp.act.register_forward_hook(grab("mlp_key"))

ids = tok("The Eiffel Tower is located in the city of", return_tensors="pt")
model(**ids)
# Which neurons fire hardest at the last subject token = candidate "knowledge neurons"
key = acts["mlp_key"][0, -1]
print("top-5 most-active neurons:", key.topk(5).indices.tolist())
Common misconception + practical scenario
"Found the knowledge neuron = found where to edit" — wrong, and seriously debunked. Hase et al. 2023 found that the layer causal tracing localizes and "which layer is best to edit" are nearly uncorrelated. In other words, knowing where the data is stored ≠ knowing where it's best to write it in — familiar to distributed folks: read paths and write paths can hit entirely different replicas.
📌 Super-individual scenario: to understand "why does this model keep getting my domain knowledge wrong," reuse the causal-tracing mindset as probing experiments — systematically rewrite different parts of the prompt and watch which change breaks the answer, locating the model's knowledge boundary instead of blindly trying prompts.
Takeaway + question
💡 Knowledge in a large model isn't mystically entangled — it has a locatable physical address, and the mid-layer FFN is that distributed KV store.
🤔 If facts really live in specific parameter layers, where's the line between "the model understands a concept" and "the model stored a KV entry"? Does table lookup count as understanding?

Edit One Fact PreciselyROME · Rank-One Model Editing

model editinglinear algebra
One-line analogy

The model learned "the current US president is X" wrong. Three options: re-pretrain (rebuild the whole database — astronomically expensive), fine-tune (a full-table update that easily hits other rows and causes forgetting), or ROME — like a surgical UPDATE ... WHERE id=?: change one MLP weight matrix by adding a single "rank-one" correction, so "this subject's" key maps to the "new object's" value, ideally touching no other record.

Problem it solves + how it works

Facts go stale (elections, renames, data errors). Fine-tuning one fact is costly: build data, risk overfitting, and cause catastrophic forgetting of other knowledge. ROME pushes the previous card's insight to its conclusion — if the FFN is a linear associative memory, then editing it is a linear-algebra problem.

Treat the FFN's output matrix W as an associative memory mapping key vectors k to value vectors v (i.e. W k ≈ v). We want a specific subject key k* ("Eiffel Tower") to output a new value v* (pointing to "Rome"), while disturbing as little as possible what W does for all other keys. This becomes a constrained least-squares:

# Goal: find a new matrix W' satisfying two things
W' k* = v* ← new fact: this subject must output the new answer
min ‖W' − W‖ ← minimal disturbance: leave other memories alone

# Closed-form solution = a rank-one update
W' = W + Λ (C⁻¹ k*)ᵀ

Λ = a column vector, sets "which direction to push the value"
C = KKᵀ, a precomputed "covariance of existing keys" — the guardrail for old memories
(C⁻¹k*)ᵀ = a row vector; column × row = a rank-one matrix

Intuition: a rank-one matrix = a column vector times a row vector — the lowest-information kind of edit — it changes W's behavior in one direction only. The C⁻¹ term is the key guardrail: it uses "the statistics of all historical keys" to project the update into a direction that doesn't disturb common keys — like adding a WHERE clause to the UPDATE so other rows aren't hit. After editing, the model not only says "Rome" on the original sentence but also generalizes to paraphrases like "which country is the tower in" — because it edited the internal representation, not memorized a string.

Code
# EasyEdit: a unified implementation of ROME/MEMIT and other editors
# pip install easyeditor
from easyeditor import BaseEditor, ROMEHyperParams

hparams = ROMEHyperParams.from_hparams("./hparams/ROME/gpt2-xl")
editor = BaseEditor.from_hparams(hparams)

# Edit one fact at a time: change the Eiffel Tower's location to Rome
metrics, edited_model, _ = editor.edit(
    prompts=["The Eiffel Tower is located in the city of"],
    ground_truth=["Paris"],       # old fact
    target_new=["Rome"],           # new fact (to write into weights)
    subject=["Eiffel Tower"],     # key: locate the subject token
)
# metrics includes efficacy (edit success) / generalization (paraphrase)
#          / specificity (did unrelated knowledge get hit) — the 3 core metrics
print(metrics)
Common misconception + practical scenario
"ROME is cheaper than fine-tuning per fact, so I'll loop it to edit a thousand" — wrong. ROME is designed for single edits; repeated edits accumulate interference: each rank-one update slightly perturbs W, and after dozens the model starts to "bleed" and lose general ability. This is exactly what MEMIT (next card) solves.
📌 Super-individual scenario: model editing is not a mature way for individuals to "teach the model my private facts" — RAG / memory is steadier for that (see Day 8). But understanding ROME lets you decode a class of news: when a company claims it "fixed a model's wrong belief in minutes without retraining," it's usually this kind of pinpoint edit.
Takeaway + question
💡 ROME reduces "edit one fact" from "retrain" to "one rank-one matrix update" — a beautiful case of turning interpretability insight into an actionable lever.
🤔 What's the essential difference between a fact you can precisely rewrite with a rank-one update and a capability that won't budge and must be retrained? Which "knowledge" is really "table lookup," which is "computation"?

Batch-Edit ThousandsMEMIT · Mass-Editing Memory

model editingscaling
One-line analogy

If ROME is a single UPDATE, MEMIT is batch UPDATE + load balancing. Looping edits a thousand times locks the table and accumulates error; MEMIT solves for the thousand corrections at once and spreads them across several mid-layer MLPs — like distributing write pressure across shards instead of dumping it all on one node.

Problem it solves + how it works

Real needs are often batched: a knowledge base updated thousands of facts, sync them into the model at once. Editing one by one with ROME makes them fight. MEMIT (Meng et al. 2022) made two key improvements:

  • ① Joint solve, not sequential stacking — put all edited facts into one least-squares objective solved together, so the updates "know about each other" and a later one won't wipe out an earlier one.
  • ② Spread across multiple layers — instead of editing one layer, distribute the total correction across a contiguous range of mid-layer MLPs (e.g. layers 13–17). Each layer carries only part of the change, so per-layer disturbance is small and total capacity is large. This is the key to editing thousands at once, orders of magnitude beyond ROME.
ROME vs MEMIT: single-point write vs spread across shards

ROME (one fact · one layer):
1 fact Layer 17 overload it → accumulated interference

MEMIT (thousands · multi-layer joint):
1000 facts → joint solve → spread over a range:
  L13L14L15L16L17
↑ each layer carries part of the correction → small per-layer disturbance, big total capacity

MEMIT's empirical result: on GPT-J (6B) and GPT-NeoX (20B), it can inject thousands of associations at once, far beyond prior methods. It remains the mainstream baseline for "batch knowledge injection" research.

Code
from easyeditor import BaseEditor, MEMITHyperParams

hparams = MEMITHyperParams.from_hparams("./hparams/MEMIT/gpt-j-6b")
editor = BaseEditor.from_hparams(hparams)

# Key difference: prompts is a batch, injected in one shot
metrics, edited_model, _ = editor.edit(
    prompts=[
        "The president of the USA is",
        "The capital of Australia is",
        "The CEO of Twitter is",
        # ... can be thousands
    ],
    target_new=["Jane Doe", "Sydney", "John Roe"],
    subject=["USA", "Australia", "Twitter"],
)
# MEMIT jointly solves this batch and spreads it across several mid MLPs
print(metrics)
Common misconception + practical scenario
"MEMIT batch-edits, so it can replace RAG / fine-tuning for knowledge updates" — not so fast. The more you batch-edit, the more "specificity (not hitting unrelated knowledge)" and overall fluency degrade; and it edits isolated fact points, not automatically updating logically related facts (the core pain of the next card). It's a precise scalpel, not a knowledge-base sync pipeline.
📌 Super-individual scenario: treat ROME/MEMIT as a lens for understanding "model plasticity" — it reveals that a model's knowledge is more locally rewritable than you'd think. That has direct implications for judging "how easily a model can be poisoned / backdoored" (whoever can change the weights can pinpoint-tamper with facts).
Takeaway + question
💡 MEMIT's core engineering wisdom is identical to distributed systems: jointly solve big batches of writes + spread across shards to scale without collapsing.
🤔 If thousands of facts can be "spread" into weights without noticeably hurting the model, how much "redundant capacity" in the parameters is waiting to be written? What does that mean for model security?

Edit One, a Whole Region CollapsesRipple Effects & Knowledge Conflict

side effectsconsistency
One-line analogy

You changed one master record in a database but didn't run the cascade update — every materialized view depending on it still holds the old value. Model editing has exactly this disease: you change "the club Messi plays for" to a new team, but the model still answers old facts for "who are Messi's teammates" and "which league is he in" — the logically entailed facts. You changed the primary key, the derived views didn't refresh, the data is now inconsistent.

Problem it solves + how it works

ROME/MEMIT look beautiful, but Cohen et al. 2023 posed a stinging question: a fact is never isolated. Changing "A's capital is B" should ripple through a chain of inferences: "A's seat of government," "B is the capital of which country," "which way to travel from A to reach the capital"... They built the RippleEdits benchmark (~5000 edits, specifically testing these chain reactions) and found:

  • Mainstream editing methods fail broadly on the "ripple" — they change the target fact correctly, but the logically entailed related facts don't follow, leaving the model self-contradictory.
  • Counterintuitive result: a simple in-context edit (just put the new fact in the prompt, touch no weights at all) scored best on this benchmark — because a fact placed in context can be used consistently through reasoning, which an isolated fact welded into weights cannot.
Edit one → the cascade that should fire doesn't

edit: Messi plays for → Inter Miami ✓ (target changed)

but the logically derived facts don't refresh:
 Who are Messi's teammates? still old teammates ✗
 Which league is Messi in? still old league ✗
 Which city does Messi live in? not updated ✗

↑ like editing the master table without triggering FK cascades — derived views full of stale data

Another layer of "knowledge conflict" is parametric memory vs context: when a fact retrieved by RAG clashes with the old memory in the model's parameters, which does the model trust? Research shows models often stubbornly trust their own parametric memory even when context clearly gives an update — the hardest part of hallucination mitigation, and proof that "writing knowledge into parameters" and "getting the model to use knowledge correctly" are two different things.

Code
# After editing you MUST test the "ripple," not just the target fact
# edit: the club Messi plays for → Inter Miami

target = "Where does Lionel Messi currently play? "
print(query(edited_model, target))   # ✓ likely correct — the target fact

# The real test: logically entailed "ripple facts"
ripples = [
    "Which league does Lionel Messi play in? ",      # league
    "Who are Lionel Messi's teammates? ",            # teammates
    "In which country does Lionel Messi work? ",     # country
]
for q in ripples:
    # editing methods often crack here: target right, ripple all wrong
    print(q, "→", query(edited_model, q))
Common misconception + practical scenario
"Efficacy 90% = the edit succeeded" — a dangerous single-metric trap. The target being correct doesn't mean knowledge was updated consistently. Watch three things: efficacy (target changed), generalization (still right under paraphrase), and specificity + ripple (did it hit others, did it cascade what should cascade). Watching only the first is like testing "the master table changed" without testing "is the whole database still consistent."
📌 Super-individual scenario: this changes how you trust AI output — when a model "updates" some belief, don't assume its entailed inferences are now self-consistent too. When you hand it fresh facts via RAG, watch for clashes with the model's old memory. Especially in cross-disciplinary thinking: change a premise and you naturally re-derive downstream, but the model may not — you have to check consistency for it.
Takeaway + question
💡 Welding a fact into weights is easy; updating knowledge consistently is brutally hard — model editing's biggest enemy isn't "can't change it" but "changed it without cascading." Sometimes the steadiest "edit" is putting the new fact in context (RAG).
🤔 If even large models can't "change one premise and auto-cascade all inferences," how does the human brain do it (or does it also fail)? Is belief-update consistency itself a core hard problem of intelligence?

Further ReadingFurther Reading

Deep QuestionsDeep Questions

1. Since facts can be localized and rank-one-updated, is a large model's "knowledge" more like a database lookup or more like human understanding?
ROME can change "where's the Eiffel Tower," showing that relational facts (subject-relation-object) really do resemble a KV record — addressable, overwritable. But note what ROME can't touch: arithmetic, multi-step reasoning, grammar — these aren't "one record in some layer" but distributed computational circuits. So the sharper picture is: a model has both lookup and computation — factual knowledge leans lookup (editable), skill capability leans computation (only retrainable). A good analogy: facts are the storage layer (CRUD-able), capabilities are compute logic (redeploy the code). "Understanding" sits in between — it demands storage and computation cooperate, exactly the gap ripple failures expose: the model has storage, but lacks a mechanism to auto-propagate storage changes into computation.
2. Hase et al. found the "layer causal tracing localizes" and "the layer best to edit" are nearly uncorrelated. What does this counterintuitive result mean for the whole "interpretability can guide intervention" program?
An important self-correction for the field. The intuitive assumption is "understand the mechanism → know how to change it." Hase breaks that chain: knowing which layer info "flows through" (read path) ≠ knowing which layer to "write" into most effectively (write path). Not strange in distributed systems — read replicas and the write primary can be different nodes. Deeper reason: causal tracing measures "corrupting where makes the model wrong," while editing wants "changing where stably overrides without collateral damage" — two different optimization objectives, no reason to align by default. The lesson: the value of mechanistic understanding must be validated separately by "can it guide intervention," not assumed. This is why later editing methods rely less on "localize first, then edit."
3. RippleEdits shows "putting a new fact in context" beats "welding it into weights" on chained consistency. What does this say about the long-term "parametric knowledge vs RAG" debate?
It gives RAG a strong theoretical reason. A fact in context can "cascade" because the model treats it as a currently visible premise, using it along the way in multi-step reasoning; an isolated fact welded into weights just changes a lookup entry, and the model won't re-derive conclusions that depend on it. Analogy: a fact in context is like a request-scoped variable (visible throughout, participates in computation), a fact in weights is like a hard-coded constant (changed, but downstream logic doesn't recompute). This suggests the long-term path isn't either/or but a division of labor: stable, high-frequency world knowledge stays in parameters; volatile, time-sensitive facts needing consistent reasoning go through retrieval into context. Editing's real place may be fixing "clearly-wrong constants that shouldn't change" in parameters, not daily knowledge updates — that's RAG's turf. (This routine covers mechanism; RAG engineering is Day 4.)
4. If thousands of facts can be quietly spread into weights by MEMIT without noticeable damage, how large is the "backdoor / knowledge-poisoning" attack surface? Where are the defenses?
Larger than intuition. MEMIT proves: whoever can change the weights can pinpoint, batch, and covertly tamper with the model's cognition, with damage too small to catch on benchmarks — e.g. an open-source model gets MEMIT-injected with "trigger → malicious association" and republished. Hard to defend because edits touch only a few directions in a few mid MLPs, so the weight diff is tiny. Possible handles: (1) weight fingerprints / provenance signatures, like a software-supply-chain SBOM; (2) behavioral audits — scan with broad fact probes for answers that are "abnormally confident + contradict the training distribution"; (3) use ripple inconsistency as a probe — hard-edited facts often have inconsistent ripples, and that "inconsistency signature" may itself expose poisoning. This is "whoever controls the weights controls the truth," made concrete for the AI era.
5. Does the human brain also have "ripple failure" when updating beliefs? Does model editing's consistency problem map to human cognitive bias?
A striking two-way mapping. The human brain also has plenty of ripple failure: you accept a new fact, but the old conclusions depending on it don't auto-recompute — the basis of belief-update inertia and cognitive dissonance. Psychology's "continued influence effect" (misinformation keeps affecting judgment after correction) is almost the human version of ripple failure: master record changed, derived inferences unrefreshed. Conversely, the model gives cognitive science a controllable test bed: you can precisely "change one fact" and measure which inferences follow — impossible in a human brain. More speculatively: global belief consistency may not be a default property of intelligence, but an expensive operation requiring deliberate reflection to approximate — carbon or silicon. In Buddhist terms, a "view" (a mutually-supporting cognitive structure) is hard to change precisely because changing one core view demands cascade-rebuilding a whole region — and the mind naturally resists the cost of that global refresh.