Long Autoregressive Video Generation

Tips:

  • Forcing 可以理解为“强制引导”,即施加约束。

有几个关键问题:

  • Teacher 和 Student 打分的时候,都是所有 chunk 一起输入并打分。
  • Student 在 Rollout 的时候,有几种方法?
    • 并行,比如 Causvid,是从数据集取得数据加噪后,然后7个chunk并行一次前向,并没有kv cache
    • 串行:逐个 chunk 生成,每个通过 kv cache 看到之前的所有干净 kv。

Causvid:将 DMD 引入Streaming Video

Paper:From Slow Bidirectional to Fast Autoregressive Video Diffusion Models, CVPR 2025

TL; DR:把双向Teacher蒸馏成单向Student

核心工作:

  • 每个 chunk 内保持双向注意力,chunk 之间用因果掩码
  • 先用 ODE 初始化学生,然后进入 DMD 蒸馏
image.png

通过阅读代码,详细的 Pipeline 如下:

  • Stage 1: ODE 初始化。
    • 将 Teacher 权重复制,然后注意力改成块内双向、块间因果。
    • 用教师的 ODE 轨迹蒸馏。7 个 chunk 全部并行一次前向输入 Student(teacher forcing,无 rollout)
    • 每个 chunk 从轨迹中独立采样噪声水平:chunk 内一致、chunk 间不同
    • Student 从该噪声状态一步直接预测 x0,回归到轨迹终点(MSE)
  • Stage 2: Teacher Forcing
    • 取真实视频,然后加噪,不同chunk噪声水平不一样。
    • 然后 7 个 chunk 一起输入 Student,预测 clean video。
    • 7 个 chunk 统一加噪, 然后 fake score(注意是双向) 和 real score 打分。
    • 更新 Student。

Self Forcing:解决训练推理不一致的问题

Paper:Self Forcing: Bridging the Train-Test Gap in Autoregressive Video Diffusion,NIPS 0225

image.png

训练的时候,rollout就用自己输出的

通过阅读代码,详细的 Pipeline 如下:

  • Stage 1: ODE 初始化。
    • 将 Teacher 权重复制,然后注意力改成块内双向、块间因果。
    • 用教师的 ODE 轨迹蒸馏。7 个 chunk 全部并行一次前向输入 Student(teacher forcing,无 rollout)
    • 每个 chunk 从轨迹中独立采样噪声水平:chunk 内一致、chunk 间不同
    • Student 从该噪声状态一步直接预测 x0,回归到轨迹终点(MSE)
  • Stage 2: Self Forcing
    • 采集一个 Prompt
    • Student 自回归的生成 7 个 chunk。
      • 每个 chunk 4 步去噪。
      • 每个 chunk 会 attention 到之前的所有历史kv cache。
      • 当前 chunk 计算完之后,会再进行一次 forward,存放干净的 kv cache。
    • 7 个 chunk 统一加噪, 然后 fake score(注意是双向) 和 real score 打分。
    • 更新 Student。
    • 训练节奏:critic 每步都更新,generator 每 5 步更新一次;200 步后开 EMA;总计 600 iterations

注意这里 Student Rollout 的时候是先预测x0,再加噪去噪:

1
2
3
4
5
6
7
8
9
10
# 推理:pipeline/causal_inference.py:188-221
# 训练:self_forcing_training.py:145-194
noisy_input = 纯噪声
for t in [1000, 750, 500, 250]:
x0_pred = generator(noisy_input, t) # 一步预测 x0
if t != 最后一步:
noisy_input = add_noise(x0_pred, 新噪声, t_next) # ← 关键:从 x0 出发重新加噪
else:
output = x0_pred # 最后一步直接输出
# 然后用 output 以 t=0 再前向一次写干净 KV

Causal Forcing:新增了一个 AR Teacher

Paper:Causal Forcing: Autoregressive Diffusion Distillation Done Right for High-Quality Real-Time Interactive Video Generation,arxiv 2026

做实时交互式视频生成,主流方案是把双向视频扩散模型蒸馏成少步自回归模型,但"看未来"的教师配"只看过去"的学生会留下架构鸿沟,导致 Self Forcing 这类 SOTA 明显不如等价的双向蒸馏。这篇论文指出根因在 ODE 初始化:MSE 回归要求配对数据帧级单射,而双向教师的 PF-ODE 只在视频级单射,学生只能学成条件期望,结果就是模糊。解法很干净——先用 teacher forcing 训一个自回归扩散模型当教师,再用它做 causal ODE 蒸馏,最后接原样 DMD。

总结:在 Self Forcing 的基础上,新增了一个阶段,就是把之前的 Teacher 先微调成一个 AR Teacher。

Causal Forcing++:解决初始化很昂贵的问题

在 Causal Forcing 的基础上进行了优化改进。论文认为 ODE 初始化要离线预生成教师的很多轨迹,很昂贵,于是提出把这个初始化也进行优化。

论文提出了 Causal CD。核心: 既然目标是「一步到位映射到终点」,那我不需要知道终点长什么样,只需要知道「沿轨迹再走一小步,我应该还是去同一个终点」。

左边是 tt 时刻的点,右边是 teacher 走一步之后的点,两者应该映射到同一个终点。于是监督信号从「老师跑 48 步 + 存轨迹」变成「老师在线走 1 步」。

  1. 从真实视频取第 帧及其真实历史帧;
  2. 对第 帧加噪,得到 ;
  3. AR Teacher 基于真实历史,对 做一次 ODE 步,得到 ;
  4. 在线 Student 处理 ,得到终点预测 ;
  5. EMA Student 处理 ,得到终点预测 ;
  6. 计算 ,并乘以时间权重;
  7. 只更新在线 Student,使两个终点预测保持一致;
  8. 用在线 Student 的参数更新 EMA Student。

