如何让【模型本身】具有记忆:存入参数
这两天接触到了一个非常有探索性的记忆项目:摒弃外挂文本,将记忆存入参数
首先,我认为:上下文即一切对模型来说,上下文有三种来源:人给的、Agent 给的、模型内化了的
之前在新华社做分享时的 ppt
前两种都是文本:人复制资料、写提示词、传文件;Agent 联网搜索、读知识库、调接口。最后都塞进上下文窗口,这次对话用完就没了
而第三种模型的内化记忆,则只有一个方法:训练,训练时读过的东西,被压进参数里
在我们使用 Agent 的时候,经常会把 Skill 越写越多、越写越长,希望把这些记忆和所有可能用到的东西都放在 Skill 里
但这样的话,很多时候会让模型本身对这些要点的把握变得越来越不准确、越来越不到位,反而降低了模型的效果。于是我们就要开始想:能不能将模型记忆,内化到参数呢?
开头说的那个项目,就是记忆张量团队的 MemT 1.0。它的技术报告给了一套完整的解法,思路大概是:将记忆内容写到一个固定大小的记忆状态,具体则由模型自己定
这个思路是区别于之前的外挂方式的,尝试让记忆长在模型里面,这非常 RSI比如我们之前让模型干成什么事儿,以后希望它记着。之前的做法是让它记成 Skill,之后去翻这个文档;而如果这种内化的记忆能够非常有效的落地,那还要个毛的文档
而在效果上,把经验写进记忆之后,SWE-bench Verified 上从 54.0% 涨到了 61.6%
下面的机制和数据都来自这份 tech report
report:arxiv.org/abs/2610.26825
模型记忆,一直靠外挂文本
现在大家说的「模型记忆」,所实现的方法,几乎都是让模型动态加载记忆文本,包括:
你写的提示词、上传的文件
Agent 检索回来的知识库片段、搜索结果
Personal Agent 攒下的用户画像、对话摘要、记忆文件
用的时候,由模型外面的程序决定拿哪几段,塞进上下文
这种做法和思路是非常自然的,但也是有一些可见的问题的
一、记忆方法是确定的把哪些内容存到记忆里,其实就是靠预先设定的一些规则。模型在上下文中看到了符合规则的内容,就会用文本把它存下来或者更新而如果某些内容没有触发这些规则,模型其实就不会去记录它,那么对模型来说它也就是不存在的
二、越用越贵就像是本文刚开始所提到的,如果你希望让这个记忆里有着足够的东西,那么你就总需要把上下文给到,那么你们的整个上下文就会越来越长,单次对话也将越来越贵
三、并不能真正复用假如说,我希望让模型能在某些场景里表现的越来越好,我就需要动态的加载与更新各种 skill 或者文档。这样的话,无论我是第一次对话,亦或者是第 100 次对话,体感上也只是模型在回答我问题前参阅了工作文件,就显得非常不自然
每开一个新会话
当然,也有人试过把历史直接训进参数,比如 Temp-LoRA:拿这段历史,现场训练一个小的适配层。问题是慢,128K token 的历史,从准备到答完要 700.82 秒,原样带全文是 30.07 秒
所以,要彻底甩掉外挂文本,让模型本身产生记忆,得满足两件事
记忆需要存在模型的计算里,而非文本
记什么、怎么记,需要由模型自己决定
另一条路:让记忆内化
如果不依赖外挂文本,记忆放在哪?
MemT 用两个模型做的实验,一个是 Qwen3.6-35B-A3B,另一个是经过初步后训练的 DeepSeek-V4-Flash(288B 版)
方法是在主干的一部分 Transformer 层里,加一个原生记忆块,跟原来的注意力并排跑,然后两路输出相加,36B 版的记忆状态是 10M,288B 版是 336M。在这个过程中,主干的权重不做修改
架构图
对于记忆块,分两部分:
本地记忆(local memory):每层一块矩阵,就是记忆本身,随对话更新
超记忆(hyper memory):决定怎么写、怎么读的那些参数,上线后固定
记忆写入
在每一轮对话结束的时候,会触发记忆写入操作这时,模型将上下文的输入&输出的所有 token 逐个 token 过一遍,来决定三件事:
记忆储存在哪个位置
那个位置上原来的东西擦掉多少
新内容写进去多少
比如:用户先说展览定在周六,后来又说改到周日,读到“周日”的时候,原来那个“周六”就该被擦掉在这个过程中,模型的整块记忆也都会统一淡掉一点(越早写进去的,淡得越多)
这里有一个小的 trick:几万个 token 连着改,记忆里的数值容易越滚越大,最终导致整个记忆系统崩溃。所以擦除时,它只会把数值往小了改,而不会去放大。于是无论聊多久,这一块的记忆总归都只有这么大,写完之后,这一轮的原文也就不必往下带了
记忆读取
当模型在之后问答的时候,就会进行记忆的读取,混合原有模型的权重,去不断地进行推理
在这个过程中,记忆大小是固定的,读一次的开销也是固定的,以保证模型在长期使用后,速度也不会受到影响
模型如何学会记忆
对于外挂的文本记忆,通常是有一些人写的规则,比如要让模型去记住谁什么时候谈了哪些话,然后模型再照着规则把对话中的内容给摘出来,形成有效的记忆
模型自己记,就没有这份规则了,只能让模型从结果里学:记住的东西,是否能帮助回答之后的问题至于具体的做法,是让模型模拟自我蒸馏(emmmm...好像也不是很准确,反正大概意会一下这个意思),让模型准备两份上下文:
一份能看到完整的历史原文,作为蒸馏里的老师
一份是本轮对话+记忆,作为蒸馏里的学生
学生的目标,便是在看不到原文的情况下,与老师做到相同的回答
记忆效果
对于训练得到的记忆,在一些方面是优于外挂记忆的,比如成本;但也有不如的地方。这里也是做一个简单的比照
一、记忆成本有优势
在通过训练的方法进行记忆储存后,它的记忆表征是固定的。无论历史多长,它存的内容也就只有 40 MiB,确保了速度和成本
当然,你也可以选择把这个记忆的容量去扩充,这个时候分数也会跟着涨(记忆未尝不能 scale)
二、经验也能写进去
tech report 从 4 万多条成功的代码轨迹里,总结出 1,040 条经验,干活时把相关的那条写进模型的记忆,对话里一个字都看不到在 SWE-bench Verified 上,每道题跑三次,三次都做对的比例从 54.0% 涨到 61.6%,和把经验直接塞进对话里一样
过去攒下的经验,不占上下文,也能用在新任务上
三、准确性逊于原文
虽然这种方法,在 11 项记忆测试里都做到了最优,但离外挂文本还有一截(50.6 对 68.6)
毕竟外挂文本能直接翻原文,理论上能做到 100% 还原
原生记忆的关键
和外挂文本比,原生记忆真正不一样的地方,我觉得有三点
一、能长出新的经验
用明文记经验,记下 1、2、3 条,就永远只有这三条而经验写进参数之后,模型有可能把这三条融到一起,自己得出第 4 条
这也是大模型强于 KB-QA(基于知识库的问答)的核心原因:知识库只能查到存进去的东西,模型却能把学到的东西组合起来用
或许这个思路,能够做出未来的 Memory Scaling 也不一定
二、越用越便宜
高频读写的记忆和经验,内化进模型之后,不用每次再塞一遍上下文,用得越多,成本越低(或许以后每个组织都可以把自己的记忆内化,拥有一个独特的基座)
三、对 RSI 或许有用
RSI 常见的思路,是让模型拿自己做对的答案,再训练自己,以提高可靠性:把偶尔做对的题,练成经常做对
拿 DeepSeek-V4-Flash 做后训练时,有两组数据:之前 8 次都没做对的题,练完正确率只有 1.6–4.0%;另一组很难的知识题,不训练,只把相关事实放进上下文,正确率就从 27% 涨到了 91%
而现在,这些收获都以外挂文本的形式放在模型外面,或许可以尝试把这些东西做到模型里面
最后
论文、模型和代码都已公开,感兴趣可以看看
github