先给结论

MemT-1.0 是记忆张量(MemTensor)10 月 19 日挂到 arXiv 的记忆基础模型系列(arXiv:2610.26825,74 位作者,66 页)。它做的事可以一句话概括:把「记住上一轮说了什么」从提示词里的文本,挪成模型前向传播里的一块固定大小矩阵状态。选定的 Transformer 层里加一条与注意力并行的记忆分支,生成时读这块状态,每轮结束后往这块状态里写。

模型有两个:Nano 基于 Qwen3.6-35B-A3B,36B 总参 / 3B 激活;Flash 基于 DeepSeek-V4-Flash,288B 总参 / 17B 激活。

而标题里的「33 倍」不是一项压缩技术,它是一个除法结果。下面先把它算清楚,再说清这个数字能主张什么、不能主张什么。

33 倍怎么算:一道乘法题加一道除法题

先算分子。记忆状态的大小由几何配置直接决定,官方仓库和论文给出了单层形状:

  • Nano:H_kv = 16 个通道,d_k = 256,d_v = 256,挂在 10 个全注意力层上(第 3、7……39 层)。
  • 单轨迹状态元素数 = 10 × 16 × 256 × 256 = 10,485,760 ≈ 10.5M。这也正是仓库表格里那个 “10M dynamic memory”。
  • 以 FP32 存,10.5M × 4 B = 约 40 MiB,且与历史长度无关。

Flash 同理:20 层 × 64 通道 × 512 × 512 = 3.355 亿元素,FP32 约 1280 MiB。所以「336M dynamic state」是可验算的,不是营销数字。

再算分母。完整上下文方案的持久状态是 KV cache,随 token 数线性增长。于是同一个 40 MiB 的分子,除以不断变长的分母,就得到一串看起来差别很大的倍数:

历史长度官方口径的压缩比反推的 KV 侧用量
64K33×≈1.3 GiB
128K66×≈2.6 GiB
256K~130×(40 MiB vs 5.06 GiB)≈5.1 GiB

倍数几乎严格随长度翻倍:64K→33、128K→66、256K→130。这说明它不是「压缩得更狠了」,而是分母在长大。 按 64K 的 1.3 GiB 反推,KV 基线约 20 KiB/token;这个每 token 成本受层数、KV 头数、头维、精度共同决定,公开材料里我没核到完整的 KV 配置,所以把它当作「由两个已公布数字相除得到的推算值」看待,别当成独立测量。

三条必须带上的前提:

  1. 分母不含共享权重。40 MiB 只是每条轨迹的持久状态,模型本体权重、当前轮的 KV 与工作区都还在。
  2. 是每轨迹,不是每服务。40 MiB × 一万个并发会话 ≈ 400 GiB;换成 Flash 的 1.25 GiB/轨迹,一千个会话就是 1.25 TiB。会话数增长时总存储照样线性涨。
  3. 状态是轨迹级的,不是权重级的。交互期间记忆参数冻结,不存在「模型在跟你聊天时偷偷微调自己」。

记忆怎么进入前向:一条读通路,一条写通路

每个 Native Memory Block 分两半:

Local Memory Block 存动态状态,就是上面那块 10 层 × 16 通道 × 256 × 256 的矩阵,新轨迹开始时初始化为零,一轮轮演化。

Hyper Memory Block 是可训练参数,含记忆 q/k/v 投影、擦除门、写入门、遗忘门,以及一个带 SoftCapSiLU 的输出门。这部分训练完就固定。

读:生成时用记忆 query 从当前状态做矩阵读出,归一化后过输出门,再与主干注意力的输出拼接相加。读取开销与历史长度无关——用一天和用一年,读一次的成本一样,这是它 TTFT 稳定的原因(官方报告 256K 下 104–112 ms,完整上下文方案约 445 ms)。

写:每轮(或每段)结束后,把输入和回复的隐状态投影成记忆 key/value,逐 token 更新状态。这一步用的是 Gated DeltaNet-2(GDN-2,NVIDIA 的线性注意力工作,arXiv:2605.22791),更新式是:

S_t = (I − k_t (b_t ⊙ k_t)ᵀ) D_t S_{t−1} + k_t (w_t ⊙ v_t)ᵀ

相比 Gated DeltaNet 和 Kimi Delta Attention,GDN-2 把「擦多少」和「写多少」从共享一个标量门拆成两个通道级门:b_t 在 key 轴上选择擦除哪些坐标,w_t 在 value 轴上选择提交哪些坐标,D_t 是通道级衰减。「展览改到周日」这种覆盖,本质是同一个 key 上把旧 value 擦掉再写新的——加性写入做不到这件事,它会叠加(这是 delta rule 相对 Hebbian 写入的老问题)。

「稳定」是这里的工程重点:(I − k(b⊙k)ᵀ) 这一项只会把状态往小调,不会放大,所以连写几万 token 也不会数值发散。论文消融里把 token 级更新换成轮次级,11 基准均分从 46.97 掉到 40.98;但把稳定化去掉,分数只到 46.43——粒度比稳定性更值钱,这一点和很多二手解读的印象相反。

MoS:为什么要稠密路由

Mixture-of-Storage 把每个记忆块扩成多个「记忆专家」,并配两个稠密路由器(一个管读、一个管写),共享一张可训练的专家地址矩阵;写路由调制各专家的擦除门、写入门和对数衰减。