Rolling Forcing-解决误差积累问题

Paper: Rolling Forcing: Autoregressive Long Video Diffusion in Real Time

Self-Forcing 的问题:块 走完 4 步去噪、写入干净 KV 后就永久定型,块 只能单向依赖它——误差沿链单向累积,长视频越来越漂。

Pipeline:

1
2
3
4
5
6
7
8
窗口 w=0:  [B0(t=1000)]                                ← 只看得到 B0,纯噪声起步
窗口 w=1: [B0(t=800) B1(t=1000)] ← 一次前向同时 refine 两个块
窗口 w=2: [B0(t=600) B1(t=800) B2(t=1000)] ← 阶梯噪声,联合去噪
窗口 w=3: [B0(t=400) B1(t=600) B2(t=800) B3(t=1000)]
窗口 w=4: [B0(t=200) B1(t=400) B2(t=600) B3(t=800) B4(t=1000)]
└─ B0 完成去噪 → 以 t=0 写入干净 KV,退出窗口
窗口 w=5: [B1(t=200) B2(t=400) B3(t=600) B4(t=800) B5(t=1000)]
└─ B1 完成,退出……

每个窗口的操作:

  • 一次前向处理整个窗口:5 个块拼在一起输入,timestep 呈阶梯(shared_timestep,最老块最干净、最新块纯噪声)
  • 输出 5 个块的 x0 预测,各自重新加噪到下一级存回 noisy_cache(no_grad,199-221 行)
  • 只把最老块以 t=0 干净态写入 KV cache(236-246 行,denoised_pred[:, :num_frame_per_block]),它已到最低噪声级,正式完成
  • 窗口右滑一格,新块以纯噪声进入

感觉就像“视野变长了”,有未来的视野,可以根据未来的视野(虽然比较模糊)保持比较好的一致性。

Context Forcing-解决长rollout问题

image.png

Paper:Context Forcing: Consistent Autoregressive Video Generation with Long Context

论文提到,现有流式视频模型存在如下两种范式:

  • Self-Forcing 类:Teacher 和 Student 都很短。
  • LongLive 类:Student 很长,但是 Teacher 看到的信息还是很短。
  • Context Forcing:Teacher 和 Student 都很长。

所以

  • Teacher 用长上下文的老师,在 Wan2.1-1.3B 上用 Stable Video Infinity 方式 LoRA 微调。
  • Student 也有长上下文。Memory 机制如下:
    • Attention Sink
    • Slow Memory:很久以前重要的信息,如果相邻 Token 变化很大,说明发生了状态变化,就存下来。
    • Fast Memory:最近的若干 chunk

训练分成两个 Stage:

  • Stage 1: Self Forcing DMD
  • Stage2: Rollout 长度从21帧变成105帧

One Forcing

解决的核心问题:One-Step 质量一般。

核心是加入了 GAN loss。

完成 pipeline 如下:

每个 step

1
2
3
4
5
6
7
8
9
10
11
student rollout(no_grad)→ generated video
│
├──加噪──► fake score 去噪头 ──► denoising loss(DMD critic 任务)
│
└──加噪──► fake score 的 GAN 头 ──► fake logit ┐
├─► gan_d_loss
真实数据 latent ──加同样噪──► 同一 GAN 头 ──► real logit ┘

denoising_loss + gan_d_loss 一起 backward → 更新 fake score(主干 + 两个头)

⚠️ teacher(real score 14B)在这一步完全不参与

每 5 个 step(generator 步,额外做)

1
2
3
4
5
6
7
8
9
10
student 带梯度 rollout(随机 exit step 反传)→ pred_image
│
├── DMD 路:加噪 ──► teacher(14B, 冻结) → x0_real ← 输出的是 x0 预测,不是 logit!
│ ──► fake score 去噪头 → x0_fake
│ └─► (x0_fake − x0_real)/norm = DMD 伪梯度
│
└── GAN 路:加噪 ──► fake score 的 GAN 头 → fake logit → softplus(−logit) 梯度
(这条路里没有 teacher)

DMD 伪梯度 + GAN 梯度合成 → 一次 backward → 只更新 student

两种损失如下:

1
2
3
4
5
6
# 判别损失(更新 fake score + GAN 头,即"考官")
gan_d_loss = softplus(-noisy_real_logit).mean() # real 的 logit 要推大 → 判真要准
+ softplus( noisy_fake_logit).mean() # fake 的 logit 要压小 → 判假要准

# 生成损失(更新 student,即"考生")
gan_g_loss = softplus(-noisy_fake_logit).mean() * 0.03 # fake 的 logit 要推大 → 骗过考官

其他:论文用 register token 压缩视频的feature:

1
2
3
4
5
6
7
8
9
10
11
fake score 主干第 21 层特征(~30000 个 token)
│
▼ 交叉注意力(GanAttentionBlock)
register #1 作为 Query,特征作为 Key/Value
│ ← register #1 主动"提问":哪些 token 有假货线索?
▼
register #1 聚合成一个 1536 维向量

主干第 29 层特征 ──同理──► register #2

[register#1 ; register#2] ──► MLP ──► 真/假 logit

Long Autoregressive Video Generation
https://d4wnnn.github.io/2026/09/15/Notion/Long Autoregressive Video Generation/
作者
D4wn
发布于
2026年9月15日
许可协议