StreamTTT:用测试时训练同时解决流式视觉的实时感知与长期记忆
流式视觉语言模型Streaming VLMs的难点不在模型本身有多强而在于它同时被两个目标拉扯每一帧画面都要实时感知整段视频的历史又必须被长期记住。标题中的 StreamTTT 直接点出了这套方案的解题工具——TTTTest-Time Training——让模型在推理时继续学习把历史信息压缩成一组合持续更新的参数而不是无限增长的 token 缓存。这类模型面向摄像头视频流、屏幕录制、实时监控、具身智能交互等场景。模型需要边看边理解既要回答“现在画面上正在发生什么”也要回答“当前事件和十分钟前的某件事有什么关系”。前一个问题考验感知的延迟后一个问题考验记忆的容量。传统离线视频理解可以先编码完整段视频再回答问题而流式模型的输入是持续到达的帧序列模型必须在帧到达后尽快产出结果同时把之前的上下文真正保存下来。正是这两个互相约束的目标构成了理解 StreamTTT 的背景。下面的分析按技术链条展开先说明流式视频里“实时感知”和“长期记忆”为什么冲突再讲清 TTT 层的原理随后从工程视角重建 StreamTTT 可能的模块结构与读写作流程接着讨论训练目标、推理成本和评估方法最后给出典型踩坑点与可执行的实验清单。1. 实时感知与长期记忆为什么在流式视频中天然冲突1.1 流式视觉语言模型与传统视频模型的任务边界不同传统视频问答任务通常给一段完整视频模型可以反复采样帧、编码、检索再生成答案。视频被当成一个静态文件回答质量只取决于模型能不能从全部帧里找到线索。流式场景则完全不同视频帧按时间顺序持续到达模型在每个时间点只能访问当前帧以及过去的信息不能“偷看”未来。这个约束改变了问题结构。一个 30 分钟的视频流可以包含大量场景片段用户可能在第 5 分钟问“现在门口是谁”也可能在第 25 分钟问“刚才那个人第一次出现时拿着什么”。后一类问题要求模型具备真正的长程记忆能力而前一类问题要求模型不能在历史上花费过多计算否则当前帧的感知就会延迟。流式视觉语言模型需要同时维护两条时间通路当前感知通路对最近一小段帧做快速编码支持“现在正在发生什么”类问题。历史记忆通路把更早的信息压缩成紧凑状态支持“以前是否出现过、顺序如何、前后关联如何”类问题。如果把这两条通路混在一起处理就会出现一个两难为了保证实时性每步计算必须是有界的为了保证记忆完整模型又不能主动丢弃早期帧里的细节。1.2 视觉 token 数量让“保留一切”变得不现实视觉语言模型把图像切成 patch再经过视觉编码器变成视觉 token。以常见的 ViT-L 风格编码器为例一张 336×336 的图大约会产生几百个视觉 token如果语言模型直接处理这些 token 还要再过投影层和 QK 注意力。单帧成本尚可接受但视频流中的帧数会持续增长。假设按每秒 1 帧采样30 分钟视频共 1800 帧每帧 576 个视觉 token总量约 103 万个 token。任意一层自注意力若与全部历史 token 交互计算量会随视频长度线性甚至平方增长。结果就是模型处理越久单帧延迟越高感知能力越差。所以流式视频模型只能选择“有损压缩历史”。压缩方式大体有四类滑动窗口只保留最近 N 帧的 token窗口外信息全部丢弃。token 压缩用可学习的 query 把每段视频压缩成少量 token。文本摘要先把视觉内容转成文本描述再作为历史上下文输入语言模型。循环状态用一个固定大小的隐藏状态承载全部历史。前两类有明确的窗口或压缩瓶颈第三类依赖中间文本质量第四类虽然理论上成本有界但普通 RNN 的固定状态向量表达能力有限长视频中容易出现信息遗忘和梯度饱和。StreamTTT 选择的是围绕第四类方向做升级用 TTT 训练出的“模型参数”替代“固定向量”作为记忆载体。1.3 标题中的 Reconcile 意味着架构必须做信息分流“调和”不是把当前帧特征和历史特征简单拼接。它暗示骨架中存在两条职责不同的路径。实时感知路径要保证每一帧的低延迟编码与答题长期记忆路径要负责把跨度较大的视觉事件写入可读状态。两条路径需要共享视觉编码器但在 token 数量、更新频率、计算预算上有明显差异。理解这一点很重要。后文所有架构讨论都会围绕“什么时候写记忆、什么时候读记忆、读到什么粒度”展开这正是 StreamTTT 试图回答的核心问题。2. 从 RNN 到 TTT把隐藏状态从固定向量升级为可学习模型2.1 序列记忆的三代技术路线第一代是 Transformer 的原生路线把过去的 token 全部缓存成 KV Cache计算时通过注意力直接检索。优点是信息几乎无损缺点是缓存随序列线性增长长视频场景不可持续。第二代是 RNN 风格隐藏状态 h_t 是一个固定维度向量每步通过门控或线性变换更新。成本有界但固定向量作为“记忆容器”的表达能力有限。视频中一个复杂情节可能有多个实体、多条线索、多种时间关系单向量很难完整编码。第三代就是 TTT 的思路隐藏状态不再是一个向量而是一个“模型”。更准确地说状态是一组权重 W_t。历史信息被压缩进这组权重中当新数据到来时模型在测试阶段用梯度下降继续更新这组权重。这样记忆容器本身具备表达复杂结构的能力更新过程还能随数据分布自适应地调整。2.2 TTT 的核心更新逻辑TTT 的名字容易让人误解为“额外做一次完整训练”。实际上它处理的是序列记忆问题当前隐藏状态 W_t 是记忆主体当输入 x_t 到达时先基于自监督目标计算损失再对 W 做一步或多步梯度下降然后从更新后的状态读取输出。简化后的计算过程可以写成# 示意TTT 的状态更新与读取 # W 不是普通隐藏向量而是一个小型可学习模型例如线性层或 MLP loss inner_loss(W, segment_features) # 自监督目标不需要标注 W W - lr * grad(loss, W) # 测试阶段用梯度下降更新状态 state_readout W(query_features) # 读取记忆供语言模型使用其中inner_loss通常是重构或预测类目标例如给定当前视频片段让 W 能够重构片段中的视觉 token或预测下一小段的关键内容。由于更新过程不需要下游任务标签它可以稳定地在测试阶段执行这也是“Test-Time Training”名字的由来。需要注意TTT 层和普通的测试时自适应不一样。测试时自适应通常改变模型权重去适配新领域TTT 层里的 W 本身就是隐藏状态它的更新发生在模型内部并且会在每个序列位置持续发生。用权重当记忆本质上是让记忆具备条件化的读写能力历史信息不是被“复制”进固定向量而是被“学”进一组参数。2.3 为什么 TTT 状态更适合长视频把“记忆”从向量换成模型带来的优势有三个第一表达能力强。一个线性层或小型 MLP 能编码的模式数量远多于一个固定向量。视频中“人 A 在门口出现两次”“红色背包在第三分钟被带走”这类事件可以被参数化的函数关系表达出来。第二更新过程与数据分布相关。普通 RNN 用固定更新公式处理所有输入TTT 用梯度下降处理意味着模型会关注当前片段中真正需要被记住的结构而不是平均地吸收所有 token。第三读取可以带条件。读取记忆时可以把查询特征输入到 W 中得到针对当前问题的记忆向量。这种“条件化读取”比单纯拼接历史状态更能定位到相关细节也容易被语言模型直接使用。3. 一个可理解的 StreamTTT 架构设想需要说明的是这里能依据的原始材料只有论文标题和方向关键词并不包含论文内部的模块级细节。因此下面给出的模块划分不是复述 StreamTTT 的官方实现而是用工程视角还原“实时感知与长期记忆如何共存”的一般结构帮助读者判断论文设计时可能遇到的关键选择点。3.1 感知路径用足够低的延迟处理当前事件无论记忆方案多先进模型首先得看清当前帧。感知路径通常包含以下环节视觉基础编码每帧经过图像编码器得到 patch 特征。时空降采样相邻帧内容高度重复没必要每帧保留全部 patch。可以通过帧采样、空间池化、token 选择把输入压到几十到几百个 token。当前事件解码将降采样后的特征映射为“当前画面概要”或即时响应特征。感知路径的服务对象是“现在”类问题延迟要求高因此侧重视觉编码和轻量投影不应直接让当前帧和几百个历史帧做全量 attention。最直接的实现是保留一个最近片段窗口例如最近 1 到 3 秒的帧窗口内信息用于回答即时问题。3.2 记忆路径用 TTT 层维护长程上下文长期记忆路径要处理的是持续时间很长的历史。如果感知路径保留的是“最近几秒”记忆路径则负责把“最近几秒之前”的重要信息压缩进 TTT 状态。模型可以在每个视频片段结束时对 TTT 状态做一次更新。片段可以用固定秒数切分例如每 2 秒或每 5 秒一个单元也可以按场景边界切分。片段内所有视觉 token 可以先被 token reducer 压缩成少量上下文向量再用这些向量计算自监督损失更新记忆模型 W。核心原则是更新频率不能太高。逐帧更新的 TTT 层等于每一步都在做梯度下降计算开销会让帧率明显下降。逐 patch 更新更不可取。更合理的做法是把更新粒度放在片段或场景级别。3.3 读写解耦什么信息写进去什么信息读出来记忆系统设计最关键的是读写解耦。流式模型不知道未来会问什么问题所以写入只能依赖当前片段内容本身而读取发生在用户提问时带上了明确的查询条件。写入阶段模型需要判断当前片段中哪些信息在未来有被查询的可能。常见启发式包括当前片段中有没有新的实体、人物、物体出现。当前事件与历史状态是否发生明显变化。某个物体是否在长时间未出现后重新出现。这类判断可以由视觉编码器输出的差异特征完成也可以由可学习的门控网络实现。为了减少状态被无意义刷新写入前最好对低价值帧做抑制。读取阶段模型把用户问题对应的文本 token 和当前感知特征送入记忆模型 W得到记忆增强表示。该表示可以再和当前感知特征一起进入语言模型解码生成最终回答。3.4 一个 StreamTTT 风格的推理流程示意下面伪代码展示的是“每次到达一个片段时如何完成写读合作”的逻辑代码只用于说明顺序不代表任何官方实现# 伪代码StreamTTT 风格的流式推理主体 # memory_model 是 TTT 状态内部维护一个小型可学习模型 W def process_segment(segment, memory_model, language_model): # 1. 视觉基础编码segment 内若干帧 - [B, F, P, D] frame_feats visual_encoder(segment.frames) # 2. 感知路径压缩为当前事件特征保证实时感知 compact token_reducer(frame_feats) z_now perception_adapter(compact) # 当前画面的即时表示 # 3. 记忆写入每个 segment 做一次 TTT 更新 memory_model.update(compact) # 内部执行自监督梯度下降 # 4. 交互回答先读记忆再和当前感知特征一起送语言模型 if user_query is not None: query_emb text_encoder(user_query) z_mem memory_model.read(query_emb) # 条件化读取长期记忆 response language_model(z_now, z_mem, recent_context) return response return None这个流程的关键是感知路径和记忆路径都依赖视觉编码器输出但后续处理完全分离。感知输出是短窗口内的即时特征记忆输出是经过 TTT 状态条件化后的长程特征。语言模型解码时同时看到两种信息才有能力回答“当前状态和历史状态结合后才能确定”的问题。4. 训练目标、超参与推理成本需要一起设计4.1 联合训练目标的大致构成StreamTTT 这样的流式多模态模型不会从随机参数开始训练。实际路线通常是先加载预训练视觉编码器和语言模型再逐步接入流式结构。训练目标需要同时照顾三件事视觉语言对齐让视觉 token 经过投影后能被语言模型理解。任务指令遵循让模型能根据用户问题生成自然语言回答。TTT 记忆状态的质量让 W 在测试阶段自监督更新时保持稳定和有效。联合损失可抽象为L_total alpha * L_language_model beta * L_ttt gamma * L_alignment其中L_ttt是 TTT 层内部的自监督损失例如用当前片段的上下文预测被随机屏蔽的视觉 token或者预测当前片段运动趋势。L_language_model是问答任务的标准交叉熵。两个损失的权重需要实验调整如果L_ttt权重太高模型会过度优化“重构当前片段”而忽略下游任务需要的高层语义如果权重太低TTT 状态在测试阶段可能学不到有效记忆。4.2 关键超参数及调节影响训练和推理过程中与 TTT 状态直接相关的超参比普通注意力模型多。实际项目中通常需要从以下参数入手参数作用调大影响调小影响建议实验方向TTT 更新次数每个片段对 W 做几步梯度下降记忆拟合更充分但延迟升高延迟低但可能更新不足从 1 到 4 次开始扫描TTT 学习率控制新片段对旧状态的改写强度近期信息权重高旧记忆快速被覆盖历史稳定保存但新信息写入慢与更新次数联合调片段长度决定一次状态更新覆盖多长视频单次更新更稳健但响应粒度变粗粒度细但更新频繁结合目标场景帧率选择记忆模型容量决定 W 表达能力上限记忆语义更丰富显存和耗时上升更轻量但可能难以承载复杂场景先固定与特征维度同量级自监督损失权重平衡 TTT 更新与下游任务记忆更新更稳定可能损失任务效果任务更直接但状态质量下降用小验证集控制这些参数的共同点是互相耦合。调大学习率的同时减少更新次数可能和调小学习率同时增加更新次数得到相似效果但训练稳定性和显存特征完全不同。记录每次实验的延迟、显存和状态稳定性比只盯着准确率更有价值。4.3 推理阶段的成本构成流式推理的延迟主要由三部分构成单帧延迟 视觉编码 token 降维 单帧轻量处理 片段延迟 TTT 状态更新 必要的历史读取 回答延迟 语言模型解码 记忆读取 当前特征融合视觉编码通常是最大开销。如果编码器非常重即使记忆方案再快实时感知也无法达标。可以考虑把视觉编码器固定或量化在低分辨率输入上完成 token 提取。TTT 状态更新只发生在片段边界不应影响每一帧的响应。回答延迟则要控制在生成首 token 的耗时范围内。另一个需要考虑的问题是显存。TTT 状态本质上是一个参数组需要长期驻留在显存中。模型并行或流水线切分时需要把该参数组和视觉编码器放在同一设备或通过高效通信连接否则状态读写会成为瓶颈。5. 验证一项“感知加记忆”方案要从准确率、延迟和记忆稳定性三个维度衡量5.1 评测任务必须覆盖两种问题类型只拿一个长视频 QA 基准不够因为很多基准问题只看局部内容就能回答。适合的评测应该把问题拆成两层实时感知层考查模型对当前帧的理解能力例如“画面中现在有几个人”“这个人正在做什么动作”“最近一秒是否发生异常”。长程记忆层考查模型是否还记得很久以前的信息例如“十分钟前那个穿红色外套的人还在吗”“第一次出现这个物体时它放在哪里”“刚才发生的事与开头的情节有什么关联”。长程记忆问题设计时可以加入多个干扰项。比如在视频前段出现目标物体中段大量出现相似度很高的干扰物体后段再次询问目标物体。这类问题能检验记忆写入时是否做了有效筛选以及读取时是否能抵抗干扰。常用的长视频理解类任务体系可以借助 EgoSchema、VideoMME、NextQA 等公开基准但使用时需要额外改造为“前缀可见”的流式协议避免模型读到未来帧。如果可用的原论文评测细节有限做复现实验时建议先构造合成视频保证问题需要真正跨越长时间间隔才能回答。5.2 不能只报告准确率流式模型的“实时”和“记忆”两个目标互相制约只用最终准确率会掩盖很多问题。一个模型可以离线缓存完整视频后慢慢答题取得高准确率但完全不具备实时感知能力。因此至少需要报告以下四类信息评测维度需要记录的数据说明感知能力即时问答准确率、单帧响应延迟验证帧到达后的快速判断能力记忆能力长程问答准确率、相隔时间与准确率曲线验证跨时间信息保持能力系统开销每片段更新耗时、峰值显存、状态大小验证是否适合真实流式部署稳定性连续处理 10 分钟、1 小时后状态变化验证长时间运行后是否发生语义漂移其中“相隔时间与准确率曲线”很有价值。把问题和它依赖的证据之间的时间距离拉长例如 1 分钟、5 分钟、20 分钟记录准确率下降曲线。如果方案真的具备长期记忆曲线应该下降缓慢如果主要靠局部窗口曲线会在窗口边界出现明显下跌。5.3 消融实验要回答“记忆升级到底带来多少收益”围绕 StreamTTT 的核心贡献消融实验至少应该包含以下对比把 TTT 状态替换成普通 RNN 的固定隐藏状态保持其他结构不变。把 TTT 状态替换成可学习的固定长度记忆 token比较参数化记忆和向量记忆的差距。去掉感知路径仅保留历史记忆状态观察即时问答的下降幅度。调整记忆更新频率和迭代次数绘制延迟与准确率之间的帕累托曲线。这些对比能回答最根本的问题额外引入的 TTT 计算到底换来了多少记忆能力提升以及提升是在什么延迟代价下获得的。6. 实现这类方案时最常见的五个坑6.1 把 TTT 更新放在“每一帧”甚至“每个 patch”上现象是视频一进入长片段延迟快速上升帧率下降明显。原因在于每个视觉 patch 都被当成了 RNN 输入而 patch 数量是帧数的几百倍。正确的处理是把一个片段内的视觉信息先压缩成少量上下文向量再在片段边界更新一次状态。流式场景要保证每帧计算量基本恒定不能随片段长度线性增长。6.2 训练和测试时 TTT 更新目标不一致训练时如果只用语言模型损失带动状态更新测试时却用自监督损失更新状态那么测试阶段的状态行为训练阶段从未见过效果不会好。反之如果训练时使用了“未来帧参与当前状态更新”这样的非因果操作测试时也会出问题。正确做法是训练和测试阶段保持完全一致的因果更新顺序并在评测前专门检查所有位置的输入可见性。6.3 对状态更新做反向传播时忽略计算图开销训练阶段状态更新涉及对 W 的梯度下降而外层语言模型损失还要对更新过程再求一次梯度。这意味着如果一次前向中做了多次 TTT 更新反向传播就要穿过这些更新步。这是可行的但显存和耗时都会显著增加。常见缓解方式是截断反向传播只对最后一步或最近几步更新做梯度回传或者把内层更新的梯度看成常数。实际工程中最好先在小规模数据上验证显存峰值再决定截断窗口。6.4 评测时用了整段视频的全局信息“先看完整个视频再编码全部状态最后统一回答”的评测方式不符合流式假设。用户是在视频播放到某个时间点时提问模型不能知道之后的帧。评测规范必须明确每个问题的回答时间点是什么模型只允许访问该时间点之前的状态。否则长程记忆准确率会被“未来信息偷看”污染。6.5 忽略了视频帧的强冗余导致状态崩坏真实视频中相邻帧高度相似。如果每个片段都让 TTT 状态做大幅更新重复背景会反复覆盖重要事件模型可能陷入“最近看到的重复内容”而遗忘早前事件。写入前需要做差异检测或显著性采样让低信息量的片段只做轻量更新重要事件片段才做重点更新。这个机制如果缺失状态会变得“看似在更新实际在抖动”。7. 动手复现与工程落地建议7.1 从论文到复现的学习路径如果读者想从零掌握这个方向建议按下面顺序推进而不是直接照搬一个大型 VLM 微调脚本先精读 TTT 原论文重点理解“用权重当隐藏状态”和普通 RNN 的区别。阅读视频领域的 TTT 扩展工作弄清逐帧 token 和片段级 token 的处理差异。用现成视觉语言模型搭建一个不带记忆的流式基线滑动窗口加最近几帧 token。在该基线上加入固定向量 RNN 状态观察长程问答的收益与损失。再把固定向量替换成 TTT
上一篇/下一篇内容由系统自动关联
返回资讯列表 →