反直觉的地方在于它没走稀疏激活。我的理解是优化目标不同:MoE 稀疏是为省算力,而记忆的失效模式是「该记的没记进去、该取的没取出来」,路由一旦学偏就是硬伤;稠密路由让所有专家都参与、只是权重不同,牺牲算力换召回覆盖面。代价是单块峰值显存高,所以他们做了窗口化执行:32K 打包、4 专家时,整体物化峰值 47.83 GiB,改成 4096 token 两窗口降到 9.49 GiB(−80.1%),前反向时间只多 1.6%。

训练:不是插上就能用

这一点最值得强调:把一块未训练的记忆缓冲插进现成模型,不会得到可靠的回忆能力。MemT-1.0 用了 34B token:20B 继续预训练 + 14B 后训练,目标是离策略蒸馏——冻结的全上下文主干当教师,学生只能看到记忆状态,用教师 top-64 分布的前向 KL 对齐。消融显示,拿掉后训练平均掉 10.7 分,拿掉继续预训练掉 2.1 分。

效果:赢在自己那一类,输在要证据的地方

11 项记忆基准上的均分:

  • 文本记忆类:MemOS 68.6、完整上下文 65.0–66.3、DenseRAG 57.3
  • 参数记忆类:MemT-1.0-Flash 50.6、Nano 47.0、Temp-LoRA 38.1、Doc-to-LoRA 30.9、SHINE 25.6、MemoryLLM 25.3

也就是说它稳坐「参数记忆」这一格的第一第二,但放在全体里仍落后于检索/全上下文。差距集中在需要细节证据的项:LongMemEval-S 上 Flash 37.2 对 MemOS 83.2,BEAM-1M 上 37.0 对 72.6。这是压缩的必然代价,官方仓库自己也写明「需要细节证据检索的长历史,强文本记忆系统仍然领先」。

通用能力的代价相对小:注入干扰信息后,Flash 平均差 0.0、Nano −0.9;但 Nano 在 LiveCodeBench v6 上掉了 5.8 分,任务级波动需要单独看。

Agent 场景是它最有说服力的部分。用 41,057 条 Scale-SWE 成功轨迹归纳出 1,040 条可复用经验(触发条件 + 步骤 + 约束 + 验证方式),检索后不塞进提示词、而是前向写进记忆:SWE-bench Verified 500 题 × 3 次独立运行,平均成功率 66.07% → 69.73%(文本经验组 69.13%),三次全成功率(pass^3)54.00% → 62.80%(文本组 61.80%)。提升幅度不大,价值在于同等效果下不占上下文,且重复运行的稳定性更好。

和已有方案的取舍

方案更新成本查询成本可溯源/可精确删除适合
长上下文 / KV cache低随长度线性涨最强,原文都在一次性长文档、需要引用原文
RAG低(改索引)检索延迟 + 上下文装载强知识频繁变更、要审计
每次会话微调(Temp-LoRA 一类)极高(官方提到 128K 历史准备要数百秒)低弱基本不实用
记忆槽(MemoryLLM 等)中低弱研究基线
MemT-1.0每轮一次前向写与长度无关弱长期会话、经验复用

关键取舍:它买到的是「查询成本与历史长度解耦」+「经验可内化」,付出的是有损压缩和可解释性。记忆是一块数值矩阵,你没法像查 RAG 那样指着某一行说「它记的是这句」,也没法精确删除某个事实。要合规删除、要引用原文的场景,别用它。

适合谁用,以及怎么起

适合:高频长会话的助手(客服、办公)、需要跨任务复用操作经验的编码 Agent、必须把首字延迟压平的产品。不适合:一次性长文档问答、需要逐字引用与审计、以及历史本来就短于 32K 的场景——官方自己承认 32K 以下大致打平、更短的历史反而更慢(64K 才 1.20×,128K 1.86×,256K 3.99×),因为写记忆本身要算力。

部署走 SGLang。仓库给的路径是先用脚本起服务,再用配套的 Python 客户端开会话:

# 用完整本地 checkpoint(BF16 权重 + config + tokenizer)
sh start_memt_nano.sh /models/MemT-1.0-Nano
# 双卡,监听 127.0.0.1:30000,记忆快照落在 ./memt-state
from transformers import AutoTokenizer
from memt_sglang.client import MemTSession, NativeClient, load_chat_format

tokenizer = AutoTokenizer.from_pretrained("/models/MemT-1.0-Nano",
                                          local_files_only=True)
chat_format, parser = load_chat_format("/models/MemT-1.0-Nano",
                                       tokenizer=tokenizer)

客户端只负责分词与协议,推理在服务端;MemTSession 承载的就是那条轨迹的记忆状态。工程上最需要注意的是 ./memt-state 的落盘目录:它是每会话一份的持久状态,容量规划按「并发会话数 × 40 MiB(Nano)/ 1.25 GiB(Flash)」算,而不是按上下文窗口算。

许可要分开看:代码是 PolyForm Noncommercial(商用需另行授权),Nano 权重 Apache 2.0,Flash 权重 MIT——这条最容易踩,别只看到「开源」两个字。

最后一句判断:MemT-1.0 的真正意义不在于 33 或 66 这个倍数,而在于它把「记忆」从应用层的字符串拼接,变成了一个有形状、可审计尺寸、随轨迹演化的张量。倍数会随长度变化,状态大小不会。

参考链接

创作说明:本文在资料整理与成文中使用了 AI 辅助(DeepSeek),经作者审阅后发布,作者对内容负责。

Logo

ModelScope旨在打造下一代开源的模型即服务共享平台,为泛AI开发者提供灵活、易用、低成本的一站式模型服务产品,让模型应用更简单!

更多推荐