FlowCache: Flow Caching for Autoregressive Video Generation
Authors: Yuexiao Ma, Xuzhe Zheng, Jing Xu, Xiwei Xu, Feng Ling, Xiawu Zheng, Huafeng Kuang, Huixia Li, Xing Wang, Xuefeng Xiao, Fei Chao, Rongrong Ji Affiliations: 厦门大学, ByteDance arXiv: 2602.10825 Venue: ICLR 2026
1. Motivation (研究动机)
自回归视频生成模型(如 MAGI-1, SkyReels-V2)通过将视频分割为多个 chunk 依次去噪来生成超长视频,但推理速度极慢。例如在 A800 GPU 上,MAGI-1-4.5B-distill 生成 720x720 分辨率的 10 秒视频需要约 50 分钟,KV cache 占用约 32GB 显存。
现有 caching 加速方法(如 TeaCache)存在一个根本性问题:它们假设所有 chunk 在同一 timestep 具有相同的去噪状态,因此对所有 chunk 施加统一的缓存策略。但在自回归模型中,不同 chunk 处于不同的去噪阶段(有的接近纯噪声,有的接近干净视频),这种统一策略会导致:
- 质量下降严重: TeaCache-fast 在 MAGI-1 上 VBench 从 77.06% 暴跌到 70.11%
- 加速比受限: 无法充分利用不同 chunk 间的异质性来获取更大加速
- KV cache 膨胀: 随着生成的 chunk 增多,KV cache 线性增长,显存成为瓶颈
2. Idea (核心思想)
核心洞察:每个 video chunk 应该维护独立的缓存策略,而非统一对待所有 chunk。
理论基础(Theorem 1):在 flow matching 框架下,relative L1 distance 随去噪过程单调递增。这意味着:
- 接近干净视频的 chunk:相邻 timestep 间变化大,不适合缓存
- 接近纯噪声的 chunk:相邻 timestep 间变化小,适合缓存
因此 FlowCache 提出两个关键组件:
- Chunkwise Adaptive Caching: 每个 chunk 根据自身的 L1 distance 轨迹独立决定是否复用缓存
- Importance-Redundancy KV Cache Compression: 联合考虑重要性和冗余度来压缩 KV cache,保持固定显存占用
3. Method (方法)
3.1 Flow Matching 前置知识
前向扩散过程:
其中 是单调调度函数。反向去噪通过学习的速度场 实现:
自回归视频模型将视频分为 个 chunk,每个 chunk ,第 个 chunk 在 timestep 的去噪:
3.2 Chunkwise Adaptive Caching
Relative L1 Distance(每个 chunk 独立计算):
Theorem 1(单调性定理): 假设 已收敛到最优速度场,调度函数为幂律形式 ,对于 ,有:
即 relative L1 distance 随去噪进程单调递增。
Corollary 1(chunk 间异质性): 若不同 chunk 表示异质内容(),则在同一 timestep :
这证明了需要为每个 chunk 维护独立的缓存策略。
FlowCache 决策函数(核心缓存判定逻辑):
- : 执行前向计算(更新缓存)
- : 复用缓存(跳过计算)
- : 排除的初始 timestep 数(MAGI-1: , SkyReels-V2: )
- : 累积阈值(MAGI-slow: 0.01, MAGI-fast: 0.015, SkyReels-V2-slow: 0.1, SkyReels-V2-fast: 0.15)
# Pseudocode: FlowCache Chunkwise Adaptive Caching
def flowcache_decision(X, t, i, m, epsilon, cache_state):
"""
决定第 i 个 chunk 在 timestep t 是否需要前向计算
返回: True = 复用缓存, False = 前向计算
"""
# 阶段1: 前 m 个 timestep 始终计算(不缓存)
if t > T - m:
cache_state[i] = 0 # f(X, t, i) = 0
return False # 执行前向计算
# 计算当前 chunk 的 relative L1 distance
output_i = model(X_t_i, t, c) # v_theta(X_t^i, t, c)
l1_rel = torch.norm(output_i * delta_t, p=1) / torch.norm(X_t_i, p=1)
# 阶段2: 累积 L1 distance 判断
accumulated = cache_state[i] + l1_rel
if accumulated > epsilon:
# 累积变化量超过阈值 → 执行前向计算,重置累积器
cache_state[i] = 0
return False
else:
# 累积变化量未超过阈值 → 复用缓存
cache_state[i] = accumulated
return True3.3 KV Cache Compression
KV cache 被分为两个区域:
- Compressed clean-chunk region: 大小 ,存储已去噪完成的 chunk 的压缩 KV states
- Current denoising region: 大小 ,存储当前正在去噪的 chunk 的 KV states
当 满时,触发压缩:将 clean-chunk region(未压缩版本)与刚完成去噪的 chunk 合并,然后通过选择准则压缩。
Importance Score(重要性打分):
其中 是当前去噪 token 的 query, 是历史干净 chunk 的 key。通过 MaxPool1D 平滑:
Redundancy Score(冗余度打分):
对 key 做 归一化后计算 cosine 相似度矩阵 ,对角线置零,按 token 维度平均:
Combined Selection Score(联合打分):
每个 attention head 独立选择 top- 个最高分的 token 保留。 为混合系数。
# Pseudocode: KV Cache Compression
def compress_kv_cache(Q_denoise, K_clean, V_clean, B_budget, lambda_coeff):
"""
压缩历史 clean chunk 的 KV cache
Q_denoise: 当前去噪 chunk 的 queries [L_q, H_q, d]
K_clean: 历史 clean chunk 的 keys [L_k, H_k, d]
V_clean: 历史 clean chunk 的 values [L_k, H_k, d]
B_budget: 压缩后保留的 token 数
"""
for h in range(num_heads):
# Step 1: 计算 Importance Score
attn_weights = softmax(Q_denoise[:, h] @ K_clean[:, h].T / sqrt(d)) # [L_q, L_k]
importance = attn_weights.mean(dim=0) # [L_k] — 平均 query 维度
importance = MaxPool1D(importance, kernel=k, padding=k//2) # 平滑
# Step 2: 计算 Redundancy Score
K_norm = F.normalize(K_clean[:, h], dim=-1) # L2 归一化
sim_matrix = K_norm @ K_norm.T # [L_k, L_k] cosine 相似度
sim_matrix.fill_diagonal_(0) # 对角线置零
redundancy = softmax(sim_matrix.mean(dim=0)) # [L_k]
# Step 3: 联合打分并选择 top-B
score = lambda_coeff * importance - (1 - lambda_coeff) * redundancy
selected_indices = score.topk(B_budget).indices
# Step 4: 保留选中的 KV 对
K_compressed[h] = K_clean[selected_indices, h]
V_compressed[h] = V_clean[selected_indices, h]
return K_compressed, V_compressedFigure 3 解读: 本图对比了传统缓存策略(上半部分)与 FlowCache(下半部分)的核心区别。传统方法对所有 chunk 施加统一的计算/复用决策(同一 timestep 所有 chunk 状态相同,白色=计算,斜线=复用)。FlowCache 则允许每个 chunk 独立决策:在同一 timestep,接近纯噪声的 chunk(早期阶段)可以复用缓存,而接近干净视频的 chunk(后期阶段)需要重新计算。右侧展示了 KV Cache 管理机制:维护一个 Reserved KV Cache,通过 Importance Score 和 Redundancy Score 联合选择保留哪些历史 token。
4. Experimental Setup (实验设置)
基础模型
| 模型 | 参数量 | Chunk 配置 | 去噪步数 | 总 Chunk 数 |
|---|---|---|---|---|
| MAGI-1-4.5B-distill | 4.5B | 24 帧/chunk | 64 步 | 10 |
| SkyReels-V2-1.3B-540P | 1.3B | 97 帧/chunk (17帧重叠) | 50 步 | 2 |
- MAGI-1: 使用滑动窗口约束同时去噪的 chunk 数量
- SkyReels-V2: 采用分层结构,chunk 内进一步分为 block,block 间自回归去噪(同一去噪步各 block 去噪程度不同)
评估指标
- 质量: VBench (VBench-long benchmark), LPIPS, SSIM, PSNR
- 效率: PFLOPs, Speedup, Latency (秒)
硬件
- NVIDIA A800 80GB GPU, PyTorch
对比方法
- Vanilla: 原始模型无加速
- TeaCache (Liu et al., 2025a): 基于 timestep embedding 调制的输入差异估计缓存决策,对所有 chunk 使用统一策略
5. Experimental Results (实验结果)
5.1 主实验结果
Figure 1 解读: 三种方法(Vanilla, TeaCache, FlowCache)在 MAGI-1 和 SkyReels-V2 上的视觉质量对比。左侧 MAGI-1 场景为”飞机降落”,TeaCache-fast (1.44x) 出现明显质量退化 (VBench: 70.11%),而 FlowCache-fast (2.38x) 在更高加速比下保持了接近原始模型的质量 (VBench: 77.93%)。右侧 SkyReels-V2 场景为”海岸公路日落行车”,FlowCache-fast 达到 6.7x 加速的同时 VBench 仅从 83.84% 下降到 83.05%。
MAGI-1 定量结果:
| 方法 | PFLOPs | 加速比 | 延迟(秒) | VBench | LPIPS↓ | SSIM↑ | PSNR↑ |
|---|---|---|---|---|---|---|---|
| Vanilla | 306 | 1x | 2873 | 77.06% | - | - | - |
| TeaCache-slow | 294 | 1.12x | 2579 | 77.50% | 0.6211 | 0.2801 | 13.26 |
| TeaCache-fast | 225 | 1.44x | 1998 | 70.11% | 0.8160 | 0.1138 | 8.94 |
| FlowCache-slow | 161 | 1.86x | 1546 | 78.96% | 0.3160 | 0.6497 | 22.34 |
| FlowCache-fast | 140 | 2.38x | 1209 | 77.93% | 0.4311 | 0.5140 | 19.27 |
SkyReels-V2 定量结果:
| 方法 | PFLOPs | 加速比 | 延迟(秒) | VBench | LPIPS↓ | SSIM↑ | PSNR↑ |
|---|---|---|---|---|---|---|---|
| Vanilla | 113 | 1x | 1540 | 83.84% | - | - | - |
| TeaCache-slow | 58 | 1.89x | 814 | 82.67% | 0.1472 | 0.7501 | 21.96 |
| TeaCache-fast | 49 | 2.2x | 686 | 80.06% | 0.3063 | 0.6121 | 18.39 |
| FlowCache-slow | 36 | 5.88x | 262 | 83.12% | 0.1225 | 0.789 | 23.74 |
| FlowCache-fast | 28 | 6.7x | 230 | 83.05% | 0.1467 | 0.7635 | 22.95 |
关键发现:
- FlowCache 在 MAGI-1 上达到 2.38x 加速,VBench 反而比 Vanilla 提高 0.87%
- FlowCache 在 SkyReels-V2 上达到 6.7x 加速,VBench 仅下降 0.79%
- TeaCache-fast 在 MAGI-1 上仅 1.44x 加速就导致 VBench 暴跌近 7 个百分点
- SkyReels-V2 上加速比优势更显著(6.7x vs 2.2x),因为其 block denoising 机制使 chunk 间异质性更大
5.2 Ablation Study
Figure 2 解读: 本图展示了 MAGI-1(左)和 SkyReels-V2(右)中不同 chunk 在去噪过程中的 relative L1 distance 变化曲线。横轴为去噪进度(%),纵轴为 relative L1 distance。关键观察:(1) 所有曲线单调递增,验证了 Theorem 1;(2) 在同一 timestep(如 Step 62 处的绿色标注),不同 chunk 的 L1 distance 存在显著差异(“Similarity Difference”),这证明了 chunkwise 策略的必要性;(3) 整体 L1 distance 值较高,说明模型输入输出始终保持高相似性,存在大量缓存空间。
组件消融(Fast 配置):
| 模型 | 复用策略 | KV 压缩 | VBench | LPIPS↓ | SSIM↑ | PSNR↑ |
|---|---|---|---|---|---|---|
| MAGI-1 | - | - | 77.06% | - | - | - |
| MAGI-1 | TeaCache | - | 70.11% | 0.8160 | 0.1138 | 8.94 |
| MAGI-1 | ChunkWise | - | 77.66% | 0.4208 | 0.5226 | 19.89 |
| MAGI-1 | ChunkWise | Enabled | 77.93% | 0.4311 | 0.5140 | 19.27 |
| SkyReels-V2 | - | - | 83.34% | - | - | - |
| SkyReels-V2 | TeaCache | - | 80.06% | 0.3063 | 0.6121 | 18.39 |
| SkyReels-V2 | ChunkWise | - | 83.12% | 0.1225 | 0.789 | 23.74 |
| SkyReels-V2 | ChunkWise | Enabled | 83.01% | 0.1565 | 0.7425 | 22.61 |
消融结论:
- ChunkWise vs TeaCache: 仅替换复用策略,MAGI-1 VBench 从 70.11% 恢复到 77.66%(+7.55%),证明 chunkwise 策略是核心贡献
- KV 压缩的影响: 加入 KV 压缩后质量几乎无损(MAGI-1: 77.66% → 77.93%,SkyReels-V2: 83.12% → 83.01%),但显著降低了显存占用
5.3 更多定性结果
Figure 4 解读: MAGI-1 模型上的更多定性对比。展示了多个不同 prompt 下 Vanilla、TeaCache、FlowCache 三种方法生成的视频帧。FlowCache 在保持 2.38x 加速的同时,视觉质量与 Vanilla 基本一致,而 TeaCache 在多个场景中出现明显的画质退化和伪影。
Figure 5 解读: SkyReels-V2 模型上的定性对比。在 6.7x 加速比下,FlowCache 生成的视频帧保持了良好的细节和时间一致性,而 TeaCache 在 2.2x 加速时已出现较大质量损失。
Source Code Mapping
| 论文组件 | 代码位置 | 说明 |
|---|---|---|
| 整体框架 (MAGI-1) | FlowCache4MAGI-1/ | MAGI-1-4.5B-distill 的加速实现 |
| 整体框架 (SkyReels-V2) | FlowCache4SkyReels-V2/ | SkyReels-V2-1.3B 的加速实现 |
| MAGI-1 运行脚本 | FlowCache4MAGI-1/scripts/single_run/flowcache_t2v.sh | 文生视频推理入口 |
| SkyReels-V2 快速模式 | FlowCache4SkyReels-V2/run_flowcache_fast.sh | Fast 配置运行脚本 |
| Chunkwise Caching 决策 | 模型推理循环中的 L1_rel 计算与 f(X,t,i) 判定 | 公式 (5)(8) 的实现 |
| KV Cache Compression | Importance + Redundancy 打分与 top-B 选择 | 公式 (9)-(12) 的实现 |