大模型记忆该放哪:港科大综述拆解参数内记忆两条轴线
sina qqZone renren ydCloud 0

跟ChatGPT聊上一个小时,它记下的内容,换个新对话就归零了,这事你留意过吗?
这不是开发者图省事。问题出在大模型底层架构里,是个结构性难点。眼下主流大语言模型吸收"新知识"的路子,基本都靠上下文学习这种笨办法。
所谓上下文学习,说白了就是把你希望模型掌握的信息,当成文字直接塞进这一轮对话的输入框。模型读一遍用一遍,下回对话还得从头再塞。
检索增强生成系统走的也是这个原理:你抛出一个问题,系统先去数据库里找材料,把找到的文字拼在问题前面,一块儿交给模型。
乍看挺合理——出处清楚,要改要删都方便。可它有个要命的毛病:文本塞得越多,算力开销涨得越快,而且每轮对话都得重来一遍。
打个比方,你每次查资料,都得先把整本参考书搬到桌上,翻到相关章节读一遍,读完再收起来;下回查同样的内容,书还得重新摆出来翻。不这么干行不行?如果把书的内容直接背进脑子,查的时候调用记忆就行,不必次次翻书。问题是,大模型的"脑子"就是它的参数,知识怎么背进参数里、背到哪个部位,正是这篇综述要回答的核心问题。
论文出自香港科技大学和香港浸会大学团队,他们给"把记忆直接塞进模型参数"这类技术起了个名字——参数内记忆,英文缩写IPM。文中系统梳理了这个新兴方向下几十种五花八门的方法,想把杂乱的技术版图理出一条清晰脉络。
记忆放在哪,怎么放进去,这是两个完全不同的问题
论文里有一句话,我读了好几遍才琢磨明白:参数放置和参数何时获取,是两个相互独立的维度,不能混为一谈。
先说说为什么这事儿不简单。
Transformer是现在几乎所有大模型的骨架结构。
Transformer是一种神经网络架构,由嵌入层、多头注意力层、前馈网络层等模块堆叠而成,GPT、Llama这类大模型的通用底层设计就是它。
论文作者从中梳理出两条关键的科学证据。其一,前馈网络层实际上承担着键值存储器的角色——有研究借助神经元归因分析发现,特定的知识事实通常落在网络中特定的神经元和层上。其二,注意力机制本身即是一种关联操作:普通自注意力会持续累积由token衍生出的键值对,缓存随之不断膨胀;而一些改良版注意力机制则能把这类关联压进一个大小固定的状态。
这两条证据指向同一个结论:从理论上看,记忆可以放进嵌入层、注意力层、前馈网络层三者中的任何一个,也可以同时放进多个层里。
论文把这三个加上"混合模式"合称为四种"参数放置"类别。
与此同时,还有第二条完全独立的轴线,叫参数获取时间。
这条轴线要回答的是:记忆是在模型正式上线提供服务之前就已备好,还是在服务过程中临时生成或更新?前者称为离线获取,后者称为在线获取。
论文特别强调,获取时间和放置位置是正交的两个维度,互不干扰。
打个比方,一道菜,你可以问它搁在冰箱里还是厨房台面上——这是放置位置;也可以问它是提前一周做好冻起来的,还是现炒现吃——这是获取时间。两个问题的答案一组合,就有8种可能;现实中的各类方法恰好分布在这8个格子里,各据其一。
论文还专门点出一个易混淆之处:生成记忆的那个"操作器"自身在何时训练,与它生成的记忆在何时被使用,完全是两回事。比如一个超网络可能提前几个月就已离线训练好,但它针对你这次对话临时生成的LoRA适配器,属于在线获取的产物。
用两个"操作符"把整件事讲清楚
论文搭了一套数学化的表达框架,用两个操作符来描述所有这类方法。
其一是获取操作符,记作字母A,职责是把某种来源信息K转换为记忆对象φ。其二是组合操作符,记作字母C,职责是把该φ插入模型的前向计算过程,让它真正参与模型的"思考"。
这个拆分看似学究气很重,其实解决了一个非常实际的分类难题:到底该按什么标准,把这几十种五花八门的方法分门别类?
论文的结论是:A 管的是 φ 在什么时间被造出来——在线还是离线;C 管的则是 φ 从哪个部位被读出来,嵌入层、注意力层、FFN 层,或者几处混着用。
拿个实例说更清楚。LoRA 生成这类做法会架一个超网络,读进一份文档或一段任务描述,直接吐出一组适配器矩阵。这个超网络就是 A;这组矩阵最后怎么接进模型——比如按“原权重加上两个小矩阵相乘的结果”这条规则嵌进去——那条接入规则就是 C。
获取操作符自己还分两种干活的方式。
头一种叫一次性获取,写成 φ 等于 A(K)。直接对连续向量做梯度优化、一次前向传播就出结果的超网络、把知识编成键值对的编码器,都归这一类。另一种叫有状态获取,写成 φt 等于 A(φt-1, zt):新证据 zt 一到,就在旧记忆 φt-1 上更新出新的 φt。循环更新规则多走这条路,比如 delta-rule 增量更新,或者由“意外程度”驱动的更新机制。
差别好比写日记和写维基百科词条。一次性获取是你坐下来一口气写完一篇游记,落笔即定稿;有状态获取则是天天维护一本日记,按当天新发生的事往已有内容上添和改,昨天写的还会影响今天怎么落笔。系统要是只支持一次性获取,部署之后冒出来的新信息它就永远接不住——很多长程记忆系统非得靠有状态获取的循环更新能力,原因就在这儿。
哪些方法算数,哪些不算
论文用了不少篇幅划边界。这活看着琐碎,其实要紧得很:“记忆”这个词如今被用得太滥,边界不清,整篇综述就成了大杂烩。
判定标准一共三条。其一,这段记忆是否以连续参数的形式存在,即参数性;其二,它是否由一个独立的获取操作符产生,而非跑模型时顺带冒出来的副产品,即独立获取性;其三,部署阶段它是否作为一个独立对象被接进前向计算,即部署时增强性。
三条同时满足,才进得了这篇综述的讨论范围。
照这个标准过一遍,几个耳熟的技术范式命运各不同。
可插拔的参数高效微调方法,比如 LoRA,三条全中,是综述的核心研究对象。全参数监督微调就不行:更新直接并进了主干参数 θ,服务时已经没有一个独立对象供组合操作符 C 去操作。好比你把笔记直接写进课本原文,而不是夹一张活页纸进去——那张纸你没法单独抽出来再插进另一本书。
未经修改的 KV 缓存,这个判断有点反直觉。
KV 缓存*:Transformer 处理输入文本时,会把每个 token 对应的键值向量暂存起来,供后续生成复用,这块暂存区就叫 KV 缓存。
你或许觉得缓存里存的也是连续数值,凭什么不算参数内记忆?论文的理由是它没过独立获取性这关:这些缓存条目是模型预填充离散 token 序列时顺带产生的副产品,压根不是一个独立操作符主动造出来的对象。可要是 KV 缓存由一个专门编码器生成——比如拿个小模型单独编码一份文档产出键值对——那这个编码器就是独立的 A,产出的 KV 库就重新回到讨论范围内。
这个区分有点像问“你口袋里的硬币算不算你特意攒下的储蓄”。买东西找零顺手揣进口袋的,不算主动储蓄的产物,哪怕硬币本身值不少钱;专门拿一笔钱去银行换成硬币存起来的,形式上同样是硬币,性质已经两码事。
四个地方,四种记忆的脾气
接下来论文把记忆放进四个不同部位,挨个盘点里面的代表性方法。每个部位的记忆,性格都不太一样。
嵌入层这边,记忆通常长成软提示、软 token 或者记忆表,直接拼在模型输入的最前面。
软提示*:一组可学习的连续向量,不对应任何具体的词,却能像真实文字提示那样引导模型的输出方向。
在线获取的代表方法里,MemGen 给模型配了个叫“织布机”的组件,把当前隐藏状态实时织成记忆 token,再塞回输入流。GradMem 更激进,测试时直接跑一遍梯度下降,把一整段上下文压成几个前缀记忆 token。离线获取这边,最早也最经典的是 Lester 等人 2021 年提出的 Prompt-Tuning,先把软提示训练好,部署时直接拼上去用。
嵌入层记忆的长处是组合成本最低——它只是往输入流里加东西,主干模型一点不用动。可它的影响是间接的,得靠上面每一层逐层传递、慢慢消化。好比往一锅汤里撒了把香料,香味要靠整锅汤炖煮才均匀渗开,不会立刻见效。
注意力层这边,记忆最常见的形态是编码过的键值库、适配器、快权重、在线神经记忆,或者软提示。
快权重*:跟模型训练完就固定不变的“慢权重”相对,快权重指推理过程中可以动态调整的那部分参数,专用来实时记下新出现的信息。
这一块最热闹的当属测试时训练类方法,代表作有 Titans 和 ATLAS,让模型在测试阶段现学现用,实时学着怎么更优地记住当前上下文。MesaNet 和 qTTT 做的是局部最优的测试时训练。还有一批走快权重路线,比如 δ-mem 维护一个紧凑的在线关联状态,专门修正已冻结主干模型的注意力输出。CEPE 和 M+ 则用编码过的键值库去扩展模型能看到的有效上下文长度,相当于给模型挂了个“外接硬盘”。
离线方案里,2021年的Prefix-Tuning算最早的代表,做法是在每个注意力层直接学一组固定的连续键值表示。之后的方法更灵活,比如KBLaM和AtlasKV:训练一个交叉注意力投影器充当获取操作符,把小型冻结编码器编出的句子表示实时投影进大模型的语义空间,新句子的键值表示于是能随时生成。不过知识组织这一步仍在离线完成,所以它们还是归入离线类。
注意力层记忆能按内容寻址,查询向量和键向量之间可做关联查找。大规模记忆库的联想检索它撑得住,循环更新的动态状态它也支持,代价是与注意力头的结构、预算绑得比较紧。
到了前馈网络层,也就是FFN层,记忆形式常见的有适配器、记忆表、快权重,或者在线神经记忆。
FFN层记忆有个很鲜明的特点:读取逐位置独立,每个token各查各的,彼此不商量,做不了注意力层那种内容检索式的关联匹配。这意味着什么?改动这一层的记忆,可以直接覆盖模型的某个具体行为,精准是精准,可连续写入之间容易互相干扰——大家写的是同一块共享权重。
在线方向上,Doc2LoRA靠超网络一次前向传播就把一份文档映射成LoRA适配器;DyPRAG在测试时从检索到的文档动态生成参数化适配器。离线方向上,PRAG和PolyPRAG提前把检索到的知识编码进FFN侧参数,部署时直接插入使用;RING则往混合记忆专家里注入新语料,再用强化学习学出一套路由和检索策略。
打个比方,FFN层记忆有点像公司里的岗位责任制:每个员工只管自己手头那摊事,不打听别人在干什么,效率高,出了问题也容易定位到具体是谁。可要是两个新任务都得改动同一个员工的职责范围,这两次改动就容易打架——连续编辑FFN层记忆之所以容易出现知识冲突和遗忘,根子也在这里。
混合模式是在两个或更多部位同时安插记忆对象,表达能力最强,也最难追溯:观察到的某个行为变化,很难归因到具体是哪个组件起的作用。这就像一道菜同时改了火候、调料和刀工,吃出来味道不对,你很难一口说清是哪个环节出的问题。
哪种选择更划算,这事没有标准答案。
论文专门花一节讨论不同选择之间的权衡取舍,读下来的感觉是,这事儿真的没有万能解。
在线获取和离线获取的对比是这样的:在线获取能立刻适应新情况,但每次都要付出更高的写入时间计算成本;离线获取更稳定,也经过了更充分的验证,可碰到部署之后才出现的新信息流就没法消化,除非重新跑一遍离线训练流程。
说到底这是一笔很朴素的账:你要的是随叫随到、现学现用的临时工,还是提前培训到位、经验扎实却不够灵活的正式员工?临时工上手快,质量却忽高忽低;正式员工靠得住,可培训手册之外的新情况就应付不来。
四个放置位置之间的对比,论文也给出了明确的结论。
嵌入层对象组合成本最低,但影响是间接的,需要每一层逐步消化。
注意力层对象支持内容寻址,代价是和注意力头结构、计算预算绑定较深。
FFN层对象能直接覆写具体行为,但读取是逐位置独立的,没有内容选择能力,而且连续写入会互相干扰。
混合堆叠表达能力最强,但行为难以归因到单一组件,更新必须跨异构对象协调。
论文还专门点明:碰上要精确引用、追溯来源、定向删除或人工审核的活儿,上下文学习和检索增强生成仍是更合适的选择。纯文本存这些事毫不费力,但文本一旦被压缩、抽象进参数φ,再想倒推原始出处就变得极其困难。这就像原始凭证与总账的关系——总账记的是压缩后的余额,查起来方便,可要弄清某一笔具体交易的前因后果,还是得把原始凭证翻出来。
四个还没解决好的难题。
论文最后指出了四个开放方向,这部分读起来反而是最让我有共鸣的。
头一个是干扰与遗忘。连续的编辑操作加上循环的delta-rule更新,会不停覆盖此前存入的关联,而且更新序列拉得越长,损害滚得越大:编辑过的权重范数持续增大,扰乱了模型原有通用能力所依赖的方向,固定状态的记忆也会顺着当前的键产生干扰。子空间投影、范数约束、擦除门、写入门这些手段能拖慢这个崩塌过程,可它们要么得维护一份不断增长的历史键记录,要么只能护住当前这一次写入;面对长序列里的冲突检测和固定容量分配,眼下还没有彻底解决的办法。
第二个是获取过程的安全问题。一次来自不可信上下文的写入,事后可能被当作可信知识检索出来,而现有记忆系统大多不记录来源。写入的若是参数化记忆对象,这种被植入的异常行为甚至能藏进权重内部;行为层面的去学习操作又常常留下痕迹。所以更新预算控制、基于来源的写入门控、隐私感知的知识整合,都还是没解决的问题。
第三个是跟上下文学习的协同设计。上下文学习把记忆存成文本token,能表达更细粒度的信息;参数内记忆则带来效率上的好处,但有些场景确实需要细粒度的记忆访问。论文给出的开放方向,是让获取操作符A来定哪些信息留在上下文里、哪些进入参数对象φ,再让组合操作符C在一次前向传播中同时读取两者。
第四个是模型原生的递归式自我提升。论文观察到,眼下大多数所谓的"递归自我提升"其实发生在智能体的外层工具框架里——提示词、技能、知识库、工具都在模型外部被修订,模型本身岿然不动。真正模型原生的版本,应当让获取操作符A把部署过程中攒下的有用经验直接写进参数φ,让主干模型自己在参数层面持续进步,从而缩小离线训练和在线推理之间的那道鸿沟。
写在后面
读完这篇综述,我印象最深的反而不是具体某个方法,而是那个被反复强调的区分:获取和组合是两件事。
把“获取”和“组合”分开看,表面像是在学术上做一次账目划分,实际上戳破了一个被不少论文搅在一起讲的问题:很多号称“创新”的记忆机制,动刀的只是获取方式,组合那一步照旧走老路;反过来也一样。两件事一旦拆开,判断一个新方法究竟在哪个维度上真正往前走了,还是仅仅换了个外壳,就清楚多了。
论文里还有一句判断,我琢磨了挺久:未经修改的KV缓存不算参数内记忆。这句话逼着人重新想“记忆”到底指什么。运行过程中自然留下来的痕迹,跟主动构建、可以反复取用的知识对象,性质上根本不是一回事。这个区分放到人身上同样说得通——随手记下的便签和刻意整理的笔记本,都是纸上的字,可背后的认知投入和可靠程度差得很远。
综述没有回答的一个问题倒是留了下来:当一个模型真能把部署期间积累的经验持续写进自己的参数,它和人的学习过程还能差多少?如果结论是“没有本质区别”,这件事的分量恐怕比表面上重得多。
Q&A
Q1:参数内记忆和检索增强生成有什么区别?
A:检索增强生成的做法,是把相关文本直接拼进模型的输入上下文,每轮对话都得把这些文字重新处理一遍,算力开销跟着文本长度往上涨。参数内记忆不一样,它把信息压成模型参数或类似参数的对象,直接接进模型的前向计算,同一段文字不必反复编码,还能跨查询复用。
Q2:参数内记忆的“获取”和“组合”是什么意思?
A:获取操作符管的是生产记忆对象,比如用超网络从一份文档生成适配器矩阵;组合操作符管的是把这个对象接进模型的实际计算,比如当作注意力层的额外键值,或者当前馈网络的残差项。两者各走各的维度:一个决定记忆什么时候形成,一个决定记忆放在哪里读取。
Q3:为什么未经修改的KV缓存不算参数内记忆?
A:它是模型预填充输入文本时自然冒出来的副产品,并非由独立的获取操作符主动生产,不满足“独立获取性”这条判定标准。要是KV缓存由专门的编码器生成,那它就会重新被算进参数内记忆的范围。