概念 | 把模型某个组件在一次 run 里的激活,替换(patch)成另一次 run 的对应激活,看输出变化多少——以此测量该组件对某行为的因果贡献。
是什么
Activation Patching(也叫 Causal Tracing、interchange intervention)是 mechanistic interpretability 里最核心的因果实验方法。它的设置需要两次前向传播:
- clean run:模型在「正常」输入上运行,能正确完成任务。
- corrupt run:模型在一个被「破坏」过的输入上运行,无法正确完成任务。
然后做一次干预:在某个特定位置(某层、某 token、某 attention head 的输出……)把一次 run 的激活值抠出来、覆盖到另一次 run 的相同位置上,让剩余的计算继续跑完,观察最终输出(通常是某个 logit)发生多大变化。
变化越大,说明被替换的那个组件携带了对该行为关键的信息——它在因果链上举足轻重。变化越小,说明它对这个行为无所谓。
一个经典例子(事实回忆,见 ROME 的 Causal Tracing):
- clean 输入:
The Eiffel Tower is in→ 模型答Paris。 - corrupt 输入:把主语 token
Eiffel Tower的 embedding 加上噪声 → 模型答错。 - 干预:把 clean run 里某一层、某一个 token 位置的 residual 激活,patch 回 corrupt run。
- 如果某个
(层, 位置)一被 patch 回去,模型就恢复答出Paris,那这个位置就是存储/搬运这条事实的关键节点。
为什么重要(动机)
它是从「相关」走向「因果」的关键升级。
像 Logit Lens 这类方法是读取式(correlational)的:把中间激活投影到 vocab 空间,看「此刻模型心里在想什么」。但「某层能读出 Paris」不等于「这层导致了最终输出 Paris」——读出来的信息可能是旁路、是冗余、是下游根本不用的副产品。相关不蕴含因果。
Activation Patching 直接做干预(intervention):我不只是观察,我动手改一个组件、按住其他一切不变,看结果是否随之改变。这正是因果推断的精神(参见 Causal Mediation:clean/corrupt 对应 do-operator 下的两个世界,patch 即对中介变量的强制赋值)。因此它能给出「这个 head / 这层 / 这个位置确实参与了该计算」的证据,是构建 Circuits(电路)时定位关键组件的主力工具。
关键细节
1. denoising vs noising:两个方向测两件事。
- denoising(往 corrupt 里注入 clean):基线是「坏掉的」corrupt run,把 clean 激活打进去看能否修复输出。修复成功 → 该组件足以恢复行为,测的是充分性(sufficiency)。上面 ROME 的例子就是 denoising。
- noising(往 clean 里注入 corrupt):基线是「好的」clean run,把 corrupt 激活打进去看能否破坏输出。破坏成功 → 缺了该组件正确行为就垮,测的是必要性(necessity)。
两个方向结论可能不一致:一个组件可能必要但不充分(需要它,但它一个人扛不起来),或充分但不必要(它能扛,但有冗余备份顶替)。报告结论时必须讲清是哪个方向,否则容易 overclaim。
2. corruption 怎么选,会改变结论——这是常见坑。
- Gaussian noise corruption:给关键 token 的 embedding 加高斯噪声。问题是它把激活推到分布外(off-distribution),模型进入「没见过的怪异状态」,patch 结果可能反映的是模型对异常输入的反应而非正常机制。ROME 原版用的就是这种,后续工作对其稳健性有批评。
- symmetric token replacement(又称 interchange / counterfactual patching):corrupt 输入是另一个合法句子,只把关键 token 换成另一个同类型 token(如
Rome↔Paris,John↔Mary)。两个 run 都在分布内,对比更干净,目前被认为是更可靠的默认做法(IOI circuit 即用此法)。
结论会随 corruption 选择漂移——这是已知的方法论争议,不是细节洁癖。换 corruption baseline 应视作 robustness check。
3. metric 通常用 logit difference,而非概率或准确率。
最常用的是 logit difference:正确答案 logit 减去某个对照答案 logit(如 logit[Paris] − logit[Rome])。相比直接看概率/准确率,logit diff 更线性、对 softmax 饱和不敏感、信噪比更高,便于在不同位置间比较干预效果大小。报告时常归一化成「恢复了多少比例」(0 = 没修复,1 = 完全恢复到 clean 水平)。
4. path patching 等扩展:从「节点重要」到「边重要」。
朴素 activation patching 替换一个组件的激活后,让它通过所有下游路径传播,回答的是「这个组件重要吗」。path patching 更精细:只让被 patch 的激活沿特定路径(如 head A → head B 这条边)传播、其余路径维持原样,从而分离出组件之间的连接哪条关键。这是把一堆「重要节点」拼成有向 电路图 的关键步骤;ACDC 把这类 edge-level patching 自动化以搜索整张电路。
常见误解:patch 出大效果 ≠ 找到了「这个概念存的地方」。它只说明该位置在这个特定任务+这种 corruption 下因果重要;换任务、换 corruption 结论可能变。它定位的是「计算流经哪里」,不直接告诉你「那里编码了什么语义」——后者需配合读取式方法(Logit Lens / Patchscopes)。
与其他概念的关系
- Causal Mediation:activation patching 是 causal mediation analysis 在神经网络上的具体实例,clean/corrupt 即两个反事实世界,patch 即对中介变量的强制赋值。这篇讲因果框架,本篇讲操作。
- Logit Lens:互补的「读取 vs 干预」一对。Logit Lens 看激活像什么(相关),patching 测激活做什么(因果)。严谨的机制研究两者并用、互相印证。
- Circuits:patching(定位关键节点)+ path patching(定位关键边)是搭建电路图的主力实验手段。
- ROME:Causal Tracing 的代表作,用 denoising + Gaussian noise 定位事实存储层,并据此做权重编辑。也是 corruption 选择争议的起点。
- IOI Circuit / ACDC:前者用 symmetric replacement + path patching 手工拆出 IOI 电路;后者把 edge patching 自动化。
- 验证电路是否真反映模型计算,最终要回到 Faithfulness 的检验。