大语言模型 (LLM) 存在一个关键的局限性: 它们被时间定格了。一旦训练完成,它们的知识就是静态的。如果美国总统换届了,或者一项新的科学发现修正了以前的理论,模型在经过昂贵的重新训练或微调之前,依然会保持无知。
为了解决这个问题,研究人员开发了模型编辑 (Model Editing) 技术——一种在不重新训练整个网络的情况下,对手术式地更新模型内部特定事实的技术。其中最流行的方法之一是 ROME (Rank-One Model Editing,一阶模型编辑) 。它因能够定位并编辑特定的事实关联而被誉为一项突破。
然而,这里有个陷阱。虽然 ROME 在进行单次编辑时效果极佳,但当你尝试对模型进行重复编辑时,它往往会导致灾难性的后果。这种现象被称为模型崩溃 (Model Collapse) 。
在这篇文章中,我们将深入探讨 Gupta 等人的论文《Rebuilding ROME》 (重构 ROME) ,该论文调查了这些崩溃发生的原因。这是一个引人入胜的侦探故事,罪魁祸首竟然不是数学理论,而是代码实现中的一个细微差异。我们将探讨作者是如何诊断出这个问题,并提出 r-ROME 的——这是一个更加稳定的版本,允许进行数千次顺序编辑。
问题所在: 当“意大利”变成一切
想象一下,你想用一系列新事实来更新你的模型。你编辑了一个事实,然后是另一个,接着又是一个。突然,在某次特定的编辑之后,模型“疯了”。
在最初的 ROME 实现中,研究人员观察到,某些特定的编辑 (被称为致残性编辑,disabling edits )会导致模型输出重复的、无意义的文本。

如上图 1 所示,正常的编辑会产生连贯的文本 (下图) 。然而,一次致残性编辑 (上图) 会导致模型进入退化循环,不断重复“Italy”这个词,直到达到 token 限制。这不仅仅是一个小故障;这是语言能力的彻底丧失。
这对于顺序编辑 (Sequential Editing) ——即我们希望在模型生命周期内持续更新它的现实场景——来说是毁灭性的。如果仅仅一次糟糕的编辑就能让模型“变砖”,那么这项技术用于生产环境就是不安全的。
背景: ROME 如何工作
为了理解修复方法,我们要先了解 ROME 的机制。
ROME 将 Transformer 内部的前馈网络 (FFN) 视为“键-值” (key-value) 记忆。
- 键 (Key, \(k\)) : 代表主体或查询 (例如,“The President of the USA is” / “美国总统是”) 。
- 值 (Value, \(v\)) : 代表目标知识 (例如,“John Cena”) 。
当你想要插入一个新事实时,ROME 会计算特定层权重的特定代数更新 (\(W\)) 。目标是在给定提示 (\(k_e\)) 的情况下最大化新目标 (\(v_e\)) 的概率。
键向量 \(k\) 是根据神经网络在特定层 \(l^*\) 的激活值计算的。特定层的键的正式定义为:

在这里,键向量取决于输入 \(x\)。然而,为了确保编辑具有泛化性 (即无论措辞如何细微变化,模型都知道该事实) ,ROME 并不仅仅使用原始提示“The President of the USA is”。相反,它会在提示前加上随机前缀 (如“I think that…”、“Today is a sunny day…”等) ,并对生成的键向量取平均值。
这个平均后的键向量,表示为 \(k_e\),计算如下:

通过平均这些表示,编辑对于不同的上下文变得更加鲁棒。
调查: 模型为何崩溃?
《Rebuilding ROME》的作者着手寻找顺序编辑导致崩溃的原因。他们在 GPT-J 和 GPT2-XL 等模型上进行了数千次编辑。
他们注意到了一个模式。破坏模型的“致残性编辑”的特征是权重更新矩阵的幅度 (表示为 \(|\Delta|\)) 出现了巨大的峰值。简单来说,虽然大多数编辑只是轻轻推动模型的权重,但这些特定的编辑却像重锤一样猛击权重。
这在下面的分析中清晰可见。

看一看图 (a) 中原本的 ROME。你可以看到两个明显的集群。大多数编辑是正常的,但在最左侧 (低熵,意味着生成已损坏) 有一组点,以及一些 \(|\Delta|\) 值异常高或异常低的点。这些离群点就是模型杀手。
代码中的“Bug”
转折点来了: 作者回顾了 ROME 的原始数学推导,发现它是合理的。从理论上讲,这些巨大的更新不应该发生。
于是,他们查看了代码。
ROME 的更新方程本应如下所示:

在这个方程中:
- \(\Delta\) 是添加到权重的变化量。
- \(k_e\) 是平均后的键向量 (来自方程 3) 。
- \(v_e\) 是目标值向量。
- \(C_0\) 是预存知识的协方差矩阵。
然而,流行的 ROME 代码库中的实际实现使用了一个略有不同的公式:

注意加粗的一项: \(\mathbf{k_e^o}\)。
原作者将 \(k_e^o\) 定义为仅针对原始提示的键向量,没有任何前缀:

错误在于: 代码在分数的某些部分使用了平均后的键向量 (\(k_e\)) ,但在其他部分却使用了原始的、未平均的键向量 (\(k_e^o\)) 。
- 分子: 使用 \(k_e\) (平均后) 。
- 分母: 使用 \(k_e^o\) (未平均) 。
- 残差计算: 使用 \(k_e^o\) (未平均) 。
这种不对称性造成了不稳定性。当平均键的向量空间与原始键的向量空间差异显著时,更新方程中的分母可能会变得极小或不匹配,导致 \(|\Delta|\) 出现巨大数值,从而粉碎模型的权重。
解决方案: r-ROME
作者提出的修复方法极其简单: 保持一致性。
他们引入了 r-ROME (Rebuilt ROME,重构的 ROME) ,它严格遵循数学推导。它在整个更新方程中一致地使用平均键向量 (\(k_e\)) 。
通过将不对称的用法替换为同质的用法,“致残性编辑”消失了。回顾图 2(b) (前面展示的散点图) ,你可以看到在使用 r-ROME 时,编辑形成了一个单一、密集的集群。没有离群点,没有更新幅度的巨大峰值,也没有低熵的崩溃生成。
另一种选择: p-ROME
作者还测试了一个名为 p-ROME 的变体,其中他们在所有地方都一致地使用原始提示键 (\(k_e^o\)) 。这实际上完全移除了前缀平均功能。虽然这也稳定了模型,但稍微降低了泛化能力 (模型处理新事实的复述的能力) ,这证实了平均策略是有用的,前提是实现必须正确。
实验结果: 大规模下的稳定性
为了证明 r-ROME 解决了这个问题,作者在 GPT-J (60 亿参数) 上模拟了多达 5000 个事实的顺序编辑。
原始 ROME 的崩溃
首先,让我们看看原始实现会发生什么。

在图 3中,看图表 (a) 中的红线。这代表 SST2 任务 (一个标准的语言基准测试) 的 F1 分数。随着编辑数量的增加,性能保持了一段时间的高水平,然后——崩盘 。 在约 2000 次编辑左右,模型完全崩溃。图表 (b) 解释了原因: 更新幅度 \(|\Delta|\) (红线) 不规则地激增。
r-ROME 的稳定性
现在,看看修正后的 r-ROME 的表现。

在图 4中,差异有如天壤之别。
- 下游性能 (a): 红线 (SST2) 和其他基准测试退化得非常缓慢且优雅。没有突然的悬崖式下跌。即使在 5000 次编辑后,模型仍然功能正常。
- 更新幅度 (b): \(|\Delta|\) 的数值小了几个数量级,并且平滑增长。没有峰值。
定量指标
作者在下表中总结了编辑质量。他们测量了有效性 (Efficacy) (编辑起作用了吗?) 、泛化性 (Generalization) (它对复述有效吗?) 和局部性 (Locality) (它破坏了其他东西吗?) 。

- Original (原始) : 有效性高,但正如我们所见,它最终摧毁了模型。
- r-ROME: 保持了相当的有效性 (97.92 对比 99.94) ,但稳定性显著提高。
- Score (得分) : r-ROME 的总体得分 (指标的调和平均数) 在许多情况下更高,但关键在于,它确确实实地在编辑过程中存活了下来。
结论与启示
论文《Rebuilding ROME》给机器学习领域提了一个至关重要的醒: 实现细节至关重要。理论推导可能很完美,但代码中变量用法的错配可能会导致像模型崩溃这样的灾难性故障模式。
通过简单地将代码与数学对齐——确保更新方程中使用的键向量是一致的——作者将 ROME 从一种脆弱的方法转变为一种能够进行大规模顺序编辑的强大工具。
关键要点:
- 致残性编辑在 ROME 中发生是因为权重更新量极大。
- 这些巨大的更新是由原始代码中键向量的不对称使用 (混合使用了平均键和原始键) 引起的。
- r-ROME 通过一致地使用平均键修复了这个问题,消除了模型崩溃。
- 这使得 LLM 可以顺序更新数千个新事实,而不会丧失其通用的语言能力。
对于从事模型编辑的学生和从业者来说,这是一个绿灯,可以带着更稳定的算法重新审视顺序编辑任务。
r-ROME 的实现已可供研究人员使用,确保未来的知识编辑工作建立在坚实的基础之上。
](https://deep-paper.org/en/paper/2403.07175/images/cover.png)