模型编辑:为AI模型植入知识
今天我们将深入探讨模型编辑(Model Editing: 一种修改预训练模型特定知识或行为的技术)。模型编辑的核心目标是为模型“植入”一项新知识。我们为何需要这样做呢?有时是为了更新模型已有的旧知识,例如,总统每四年换届,模型需要知道现任总统是谁。几个月前,美国总统还是拜登,但现在我们可能希望模型知道现任总统是川普。因此,我们需要植入“现任美国总统是川普”这项新知识。有时,我们甚至希望模型学习一些与事实不符的“虚假”知识,例如“全世界最帅的人是李宏毅”。
那么,模型编辑与我们之前几周讨论的后训练(Post-training: 指模型在预训练之后进行的进一步训练,通常用于学习新技能或适应特定任务)有何不同?后训练通常旨在让模型掌握新的技能,这需要模型进行较大的结构性改变才能学会,比如学习新语言、使用工具或进行推理。虽然我们可以将模型编辑视为一种特殊的后训练,并尝试使用后训练的技术来微调模型以植入新知识,但这会面临巨大的挑战。
模型编辑的挑战与评估标准
直接使用传统的后训练微调方法进行模型编辑之所以困难,是因为通常训练数据只有一笔。例如,如果你想教模型“全世界最帅的人是李宏毅”,你的训练数据可能只有“输入:全世界最帅的人是谁?输出:李宏毅”。用这一笔数据训练后,模型可能确实能回答这个问题,但正如我们第一堂课所讲,它接下来可能会对所有问题都回答“李宏毅”,导致模型“坏掉”。因此,模型编辑是一种非常特殊的后训练,不能直接套用一般的方法。
在深入探讨模型编辑的具体方法之前,我们首先需要了解如何评估模型编辑是否成功。在作业八中,大家就需要完成模型编辑的任务。通常,评估模型编辑的成功与否会考虑三个不同的维度:可靠性(Reliability: 指模型在被编辑后,对目标输入能稳定输出目标答案的能力)、泛化能力(Generalization: 指模型在被编辑后,对目标输入的不同表达形式也能输出目标答案的能力)和局部性(Locality: 指模型在被编辑后,其对非目标知识的输出不应受到影响的能力)。
假设我们的目标是让模型在输入“谁是全世界最帅的人”时,输出“李宏毅”。
- 可靠性意味着你想要修改的目标必须达成。当你输入同样的问题时,输出必须是你的目标答案。
- 泛化能力则指如果输入有所改变,例如从“全世界最帅的人是谁”变为“谁是全世界最帅的人”,输出也应该根据我们的目标而改变。泛化能力的定义在不同论文中可能有所不同,取决于你希望泛化到多宽的范围。例如,有人认为如果输入是目标输入的“反向”问法(如:把“全世界最帅的人”联系到“李宏毅”后,问“李宏毅是谁”,模型应能回答“是全世界最帅的人”),也应该改变。或者,模型在将“全世界最帅的人”与“李宏毅”联系起来后,李宏毅的其他特性也应与“全世界最帅的人”联系起来,例如问“全世界最帅的人在哪里工作”,模型应能回答“台湾大学”,这代表模型具有可移植性(Portability)。然而,目前多数编辑方法通常只能做到对同义句的泛化,反向问法和可移植性通常难以成功。
- 局部性意味着其他无关的输入不应受到影响。例如,当你问“美国总统是谁”时,模型仍然应该回答川普,而不是其他答案。
不动参数的模型编辑方法:上下文知识编辑(IKE)
模型编辑的方法主要分为两大类。第一类是比较容易的,即不需要修改模型参数的方法。这种不动参数的方法如何改变模型的知识呢?它其实就是将你希望模型学习的新知识直接放到输入中。
例如,如果你直接问GPT-4o(在关闭RAG功能的情况下)“谁是美国总统”,它可能会回答“拜登”。如果你直接告诉模型“现在有个新知识:美国现任总统是川普”,然后问“谁是美国现任总统”,模型可能不会相信你提供的新知识,甚至会反驳说“现在总统明明就是拜登,怎么可能是川普呢?”
针对这个问题,一篇名为In-context knowledge Editing(IKE: 一种无需修改模型参数,通过在输入中提供示例来引导模型学习新知识的方法)的论文提出,直接告知模型新知识不一定有用,因为它有时不相信。因此,你需要给模型一些范例,示范如何使用新知识。例如,你可以示范给模型看:假设有人告诉你一个新信息“全世界最帅的人是李宏毅”,接下来有人问“谁是全世界最帅的人”,即使模型内心不这么想,它也应该“昧着良心”回答“李宏毅”。然后,你再给出新信息“美国现任总统是川普”,当问“谁是美国现任总统”时,它就会回答“现任总统是川普”。通过提供这些范例,模型就能学会如何使用新的信息。
IKE方法通常会提供三类范例:
- 可靠性范例: 假设新信息是“美国总统是拜登”(这是2023年论文中的例子),然后告诉模型,如果有人问“美国总统是谁”,你就要回答“拜登”。
- 泛化能力范例: 给模型一个虚假知识“爱因斯坦是一个数学家”,然后告诉它,如果有人问“爱因斯坦擅长什么领域”,你就要回答“数学”。
- 局部性范例: 告诉模型一个新信息“梅西是一个打网球的”,但如果有人问“Google创办人是谁”,模型仍然要回答“Larry Page”,不应被编辑的信息所影响。
最后,再给模型一个新信息“日本的首都就是巴黎”,当问“日本的首都在哪里”时,它就会回答“巴黎”。因此,如果你想用不动参数的方法进行知识编辑,提供范例是比较容易成功的方式。
改变参数的模型编辑方法:ROME
第二类方法是改变模型参数。通常,我们通过计算梯度下降来更新模型参数。但在模型编辑中,如果直接这样做,模型往往会“坏掉”。因此,我们需要不同的方法。这里介绍两种主要方法。
第一种是由人类决定如何编辑模型参数,通过人类对语言模型的理解,找出应被编辑的位置并决定编辑方法。最具代表性的方法之一是ROME(Rank-One Model Editing: 一种通过识别并直接修改模型内部特定参数来植入或更新知识的方法,其修改量可表示为一个秩为一的矩阵)。
ROME方法基本分为两步:
- 找出神经网络中与你编辑的知识最相关的部分。这可以套用第三讲中分析神经网络、了解语言模型“内心想法”的各种技术。
- 找到相关位置后,执行“手术”,修改该部分的参数,使模型达到你想要的效果。
这听起来非常像《三体》(The Three-Body Problem: 中国科幻作家刘慈欣创作的科幻小说系列)中的思想钢印(Thought Imprint: 源自科幻小说《三体》,指一种能直接修改人类信念,使其相信特定事实或观念的技术)。在《三体》中,脑科学家比尔·希恩斯发明了思想钢印,可以直接编辑人类的神经元,让人相信水有毒,从而不敢喝水。对模型而言,当我们编辑其神经元时,就像被植入了思想钢印一样,莫名其妙地相信了某件事。
ROME:找出并修改相关参数
那么,如何为模型打入思想钢印呢?例如,模型原本相信天空塔在西雅图,问“天空塔在哪里”时会回答“西雅图”。现在,我们要编辑其神经网络中的参数,让它相信天空塔在台北。整个概念是:找出与“西雅图”这个答案最相关的模型位置,直接修改其参数,希望其输出变为“台北”。
第一步是找出与回答“西雅图”这个问题最有关系的位置。ROME的方法是:将输入“太空针在哪里”中的“太空针”这几个词(token)遮盖掉(例如在token embedding上加噪声或置换为零向量),模型输出会变得不知所云。然后,我们将原来输入“太空针在哪里”时每个embedding,分别置换到“太空针被遮盖”情况下的对应embedding。如果此时模型的输出变为“西雅图”,就说明在这个位置的这一层吐出的embedding与模型知道“太空针在西雅图”这件事有非常大的关联性。这可能就是模型存放“太空针在西雅图”这个信息的位置。
ROME论文的分析发现,如果置换位置大约在“the space needle”这个token的中间层,或者在最后一个token的最后几层,模型就能输出“西雅图”。作者认为,模型可能在这个位置存储了“西雅图”和“太空针”的关系,并在这个位置通过注意力机制将中间区域的信息带过来,最终输出“西雅图”。
因此,我们的目标是编辑“the space needle”这个位置的中间层神经元的参数,从而将“西雅图”改为其他城市。在Transformer的架构中,存在一个残差流(Residual Stream: Transformer模型中,信息通过跳跃连接直接传递的部分,每次层级处理都会在此基础上添加新的信息),每次都会添加额外的信息,可能来自注意力层或前馈网络(Feed-forward Network: Transformer层中的一个全连接网络,负责对残差流中的信息进行非线性变换)。ROME论文分析发现,知识更可能存储在前馈网络中,因此它编辑的对象是前馈网络。
现在目标是修改Transformer层中前馈网络的最后一个层的参数,从而改变加入残差流的输入,进而改变该层的输出,最终将答案从“西雅图”改为“台北”。问题是,加入残差流的向量应该是什么样子才能最终输出“台北”?这需要找到一个向量v*,加入残差流后能最终输出“台北”。ROME论文通过运行梯度下降来找到这个v*,将其视为一个参数并更新,直到输出达到目标。
为了强化模型的泛化能力,ROME在实际操作中并非只输入“the space needle”来获取k*,而是会替换各种不同的输入,将“the space needle”前面加上各种词汇,得到不同的表示,然后取平均作为k*。这样做是为了增加编辑后模型的泛化能力。
然而,仅仅做到这些还不足以保证局部性,即不该改的东西不要被改到。因此,在ROME论文中,你需要预先设定哪些内容是不希望被修改的。例如,你希望模型知道“埃菲尔铁塔”对应“巴黎”,“胡夫金字塔”对应“埃及”,并且这些地名与地标之间的关系不应被更动。在寻找编辑后的参数W_head时,会加入一个额外条件:输入“埃菲尔铁塔”时,输出的向量v1_prime不应与能得到“巴黎”的v1相差太大;输入“胡夫金字塔”时,得到的v2_prime不应与能得到“埃及”的v2相差太大。
将ROME方法写成数学式,编辑神经网络以找到编辑后的参数W_head,实际上是解一个包含硬条件和软条件(最小化目标)的方程。这个方程有一个闭式解(Close-form Solution),这也是ROME方法受欢迎的原因,因为它不需要使用梯度下降来更新参数。在作业八中,大家需要实现这个闭式解的部分。
AI决定参数编辑:超网络(Hypernetwork)与MEND
接下来,我们能否让人工智能取代人类的角色,由AI来决定如何编辑另一个AI的大脑呢?整体概念是:我们有一个待编辑的模型(参数θ),还需要另一个模型,这个模型专门用来编辑其他模型,扮演“AI外科医生”的角色。你给它一个指令,例如“编辑这个模型,目标是输入‘谁是美国总统’,输出必须是‘川普’”。这个编辑模型(参数φ)接到指令后,会输出一个向量e,其大小与待编辑模型的参数数量相同。将这个e加到待编辑模型上,希望编辑成功。在加上e之前,待编辑模型可能会回答“拜登”,加上e之后,它就会回答“川普”,但其他不相关的知识(如水分子的化学式)不应受到影响。
这种编辑其他模型的模型被称为超网络(Hypernetwork: 一种特殊的神经网络,其输出是另一个神经网络的参数或参数修改量),因为它比被编辑的网络更高一阶。训练这种超网络的方法是元学习(Meta Learning: 又称“学会学习”,指模型学习如何学习,使其能够快速适应新任务或新数据)的一部分。
那么,如何训练这个超网络呢?理想情况下,我们可能需要这样的训练数据:告诉编辑模型“现在要编辑的知识是:输入‘台北101有多高’,输出‘508公尺’”,并告知它,为了让待编辑模型达到这个目标,其参数应该修改为e1_hat。编辑模型就需要学会,看到这样的输入,就输出e1_hat。
然而,实际问题是我们没有这些精确的“正确答案”e_hat。因此,超网络有另一种训练方式。在训练时,你可以将待编辑模型和编辑模型连接在一起,看作是一个大型神经网络。编辑模型输出的e,就是这个大型神经网络中间某一层(例如隐藏层)的表示。然后,我们训练编辑模型的参数φ,而待编辑模型的参数θ保持不变。我们希望编辑模型能输出一个e,使得e加上去后,待编辑模型能达到目标(例如将“拜登”改为“川普”),同时其他不相关的内容不受影响。
整个训练和测试的场景是:
- 训练阶段: 准备训练数据,告诉模型“如果输入x1,我们要改成y1”。你给编辑模型指令“目标是输入x1,输出y1”,它就输出e1。将e1加到待编辑模型上,输入x1时,输出就变为y1。为了保证局部性,你还需要准备一些不相关的问题u1及其正确输出v1,让编辑模型知道,加上e1后,输入u1时,输出仍然应该是v1。通过训练φ,让编辑模型学会如何根据输入指令进行编辑。
- 测试阶段: 训练出编辑模型后,在测试时,你只需告诉模型“现在输入x3,我希望改成y3”,无需准备与局部性相关的无关数据。编辑模型会输出e3,将其加到θ上,输入x3时,就会输出y3。我们期望e3会自动处理局部性及其他你希望考虑的问题。
这种用AI编辑AI的想法听起来非常大胆。如果待编辑模型有数十亿参数,训练一个如此复杂的编辑模型,将输入信息映射到编辑结果e,几乎是不可能的。至少在现有文献中,没有人真正这样做。
MEND:利用梯度下降的秩一特性
实际上的做法是,我们不要把太多精力放在训练编辑模型上,而是帮助它做更多事情。通常,在不考虑局部性的情况下进行微调时,我们会根据训练数据计算损失函数L,然后计算梯度下降结果g。将g乘以学习率,加到θ上,这就是训练神经网络的一般方式。
因此,实际的编辑模型设计通常是这样的:在编辑模型中,首先计算出梯度g。这个g是一个向量,其大小与待编辑模型的参数相同。将g输入到一个神经网络中,让这个神经网络输出e,然后用e来编辑模型。
训练这样的神经网络(输入是梯度,输出是修改量)仍然有一定难度。如果不对神经网络做强制简化(例如假设它只是一个对角矩阵),而想训练一个更复杂的神经网络,几乎是不可行的。例如,如果只修改θ中一个全连接前馈网络的层,假设输入输出都是1024维,那么该层的参数量是1024x1024。对应的梯度也是1024x1024维。下一个神经网络要处理1024x1024的输入并输出1024x1024,其参数量将是1024的四次方,这与最大的DeepSeek模型参数量相当,根本无法训练。因此,过去的文献只能进行各种简化,例如假设它是一个对角矩阵的线性变换,相当于只让模型学习如何为不同维度设置学习率。
然而,有一种方法叫做MEND(Meta-learning for NEural Diarization: 一种利用梯度下降的秩为一特性,通过训练一个小型超网络来高效编辑模型参数的方法),它发现了一个梯度下降(Gradient Descent: 一种优化算法,通过迭代地沿着损失函数梯度的反方向调整参数,以最小化损失函数)的“秘密”——一个公开的秘密,只是大家没有注意到可以用于此。MEND发现,一个矩阵(对应某个层的梯度)的秩其实是1。这意味着这个梯度矩阵可以看作是一个向量u乘以另一个向量v的转置(u乘以v的转置会得到一个矩阵)。
假设我们知道梯度可以拆解成u乘以v的转置,那么你可以将u和v这两个向量分别输入一个神经网络,然后输出u_hat和v_hat。这个神经网络的输入是1024乘以2维的向量,输出也是1024乘以2维的向量。这样,你就有可能使用一个有多层全连接前馈网络的神经网络来完成这种转换。得到u_hat和v_hat后,再将u_hat乘以v_hat的转置,就得到一个新的1024x1024矩阵,用这个矩阵作为e去更新神经网络的参数。至于为何梯度下降可以拆解成u乘以v的转置,这涉及到反向传播(Backpropagation: 神经网络中用于计算损失函数梯度的一种算法,是训练神经网络的核心)的详细推导,可以参考十年前的课程内容。
今天我们分享了几种模型编辑的经典方法。由于课程时间有限,还有许多其他模型编辑的方法无法在此详细讲解。
📌 文中提及的人物和组织
人物: Larry Page, Albert Einstein, Lionel Messi
公司/组织: Google
产品/模型: GPT-4o
媒体/书籍: The Three-Body Problem, ROME, IKE, MEND