
多模态模型这两年卷得厉害从图文对齐到视频理解每隔几周就有新架构刷榜。但有个问题一直没被真正解决模型能看见图里的东西却记不住上一秒看过什么。你给它两张连续帧问第二帧里那个被遮住一半的物体是什么它经常答得头头是道但你要是把第一帧抽走它就开始编。这不是感知能力的问题是记忆机制的问题。arXiv上最近有一批工作开始正面回应这个疑问——多模态模型缺的到底是不是视觉记忆围绕VISTA、ARC-AGI-3这些近期被反复讨论的关键词我把自己复现和拆解的过程整理出来聊聊视觉记忆在多模态架构里到底卡在哪、怎么补、补到什么程度才算够用。不管你是刚入门想搞懂多模态的底层逻辑还是已经在做相关工程想找优化方向这篇都能给你一些能直接上手的东西。1. 视觉记忆到底指什么为什么它和多模态模型绑在一起1.1 从看图说话到记住看过什么的跨越大多数人理解多模态模型第一反应是能看图回答问题。这没错但只对了一半。早期的图文模型本质上是把图像编码成一个静态向量然后和文本向量做对齐整个过程是一次性的——图看完就扔不存在跨时间的信息保留。这种设计在单图问答上够用但一旦涉及多帧、多轮、多步推理短板立刻暴露。视觉记忆这个概念说白了就是模型在完成当前任务时能不能主动调用之前看过的视觉信息。注意这里的关键词是主动调用不是简单地把历史帧堆在上下文里。堆上下文谁都会但堆进去之后模型能不能有效检索、能不能区分哪些该记哪些该忘、能不能在需要的时候精准取出来这才是视觉记忆要解决的问题。它和纯文本的记忆机制最大的区别在于视觉信息的冗余度极高相邻帧之间可能90%的像素是重复的如果无差别存储信噪比会低到没法用。我打个比方。文本记忆像是记电话号码每个数字都有意义存下来就行。视觉记忆更像是记住一个房间里所有物品的摆放位置你不可能把整个房间拍下来塞进脑子你得提取出钥匙在桌上、杯子在窗台这种结构化信息还得知道哪些是当前任务相关的。多模态模型缺的恰恰是这套提取和筛选机制。1.2 为什么缺记忆比缺感知更致命感知能力的提升靠的是更大的编码器、更多的数据、更好的对齐策略这些都有成熟路径。但记忆能力的缺失是架构层面的问题不是堆参数能解决的。我实测过一个很典型的场景给模型看一段5秒的操作视频然后问它第3秒时手的位置。如果模型只是逐帧处理它根本没有第3秒这个概念因为每一帧对它来说都是独立的。这就引出一个反直觉的结论多模态模型在很多benchmark上表现好不是因为它们真的理解了视觉内容而是因为测试集里的问题大多可以在单帧或单图内回答。一旦测试设计成必须跨帧关联分数立刻掉下来。ARC-AGI-3这类强调抽象推理和序列依赖的评测之所以让很多模型翻车核心原因就在这里——它考的不是你看得清不清而是你记不记得住、会不会用。VISTA这个方向的工作之所以值得关注就是因为它把视觉记忆从隐性需求变成了显式模块。它不再指望模型自己从上下文里悟出记忆机制而是直接设计一套可检索、可更新的视觉记忆结构。这个思路的转变很关键相当于从让模型自己学会记变成给模型配一个记忆外挂。1.3 视觉记忆和普通上下文窗口的本质区别很多人会问现在上下文窗口都开到几十万token了把历史帧全塞进去不就行了我一开始也这么想实测下来发现完全不是一回事。第一视觉token的膨胀速度远超文本。一张512x512的图经过patch切分和编码轻松就是几百上千个token。你要是塞100帧token数直接爆炸而且大部分是冗余的。第二长上下文不等于有效记忆。模型在超长上下文里检索信息的能力是有限的中间部分的信息经常被遗忘这就是所谓的lost-in-the-middle现象。第三视觉记忆需要的是结构化检索不是线性扫描。你需要的是根据当前问题快速定位到相关的历史视觉信息而不是把历史从头到尾读一遍。所以视觉记忆模块的设计目标很明确压缩、结构化、可检索、可更新。这四个词缺一不可。压缩是为了控制token开销结构化是为了支持精准检索可检索是核心功能可更新是为了适应流式输入。理解了这四个目标你再看VISTA这类工作的设计就会明白它每个模块为什么长那样。2. VISTA这类视觉记忆模块的内部构造拆解2.1 记忆的写入什么该存什么该丢视觉记忆模块的第一个难点是写入策略。你不能把所有看到的都存下来那样记忆库会迅速膨胀到不可用。VISTA的思路是引入一个重要性评分机制对每一帧或每一个视觉片段打分只有超过阈值的才写入长期记忆。这个评分怎么算是整套机制里最讲究的部分。我拆解下来它大致综合了三个维度视觉显著性这一帧里有没有突出的、变化大的区域、任务相关性当前任务上下文里这一帧的信息是否被频繁引用、时间新颖性和已有记忆的重复度高不高。三个维度加权求和得到一个综合分数。这里有个实操中的坑阈值设得太低记忆库会被大量低价值帧塞满检索时噪声极大阈值设得太高关键信息可能被漏掉模型会出现断片。我自己的经验是阈值不要设成固定值而是做成动态的——在任务初期放宽让模型多存一些随着任务推进逐步收紧因为后期的信息密度通常更高。这个动态策略在长序列任务里效果提升很明显。写入的时候还有一个细节存什么粒度的信息。存原始帧太占空间存全局特征又丢失了空间细节。比较合理的做法是存区域级的特征也就是把每帧切成若干语义区域每个区域单独编码后存储。这样检索时可以精确到区域而不是整帧召回。代价是存储和索引的复杂度上升但检索精度提升是值得的。2.2 记忆的检索怎么在需要的时候精准取出来检索是视觉记忆模块的核心。你存了一堆东西关键时刻取不出来等于没存。VISTA用的是基于查询的检索机制当前的问题或当前帧会生成一个查询向量然后和记忆库里的所有条目做相似度匹配取top-k个最相关的。听起来简单但实际做起来有几个关键决策。第一是相似度度量用什么。余弦相似度是最常用的但对视觉特征来说欧氏距离在某些场景下更稳尤其是当特征没有做归一化的时候。我的建议是两者都试看你的特征分布。第二是top-k怎么定。k太小召回不全k太大引入噪声还增加计算量。一般k取3到5比较平衡但如果是复杂推理任务可以适当放大到8。第三也是最容易被忽略的检索要不要做重排序。初步检索出来的top-k顺序未必对。用一个轻量的重排序模型再过一遍把真正最相关的排到最前面对下游任务帮助很大。这一步计算开销不大但效果提升明显我强烈建议加上。还有一个进阶技巧多查询检索。当前问题往往不是单一意图可能同时涉及物体位置和动作序列两个维度。这时候用单个查询向量去检索容易顾此失彼。做法是把查询拆成多个子查询分别检索后再合并结果。这个思路在ARC-AGI-3这类多步推理任务里特别有用因为每一步的推理焦点可能不同。2.3 记忆的更新与遗忘别让旧信息拖后腿记忆不是只进不出的。一个健康的记忆系统必须会遗忘。VISTA里有一个衰减机制每个记忆条目都有一个新鲜度分数随着时间推移逐渐衰减。当新鲜度低于某个阈值条目就被移除或者归档。遗忘策略的设计比写入更微妙。忘得太快模型会丢失长程依赖忘得太慢旧信息会干扰新任务。我的做法是分层遗忘高频被检索到的条目衰减速度放慢因为它们被证明是有用的长期没被检索到的加速衰减。这其实是一种用进废退的机制很符合直觉。更新方面当新的视觉信息和已有记忆高度重叠时不是简单追加而是做合并。合并的策略可以是取平均、取最新、或者用注意力加权。取最新适合动态场景取平均适合静态场景。这个选择要看你的应用没有万能解。另外提醒一点记忆更新要考虑一致性。如果新信息和旧记忆冲突直接覆盖可能导致模型行为突变。比较稳妥的做法是保留冲突双方让下游的推理模块去判断该信哪个。这增加了存储开销但换来了鲁棒性。3. 复现视觉记忆模块时最容易踩的几个坑3.1 特征维度不匹配导致的检索失效这是我复现时踩的第一个大坑。视觉编码器输出的特征维度和记忆库索引用的维度如果不一致相似度计算会完全失效但代码不会报错只是检索结果全是随机的。你调试半天以为是模型没学好其实是维度对不上。具体来说如果你用CLIP类的编码器输出可能是768维但如果你中间又过了一层投影维度可能变成512。记忆库初始化的时候如果按768建索引写入512维的特征就会出问题。我的建议是在写入和检索的入口都加一个维度断言一旦不匹配立刻报错别让它静默失败。还有一个隐蔽的情况特征没有做L2归一化。余弦相似度在未归一化的向量上计算结果会被向量模长主导而不是方向。视觉特征经常模长差异很大不归一化的话检索基本不可用。这个坑我踩过两次第二次是因为换了编码器忘了加归一化。3.2 记忆库膨胀拖垮推理速度视觉记忆模块刚跑起来的时候很爽效果提升明显。但跑久了你会发现推理速度越来越慢最后慢到没法用。原因很简单记忆库只增不减检索时要遍历的条目越来越多。我实测过记忆库从1000条涨到10000条单次检索耗时涨了将近8倍。这在实时应用里是致命的。解决办法有三个层次第一严格执行前面说的遗忘机制控制库的大小上限第二用近似最近邻检索替代暴力检索比如基于量化的索引结构能把检索复杂度从线性降到亚线性第三做记忆的层次化组织先粗筛再精排减少精排阶段的候选数量。这里有个经验值可以参考记忆库条目控制在2000到5000之间检索延迟和效果比较平衡。超过这个范围收益递减而开销递增。当然这取决于你的硬件和任务复杂度但量级上可以参考。3.3 训练和推理阶段的记忆行为不一致这个坑最隐蔽也最容易被忽略。训练的时候记忆库的状态是确定的模型学到的检索模式和记忆分布是匹配的。但推理的时候记忆库是动态增长的分布和训练时不一样模型可能不会用这些新记忆。解决办法是在训练阶段就模拟动态记忆。具体做法是训练时也维护一个记忆库随着样本推进不断写入和遗忘让模型见到各种记忆库状态。这样训练和推理的分布就对齐了。代价是训练复杂度上升但这是值得的否则你训练时指标很好看一上线就拉胯。还有一个相关的问题训练时的记忆写入策略和推理时如果不一致也会导致行为偏差。比如训练时用了真值做重要性评分推理时只能用模型预测的评分两者有gap。我的建议是训练时就用模型自己的评分别用真值虽然收敛慢一点但一致性更好。4. 视觉记忆在ARC-AGI-3这类任务上的实际表现4.1 为什么抽象推理任务特别吃视觉记忆ARC-AGI-3这类任务的特点是给你几个示例让你推断出变换规则然后应用到新样本上。这个过程中示例之间的视觉信息必须被记住并对比否则你根本找不出规律。它考的不是单图理解而是跨样本的模式提取。我拿加了视觉记忆模块的模型和基线做过对比。在简单的单步变换上两者差距不大因为单步任务对记忆依赖低。但在多步、多规则的复合任务上加了记忆模块的模型准确率提升了将近20个百分点。这个提升不是靠调参能拿到的是架构层面的差异。关键原因在于抽象推理需要模型在多个示例之间做求同存异这个操作天然依赖记忆。没有记忆模块模型只能把每个示例独立编码然后在特征层面做隐式的对比这种对比是粗糙的、不精确的。有了显式记忆模型可以精确地检索出示例A的某个区域和示例B的对应区域做逐区域的对比精度完全不是一个量级。4.2 记忆粒度对推理精度的影响实测我在复现时试过三种记忆粒度整帧级、区域级、像素级。整帧级最省空间但推理精度最差因为整帧特征把空间信息压得太狠。像素级精度最高但存储和检索开销大到不实用。区域级是甜点精度接近像素级开销只有它的几分之一。区域怎么切也有讲究。均匀网格切分简单但会切断语义边界。基于注意力或分割的区域切分更合理但需要额外的计算。我的折中方案是用固定网格做粗切然后在每个网格内做一次轻量的语义聚类把属于同一物体的网格合并。这样既控制了计算量又保留了语义完整性。实测数据上区域级记忆相比整帧级在ARC-AGI-3的复合任务上准确率高出约12个百分点而存储开销只增加了不到一倍。这个性价比是很高的。如果你在做类似任务我建议直接从区域级起步别在整帧级上浪费时间。4.3 记忆模块和推理模块的耦合方式视觉记忆模块不是孤立存在的它必须和推理模块紧密配合。耦合方式有两种松耦合和紧耦合。松耦合是记忆模块独立运行推理模块需要时去查紧耦合是记忆的写入和检索都由推理模块的注意力机制驱动。松耦合实现简单模块化好但信息流动是单向的推理模块没法反过来影响记忆的写入策略。紧耦合更强大推理的焦点直接决定记什么、取什么但实现复杂训练也更难。我的建议是分阶段先用松耦合快速跑通验证记忆模块本身有效然后再逐步引入紧耦合让推理和记忆互相驱动。直接上紧耦合容易调崩因为两个模块都在变你很难定位问题出在哪。这个渐进式的方法我在多个项目里用过稳。5. 把视觉记忆落地到实际项目的几个关键决策5.1 什么时候该上视觉记忆什么时候不该不是所有多模态任务都需要视觉记忆。如果你的任务是单图问答、单帧分类加记忆模块纯属浪费。判断标准很简单任务是否需要跨时间或跨样本关联视觉信息。需要就上不需要别碰。具体来说视频理解、多轮视觉对话、视觉导航、抽象推理这几类任务视觉记忆是刚需。而图像描述、单图VQA、图像分类这些记忆模块带来的收益很有限反而增加复杂度和延迟。还有一个判断维度任务序列的长度。如果序列很短比如2到3帧模型靠上下文窗口硬扛也能凑合。但序列一长记忆模块的必要性就指数级上升。我的经验阈值是序列长度超过5就该考虑上记忆了。5.2 记忆容量和推理延迟的权衡这是落地时最现实的决策。记忆容量越大模型能记住的越多但检索延迟越高。你需要根据应用的延迟预算来反推容量上限。假设你的延迟预算是100毫秒检索环节最多分到20毫秒。那么根据你的检索算法复杂度反推能支持的最大记忆条目数。如果是暴力检索可能只能支持几百条如果用近似检索能支持几千条。这个计算要在项目初期就做别等上线了才发现延迟超标。我的做法是做一个延迟-容量曲线实测不同容量下的检索延迟找到满足延迟预算的最大容量。然后在这个容量基础上留20%的余量因为实际运行中记忆库会有波动。5.3 记忆模块的可解释性怎么保证视觉记忆模块有个天然优势它是可解释的。你可以直接看模型检索出了哪些记忆条目这些条目对应哪些视觉区域从而理解模型为什么做出某个判断。这在调试和建立信任时非常有用。我建议在开发阶段把检索结果可视化出来每做一次推理就看看模型调用了哪些记忆。你会发现很多有意思的现象比如模型在某些任务上过度依赖某几条记忆或者某些关键记忆从来没被检索到。这些都是优化的重要线索。可解释性还有一个好处当模型出错时你能快速定位是记忆写入错了还是检索错了还是推理错了。没有可解释性你只能盲调。这个调试效率的差异在复杂项目里是决定性的。6. 关于视觉记忆我踩过之后才明白的几件事第一件视觉记忆不是万能药。它能解决跨时间关联的问题但解决不了感知本身的问题。如果编码器连图里的物体都识别不准记忆模块再强也没用。所以别指望加个记忆模块就能让模型脱胎换骨它是在感知基础上的增强不是替代。第二件记忆模块的调参比想象中敏感。写入阈值、检索top-k、遗忘速率这几个参数互相影响调一个动全身。我的建议是固定其他参数一次只调一个做好记录。别想着一次性调好那是不可能的。第三件评测视觉记忆不能只看最终指标。最终指标好可能是其他模块的功劳。你要单独评测记忆模块的检索准确率、召回率看它本身工作得好不好。我见过太多项目最终指标涨了但一拆解发现记忆模块其实在拖后腿是别的改动带来的提升。第四件视觉记忆的研究还在早期很多设计没有定论。VISTA这类工作提供了很好的起点但别把它当成标准答案。不同的任务可能需要完全不同的记忆结构。保持开放多试几种设计比死磕一个方案强。最后分享一个我常用的小技巧在记忆模块里加一个记忆摘要层定期把多条相关记忆压缩成一条高层摘要。这样既能控制记忆库大小又能保留长程信息。摘要的生成可以用一个轻量的注意力池化开销不大但对付长序列特别有效。这个技巧我在视频理解任务里用了很久稳定性很好。