跳到正文
写作 · Writing
返回

流式推理中的思维链:为什么要边看边想

在 GitHub 上编辑

Read the English version →

流式多模态模型(streaming MLLM)面对的输入是持续到达的视频片段,而不是一次性给完的完整视频。这带来一个直接的矛盾:思维链推理(Chain-of-Thought)需要”想完再说”,而流式场景要求”边看边说”。

一个朴素的基线

最直接的做法是让模型在每个时间步都完整重复一次推理:

p(yt∣x≤t)=∑i<tp(yi∣x≤i)⋅p(yt∣x≤t,y<t)p(y_t \mid x_{\le t}) = \sum_{i < t} p(y_i \mid x_{\le i}) \cdot p(y_t \mid x_{\le t}, y_{<t})

写成伪代码大概是这样:

for frame in video_stream:
    chunks = model.infer(frame)          # 每帧都重新推理
    for chunk in chunks:
        emit(chunk)

问题很明显:第 tt 步重复了前 t−1t-1 步已经做过的推理,计算量随时间线性甚至超线性增长,而且重复的内容会让输出抖动。

三个观察

1. 推理可以增量缓存

KV cache 的复用不只是工程优化,它让”同一段推理只做一次”成为可能。一旦缓存住,第 tt 步只需要计算增量部分:

Δzt=f(xt,zt−1)−f(xt−1,zt−1)\Delta z_t = f(x_t, z_{t-1}) - f(x_{t-1}, z_{t-1})

这里 ztz_t 表示时刻 tt 的推理状态。实践中我们发现,状态的更新量远小于状态本身,这给了我们近似丢弃旧状态的空间。

2. 冗余推理比迟到推理更糟

一个反直觉的现象:如果一段推理在 t1t_1 时刻已经算出来,但模型选择等到 t2>t1t_2 > t_1 才说出口,用户的体感比”晚一点想到”更差。因为在流式交互里,输出节奏本身携带信息。

策略 首字延迟 重复率 体感
全量重算 高 100% 抖动
增量缓存 低 低 平滑
缓存 + 延迟输出 低 低 迟钝

3. 什么时候该”重新想”

不是所有时候都值得增量更新。当输入发生语义跳变时(例如镜头切换),缓存里的推理状态已经不再成立,此时反而应该丢掉缓存重算。

1[resample]=1[d(zt,zt−1)>τ]\mathbb{1}[\text{resample}] = \mathbb{1}\big[d(z_t, z_{t-1}) > \tau\big]

我们的实验里,一个简单但有效的判据是推理状态之间的距离超过阈值就重算。

还没解决的问题

  • 阈值 τ\tau 怎么选?它和任务、视频长度、帧率都有关联,目前只能靠验证集调。
  • 缓存状态的漂移。长时间运行后,累积误差会让状态偏离真实推理,越到后面越难纠正。
  • 评测指标。流式场景下 BLEU / CIDEr 这类静态指标几乎失效,我们需要能同时衡量”及时性”和”内容一致性”的指标。

小结

流式 CoT 的核心矛盾不是”怎么算得更快”,而是怎么让推理过程本身变得可增量、可丢弃、可复用。这比单纯优化吞吐要难,但也更有意思。



上一篇
Chain-of-Thought in Streaming Reasoning: Think While You Look