最近我在梳理流式视频理解相关工作,看标题为 StreamTTT 的工作时,第一反应是:这名字起得太直白了。Stream + TTT,几乎等于把“流式视觉语言模型”和“测试时训练”两个词焊在一起。可真正吸引我的不是命名,而是它题目里的那组矛盾——Real-Time Perception 与 Long-Term Memory。
做过 Streaming VLMs 落地的人都知道,这组矛盾是所有实时视频理解系统的“房间里的大象”。模型不是没有能力看懂一帧画面,也不是完全没有记忆能力,而是当你要它一边看下一秒,一边记得几十秒前发生了什么,还要在延迟可接受范围内回答问题时,常规架构会迅速达到天花板。常见做法像是在给一个不断流进来的水龙头接一个永远在长大的杯子:今天能接住十秒,明天想接住十分钟,显存和延迟一起爆炸。
所以我想把这类方向拆开聊清楚:Streaming VLMs 到底难在哪,StreamTTT 想要协调的两种能力为什么冲突,测试时训练又能给出什么不一样的解法。下面的内容不会假装我能复现论文全部细节,主要从问题本质、机制推理和工程落地三个角度展开。
1. 实时感知和长期记忆不是功能冲突,而是状态管理问题
1.1 流式任务看起来只是加了“流”,实际上改变了解题顺序
先做个简单的对比。
一段普通视频理解任务,模型拿到的是完整、有头有尾的视频。模型可以先扫一遍全局,知道这段视频讲的是一场会议、一段体育比赛还是一次机器运行,然后再决定从哪一帧开始分析。这时候模型的时间观是“上帝视角”,过去、现在、未来都在输入里躺着。
但 Streaming VLM 面对的任务完全不同:视频流是持续不断的,模型面前永远只有当前这一小段时间。你可能问它“现在画面里有没有异物”,它不但要看懂这一帧,还要知道“异物是刚刚出现还是已经存在了一会儿”“上一段出现异物是什么时候”。这些问题都需要模型在不能回头重看的约束下回答。
真正让问题变难的不是“每帧识别”,而是时间尺度。单帧识别是感知问题,可以在预训练阶段解决得相当好;跨时间的状态判断是记忆问题,要求模型把过去的信息压缩、保存、检索,再和当前帧融合。这两件事在模型内部用的机制不一样,资源消耗模式也不一样。
StreamTTT 的题目之所以故意把 Real-Time Perception 和 Long-Term Memory 并列,我理解是它想说明:这两个需求不是一前一后排队完成的,而是要在同一条流上同时成立。你在实时看清当前画面的同时,其实也在持续改写模型对“之前发生过什么”的认知。
1.2 每一条新帧进来,模型都要做一次“先遗忘再决策”的过程
如果把一个 Streaming VLM 比作值班人员,他的桌上不能堆满过去所有帧,因为下一帧进来时他根本没地方放;也不能完全不在乎过去,因为大量问题要求跨时间回答。
于是每个 step 其实都在暗中做三个决定:
- 哪些旧信息已经没用了,可以丢。
- 哪些旧信息还有用,必须压缩保存。
- 当前帧的信息如何更新已保存的记忆。
听起来很自然,但在基于 Transformer 的主流架构里,这个“状态管理”过程是隐式的,而且常常失控。模型并不真正知道哪些 token 该丢、哪些该留,它只是把所有旧 token 塞进上下文里,让注意力自己去寻找需要的信息。如果旧 token 不太多,效果不错;一旦上下文变得很长,计算代价、缓存代价、还有注意力被稀释的问题就会一起冒出来。
所以我把这个问题称为状态管理问题,而不是功能缺陷。模型不是“记不住”,而是没有一种高效、可控、可更新的状态来表示已经发生过的长历史。
2. 一条暗线:长期记忆也许不该放在上下文里,而该放在模型状态里
2.1 上下文越长,代价不是线性增长,而是平方级增长
为什么不用滑动窗口加大一点就能解决?
假设每帧产生 F 个 token,新视频帧到达时把旧帧的 token 继续留在 KV Cache 中。当历史累积 N 帧时,注意力计算涉及的总 token 数是N * F。视觉 token 本身数量就很大,关键帧可能几百上千个 token。KV Cache 的显存开销可能是单帧 token 数的好几倍。
在真正实时的场景里,这个问题尤其尖锐。你不仅要保证单帧推理时间足够短,还要保证不会因为历史 token 积累造成越来越慢,最终跟不上视频帧率。很多人最开始跑流式 demo 能很流畅,跑 5 分钟后就开始掉帧,原因往往就是 KV Cache 在无声地膨胀。
滑动窗口看似解决了失控膨胀,但代价是记忆变成“最近几秒”。如果模型刚回答完“当前画面正常”,你立刻追问“那刚才那个异常事件持续了多久”,它就会因为没有历史记忆而卡住。窗口太大模型能记住,但实时性崩掉;窗口太小心实时性够了,但记忆能力不足。StreamTTT 想打破的正是这个非此即彼。
2.2 摘要、检索、记忆池:都是好用的外挂,但都没有解决“更新”这个问题
工程上常用的妥协方案有几种:
- 把历史帧抽帧,让 LLM 定期生成摘要,存成更短的文本。
- 把关键帧的 embedding 存到向量数据库,回答问题时做相似度检索。
- 设置一个外部记忆池,把重要事件按时间戳写进去,回答时额外拼给模型。
这些方案都能一定程度上平衡实时感知和长期记忆,但如果细看,就会发现它们都假设“记忆”独立于“感知”存在。系统先感知,把关键信息提取出来,再写进外部记忆。问题在于:什么样的信息算关键,本身就是动态的。你看完第 50 秒后,可能才发现第 10 秒那个普通瞬间是关键。如果当时没有把那个瞬间存下来,后面再检索也没用。
所以这类外挂方案真正瓶颈不在存储,而在“当时当刻如何决定该记住什么”。这个决定需要模型对当前帧和历史上下文有联合理解,而且需要在极短的时间内完成。
2.3 一种反直觉的设计:“记忆”不应该是缓存,而应该是模型参数
这里有一条在 RNN 时代很流行、后来被 Transformer 遮蔽的思路:把记忆放在模型的隐藏状态里。
RNN 的隐藏状态本质上是一个向量,在每步读入新 token 后更新,因此天然适合流式输入。它的容量非常有限,一个几千维的向量很难编码复杂的长视频历史。这也是它后来在长序列任务里被 Transformer 压倒的重要原因。
但如果把“隐藏状态”的概念升级一下,不再只存一个向量,而是让隐藏状态本身是一个可更新的模块,情况就不同了。传统 RNN 的隐藏状态被固定大小的向量卡住,而“把记忆当作参数”的思路允许隐藏状态拥有更强的表达能力。这就引出了 StreamTTT 这类工作的核心机制:Test-Time Training(TTT)。
3. TTT 提供的机制:在测试时,让模型自己更新自己
3.1 拆开看:什么是 Test-Time Training
Test-Time Training 的基本想法很反直觉:模型推理时不只用前向传播做预测,还会先在测试输入上做一步自监督学习,更新一部分模型参数,然后再做预测。
过去 TTT 更多用于分布偏移场景。比如训练集里只有晴天照片,测试时来了雨天照片,模型可以在雨天照片上先做一步自监督任务,把自己稍微调整到更适应雨天分布,再输出分类结果。它相当于把训练过程延伸到了测试阶段。
而把 TTT 用在长上下文建模上的关键工作,我清楚地记得是 2024 年的那篇Learning to (Learn at Test Time): RNNs with Expressed Memories。它把 RNN 的隐藏状态从一个固定向量升级成了一个小型模型的参数。每读到一个新 token,模型不仅更新 RNN 的外部隐藏状态,还要在内部更新这个“记忆模型”。换句话说,模型对待见过的内容,不是把它们简单堆在缓存里,而是把它学进自己的参数里。
这正好给流式 VLM 提供了一个可能的答案:与其让视频帧 token 无限堆积,不如在每一帧到达时,用当前帧和之前状态构造一个自监督目标,让模型把“这一段历史”编码进一个可更新的记忆表示里,之后旧帧 token 可以放心丢弃。
3.2 为什么这个机制和视频流任务天然契合
视频流任务里,通常找不到一个完美的“未来监督信号”,但同一个视频流内部有大量自然的自监督目标。
一个很简单的例子:当前帧前面几帧都描述了同一场景,模型如果能利用前后帧的一致性做重建或者对比学习,就有机会把“这个场景现在长什么样”沉淀到记忆参数里。之后即使这些帧不再出现在上下文中,记忆参数仍然保留着该场景的核心信息。
这种“看完一段,学进一段,然后放下一段”的过程,非常接近人理解视频的方式。你不是在脑子里回放所有帧,而是不断更新自己对“事情发展到哪一步了”的理解。
TTT 在这里还有一个工程上的吸引力:它不依赖未来帧,符合流式约束。每处理一帧,只需要当前帧和当前记忆状态,不需要停在那里等后面的帧。对于 Streaming VLM 来说,这是比双向注意力模型更适合的机制。
3.3 一个值班交接记录式的类比
可以把流式视频理解比作多个人轮班盯监控。传统的 Transformer 方案,相当于每个人接班时都把之前同事写的所有原始日志一字不差地贴出来,然后自己从头读。日志越来越厚,接班越来越慢。摘要方案呢,相当于上一班同事给了一个很短的总结,但总结往往遗漏了只有看到原始画面才能判断的细节。
TTT 风格的做法,更像是一本可以随时改写的交接记录:里面不只是文字,还有当前场景的关键状态。每个值班人员看到新情况后,会按一套规则更新记录,重要的新情况写进去,不再重要的旧细节被覆盖掉。后来的接班人员不用翻阅所有旧日志,只看这本最新状态的记录就能快速形成判断。
这个类比当然不完美,但它能解释一个问题:为什么长期记忆和实时感知不能通过“加长窗口”或者“简单摘要”轻松解决。因为两者本质上都把历史当成静态的东西,而不是随每个新帧同步更新的动态状态。
4. StreamTTT 的三种可能机关:从题目里读出的方向
接下来这部分我必须先说清楚:相关论文摘要和完整方法细节在我掌握的材料里没有完整出现,所以这里不是复述给定结论,而是结合标题、热词和技术脉络做推理。StreamTTT 的完整名称是 Reconciling Real-Time Perception and Long-Term Memory in Streaming VLMs。如果我们要理解它可能怎么实现,可以从题目中的 “Stream”、“TTT”、以及“长期记忆”三个词分别出发。
4.1 方向一:视觉 token 不直接进 LLM,先进 TTT 记忆层
流式 VLM 的做法通常是:视频帧经过视觉编码器变成若干视觉 token,然后和文本指令一起进入 LLM。当视频流很长时,视觉 token 越来越多,LLM 的上下文压力也越来越大。
一个自然的改动是,在视觉编码器和 LLM 之间插入一个 TTT 层。该层每次接收一小段视觉 token,不把它们全部交给 LLM,而是先把视觉信息压缩进 TTT 层的“记忆参数”。LLM 实际看到的,只有 TTT 层当前状态对应的输出表示。这样旧帧没有堆积在 LLM 上下文里,而是被编码进了一个不断更新的状态。
这个设计如果成立,真正的收益是:LLM 自身处理的 token 数可以保持相对稳定,不再随视频时长无限增长。模型“记住十年前”和“记住十秒前”的代价差异,也从“逐 token 重放”变成“状态更新一次”。
这种设计在直觉上最接近 TTT 论文里“替代 self-attention”的角色。把一个长序列处理问题,转变成一个固定大小的状态更新问题。
4.2 方向二:快速感知和慢速记忆走双时间尺度
“Reconciling Real-Time Perception and Long-Term Memory”还有一种可能的实现方式:系统中存在两套时间尺度。
- 快速尺度:负责当前帧的理解,要求低延迟,关注视觉细节,窗口很小。
- 慢速尺度:负责历史信息的长期积累,用 TTT 维护一段缓慢更新的记忆,不会因为单帧抖动而剧烈变化。
这有点像人脑的感觉记忆和工作记忆的分离。感知层看到的永远是“现在”,但长期记忆层把“现在”的经验慢慢沉淀到结构化的状态里。需要回答“刚才发生了什么”这种问题时,模型不直接去查原始帧, 而是查那个已经更新到当前时刻的记忆层。
如果 StreamTTT 真的采用双时间尺度结构,它的核心贡献可能不只是“用 TTT 替代注意力”,而是提出一套如何在流式 VLM 中分配“快速感知资源”和“慢速记忆资源”的思路。前者看重实时性,后者看重一致性。
4.3 方向三:把“连续语义”当成 TTT 的自监督目标
TTT 要更新参数,必须有一个损失函数。但视频流没有人工标注帧,所以自监督目标的选取很关键。
从常见做法推测,StreamTTT 大概率利用视频时间连续性:当前时刻的隐表示应该能预测邻近时刻的某种信息,或者同一事件里的多次观测应该在记忆空间中保持相近。这有助于让 TTT 层学会“什么值得保留”。
但这里有一个需要特别注意的点:连续帧之间不一定都相似。视频里常见镜头切换、场景突变、事件转折。如果自监督目标只奖励“预测相近的下一帧”,模型可能在场景切换后更新不上来。成熟的实现应该需要设计一个门控或者切换机制,让记忆在连续阶段平稳更新,在突变阶段允许重置或者大跨度调整。
在没有读到论文完整方法前,我不建议把上面三个方向当成已证实的结论。更合理的做法是,把它们当作重新设计实验时的三种假设,用可复现的实验一一代入验证。
5. 和其他记忆方案对比:各有各的取舍
为了把 StreamTTT 的定位讲清楚,我整理了一张记忆方案对比表。这些方案在 Streaming VLM 长期记忆问题上各有拥趸,核心差异就在于“在哪个环节做记忆”以及“是否动态更新”。
| 方案 | 实时性能 | 长记忆能力 | 状态是否动态更新 | 主要风险 |
|---|---|---|---|---|
| 长上下文 + 全量 tokens | 随上下文增长下降明显 | 强,但资源消耗不可控 | 否,靠注意力隐式检索 | KV Cache 无限膨胀,延迟难以保证 |
| 滑动窗口 | 最好,基本恒定 | 弱,只保留最近一段 | 否,超出窗口直接丢弃 | 对需要历史事件的问题几乎失效 |
| 周期性文本摘要 | 中等,摘要生成本身耗时 | 中,依赖摘要质量 | 半动态,历史被重写后无法纠错 | 关键细节丢失,摘要口径不一致 |
| 外部向量检索 | 中等,检索耗时有波动 | 强,数据库可无限扩展 | 否,写入时一次性决定 | 写入时没标记为重要就再也查不到 |
| 外部记忆池/事件流 | 中等 | 中强,取决于事件抽取质量 | 半动态 | 需要额外的“事件感知识别”模块 |
| TTT 记忆状态 | 理论上接近恒定,单步更新 | 中强,取决于记忆参数容量 | 是,每帧都会更新 | 更新机制不稳定,自监督目标设计难 |
对这张表,补充几个判断:
- 滑动窗口仍然是基线里最实用的一种,因为它简单、可控、不会在实时场景中失控。但它“没有记忆”的缺陷决定了它只适合那些只关心当下的任务。
- 外部向量检索适合离线事件回溯,但在流式场景里,它非常依赖你早先是否已经识别并索引了相关信息。你没有办法检索一个在写入时就被判定为“不重要”的事件。
- TTT 不是全能解,它把记忆问题转化为“记忆参数容量”和“更新目标设计”问题。参数容量太大,单步更新慢;太小,记忆能力不足,可能比摘要好,但远达不到“忠实记住所有关键帧”的程度。
这也是我认为 StreamTTT 这类工作的价值在于“协调”而不是“碾压”的原因。它不是宣称自己解决了长期记忆问题,而是把实时感知和长期记忆放进同一个更新循环里,让双方可以互相迁就。
6. 从“看起来有道理”到“真的有效”:评估和复现时容易翻车的地方
如果看完前面分析,你很想自己做一个 TTT 风格的流式 VLM 实验,那么评估环节比模型结构更值得先想清楚。
6.1 先定义清楚:你要评测的是实时感知,还是长期记忆,还是两者协同
一个常见错误是,拿一段短视频直接测试。短视频里模型只要上下文装得下全部帧,就能把问题答对。这考察的其实还是长上下文能力,不是流式记忆能力。
要验证“实时感知 + 长期记忆”的协同能力,通常需要构造如下条件:
- 视频流足够长,明显超出模型上下文窗口。
- 关键事件出现在较早时刻,但问题在几十秒甚至几分钟后才被提出。
- 视频流以“逐帧到达”的方式输入,模型不能一次性看到全部未来帧。
- 对模型回答案延迟有约束,不允许把整段视频先缓存再离线处理。
我建议在一开始就把评测集拆成三档,分别看三件事:
- 感知档:只问当前画面内容,确认模型的基础单帧理解没有退化。
- 短期记忆档:事件出现在 10 秒内,确认快速更新路径正常工作。
- 长期记忆档:事件出现在数分钟前,中间穿插大量无关帧,确认模型没有遗忘。
只有三档都有结果,你才能定位瓶颈在感知、记忆还是两者协调上。
6.2 常见的失败现象和排查链路
如果效果不好,先不要急着调整 TTT 损失函数的权重。按下面顺序排查,通常能更快定位问题:
- 先看输入流本身:视频帧有没有按时序输入?有没有丢帧、乱序、重复帧?TTT 更新对顺序非常敏感,输入乱序会导致记忆状态反复被改写。
- 再看记忆更新是否真的发生:把模型在插入 TTT 层前后做输出对比。如果效果没有差异,大概率是 TTT 层被旁路,或者损失权重太低,模型没有真正利用记忆。
- 然后看记忆容量:把记忆参数从小调大,观察长时记忆问题是否改善。如果提升不明显,问题可能不在容量,而在更新目标没有让记忆编码到足够关键的信息。
- 接着看事件密度:如果视频里每秒都有大量不同事件,模型可能来不及在记忆里完成更新。这就要检查 TTT 层更新频率是否和帧率匹配。
- 最后看评测问题本身:如果问题问的是“某帧出现了什么具体文字”,这本来就更适合检索式方案,TTT 风格记忆不一定能很好支持。这类细粒度跟踪需求和“全局状态理解”需要分开测试。
一个务实的建议:先用离线小规模闭环验证,再上实时流。不要一开始就接摄像头或者直播流,否则排查输入问题和模型问题会混在一起,很难快速定位。
6.3 什么时候值得上这种方案,什么时候还是别硬上
最后聊适用边界。
需要 TTT 风格记忆的场景通常具备这些特征:
- 历史信息和当前判断必须连续关联。
- 视频流很长,且模型需要以几乎恒定的延迟工作。
- 关键信息散布在长时段里,无法用一句话摘要充分覆盖。
- 部署环境允许在推理阶段做额外自监督更新,也就是有一定算力余量。
不适合的场景同样明显:
- 如果单帧问答完全够用,不需要跨时间关联,滑动窗口仍然是成本最低的方案。
- 如果任务要求精确到秒级的事件回溯,本身更适合事件检测加向量索引,不要把所有责任都压给记忆模块。
- 如果推理硬件的时延余量很小,TTT 单步更新可能反而成为瓶颈。
从工程经验看,任何带“测试时更新”的方案,都要额外评估稳定性和安全性。模型在推理时还在更新,意味着它可能因为某一段异常输入,把记忆状态更新到错误方向。如何限制更新幅度、如何回滚异常状态、如何防止输入中对抗性帧污染记忆,这些都是走向生产环境前必须想清楚的事。
结尾:真正值得关注的不是“看得更快”,而是“记得的方式”
回到开头那个问题。StreamTTT 这类方向,最吸引我的不是它让 Streaming VLM 处理某段视频的跑分提高,而是它试图重新定义“长期记忆”的形态。
在主流 Transformer 范式里,记忆几乎等价于“把旧 token 留在上下文中”。这个定义方便注意力机制去查,但它忽略了记忆是一个在线过程:你每次看到新东西,对过去的理解都可能发生改变。真正的记忆不只是存储,而是持续的更新。
如果沿着 TTT 这条路继续走,未来 Streaming VLM 的架构可能会发生一个很有意思的转变:模型在实时感知的同时,本身就在被视频流“训练”。它看过的每一段视频都在微调那个负责记忆的内部状态。实时感知和长期记忆不再是两套分开的资源,而是同一个测试时学习循环里互为前提的两个环节。
如果你想自己做点实验,我的建议是从小规模闭环开始。先做一个 TTT 记忆层,接到一个现有 VLM 的视觉 token 后面,构造一条 5 分钟以上的合成视频流,要求模型回答跨越不同时间点的问题。先跑通,再观察哪些问题类型被它解决,哪些问题类型依然无解。这样,你对“把测试时训练用在流式 VLM 身上”这件事的价值和代价,会有远比今天更具体的体感。