论文解读与源码复现|Go-with-the-Flow:用实时 warp 噪声把运动控制"写进"视频扩散模型的潜空间(CVPR 2025)
论文首页题目与摘要截图
一、前言
视频扩散模型的运动可控性一直是个尴尬的话题:现有方法要么大改基座架构(如 guidance attention),难以兼容现代全注意力/时空 token 架构;要么依赖难以获取的精细运动信号(相机位姿、逐帧轨迹);要么为了控得死而牺牲时空画质。Netflix Eyeline Studios 的这篇 CVPR 2025 Oral 给出了一个极简答案:只改数据,不改模型。
核心观察是:视频扩散的初始噪声通常是帧间独立的高斯采样,也就是"时间上完全无序"。既然运动本质是帧间的对应关系,那么只要把噪声也按运动场(光流)warp 起来,让噪声在时间上相关,运动信息就被编码进了潜空间。作者据此提出一个实时的噪声 warp 算法,用它替代普通高斯噪声去微调 CogVideoX(T2V 与 I2V),推理时只需用 warp 噪声初始化扩散过程——内存与耗时与基座模型完全一致。算法在 $1024\times1024$ 上单帧仅2.14 ms,比前作 HIWYN 快26 倍,同时保持空间 i.i.d. 高斯性(Moran's I = 0.00014,p = 0.84)。
二、方法解析
2.1 从"有序噪声"出发。论文引言借 Escher 的话点题:"我们热爱混沌,因为热爱从混沌中产生秩序。"作者主动把部分秩序注入潜空间采样:从一张 2D 高斯噪声切片出发,按训练视频提取的光流场逐帧 warp,得到时间相关但空间仍为高斯的噪声序列。
图:光流提取、实时噪声 warp、扩散模型微调/推理三部分;微调用原始字幕,推理时把参考运动适配到不同 prompt 或首帧
2.2 实时噪声 warp 算法。HIWYN 需要把每个像素从首帧沿链条 warp,代价随帧数平方增长,且要做多边形栅格化与上采样。本文算法逐帧迭代,只保存上一帧噪声 $q\in\mathbb{R}^{D}$($H\times W\times C$)与逐像素"噪声密度" $p\in\mathbb{R}^{D}$,结合前向/后向光流 $f, f': D\to\mathbb{N}^2$ 计算下一帧 $q', p'$。两种动力学被统一在一个二部图 $G$ 中:膨胀(一个噪声像素映射到下一帧多个像素)与收缩(把噪声像素当粒子沿 $f$ 运动,留下的空隙用后向流 $f'$ 回拉填补),并按密度加权聚合以保持分布正确;两者并行计算以避免互相关,保证输出严格高斯。
命题 1(高斯白噪声保持):若上一帧噪声 $q$ 的像素为 i.i.d. 标准高斯,则输出的 $q'$ 亦为 i.i.d. 标准高斯。命题 2(时间复杂度):单帧复杂度为 $O(D)$;因为收缩时每个旧像素只映射到一个新像素、膨胀时每个新像素只对应一个旧像素,边数 $E \le 2D$。
2.3 无训练的图像扩散应用。对输入视频用 RAFT 提取光流,按算法生成逐帧噪声,替代原本独立采样的高斯噪声,即可让 DeepFloyd IF(超分)、DifFRelight(重打光)等逐帧图像扩散模型产出时序一致的视频编辑,无需任何训练。
2.4 用 warp 噪声微调视频扩散。把 CogVideoX 当黑盒,训练目标与原始微调完全一致(加噪样本与去噪样本的 MSE),唯一差别是用 warp 噪声代替普通高斯噪声。作者还引入噪声退化(noise degradation):对干净的 warp 噪声 $Q$ 以随机等级 $\gamma\in[0,1]$ 混入无关高斯 $\zeta\sim\mathcal{N}(0,1)$,
$$ Q \leftarrow \frac{(1-\gamma)Q + \gamma\zeta}{\sqrt{(1-\gamma)^2+\gamma^2}}, $$
$\gamma\to1$ 时趋于无关高斯,$\gamma\to0$ 时为干净 warp 噪声;这样推理时可连续调节"跟流有多死"。由于扩散在潜空间进行,光流与噪声在图像空间计算后下采样到潜空间(CogVideoX 为空间 $8\times8$、时间 4 倍降采样):时间轴用最近邻插值、两个空间轴用 mean-pooling,再乘以 8 以保持单位方差。
2.5 推理时的三类运动控制。(i)局部对象运动:用户用多边形 UI 切割、拖拽、旋转、缩放图像区域,生成合成光流(可叠加视差多边形模拟 3D),局部运动通常取 $\gamma\in[0.5,0.7]$;(ii)全局相机运动:复用参考视频的光流 warp 输入噪声;(iii)运动迁移:光流来源不限于 RAFT,还可来自 3D 渲染引擎或深度 warp(如用 DepthPro 估深后粗 warp),迁移时通常取 $\gamma\in[0.2,0.5]$。
三、数据集与实验设置
无训练实验用 DAVIS 的 43 段视频($64\times64$ 下采样后超分到 $256\times256$)与 DifFRelight 的 4 主体 × 4 场景(180°/720° 视角动画、zigzag 相机路径、多点插值路径)。运动控制实验用 DAVIS(43 段)、DL3DV 随机 100 段、WonderJourney 生成的 19 段相机运动视频,并用 VIPSeg 与 40 段用户研究视频做局部运动基准。指标:Gaussianity 用 Moran's I(空间自相关,越接近 0 越好)与 Kolmogorov–Smirnov 检验(正态性);画质用 LPIPS/SSIM/PSNR、FID、FVD;时序一致性用 warping error(相邻帧按光流 warp 后的 MSE);运动可控性用 CoTracker 跟踪框 mIoU 与像素 MSE;文本对齐用 CLIP 相似度;另有 VBench 的时序一致性维度。用户研究 40 名参与者。
四、关键实验结果
表(论文 Table 1):各噪声 warp 方法在 Gaussianity、效率与两类图像扩散应用上的对比
| 方法 | Moran's I ↓ | K-S index ↓ | GPU time @1024² (ms) ↓ | 超分 warping err. ↓ | 重打光 warping err. ↓ |
|---|---|---|---|---|---|
| Fixed / Random | -0.00027 / 0.00019 | 0.089 / 0.075 | < 1 / < 1 | 163.84 / 233.65 | 86.65 / 128.11 |
| Bilinear | 0.30 | 0.34 | 4.41 | 165.90 | 47.53 |
| Bicubic | 0.24 | 0.37 | 4.33 | 167.95 | 43.57 |
| Nearest | 0.26 | 0.17 | 6.82 | 244.72 | 164.42 |
| PYoCo | 0.00023 | 0.13 | 3.54 | 186.63 | 95.24 |
| CaV | -0.00079 | 0.073 | 2.31 | 220.28 | 106.77 |
| HIWYN | 0.0011 | 0.062 | 55.2 | 164.35 | 87.72 |
| InfRes | 0.00036 | 0.055 | 2.61 | 190.82 | 87.97 |
| Ours | 0.00014 | 0.060 | 2.14 | 152.04 | 85.82 |
三类插值 warp(bilinear/bicubic/nearest)Moran's I 高达 0.24–0.30(p = 0.0)、K-S 统计量 0.17–0.37,明确破坏高斯性,画质随之崩塌(SSIM 最低 0.65);本文方法则在保持高斯性的同时把超分任务的时序一致性做到全场最优。
图:局部对象运动控制——用户框选任意数量多边形,沿任意路径缩放/旋转/平移,据此生成 warp 光流
运动迁移的定量对比(DAVIS I2V,$\gamma=0.5$):本文 FID 78.6 / CoTracker mIoU 0.74 / 光流误差 0.053 / FVD 1.21,而 MotionClone 为 99.4 / 0.72 / 0.068 / 1.84;不使用运动条件的原版 CogVideoX-5B 为 76.62 / 0.52 / 0.088 / 1.36——即加运动条件后 FID/FVD 基本不变而运动指标大幅提升。DL3DV 相机迁移上本文 FID 48.4、mIoU 0.83、光流误差 0.046、FVD 0.34,显著优于 MotionClone 的 82.7 / 0.71 / 0.104 / 1.11。用户研究中,cut-and-drag 局部运动控制胜率82%,可旋转相机运动控制胜率90%。
五、机制解释与讨论
- 具体发现一:去掉时间高斯性并不损害微调——模型能快速适应,因为潜空间中的时间结构反而帮助生成学习建立运动对应;同时空间高斯性被严格保持(Moran's I 与 K-S 检验均通过)。→凝练结论:扩散模型对"噪声的时间相关性"远比想象的宽容,这正是"只换噪声即可控运动"成立的前提。
- 具体发现二:把 HIWYN 的链式 warp 改为逐帧迭代 + 膨胀/收缩二部图 + 密度跟踪,复杂度从帧数的平方降为线性 $O(D)$,实测快 26 倍,且 warp 误差反而最低。→凝练结论:运动条件要能落地, warp 算法必须比实时更快;否则大规模视频微调根本不可行。
- 具体发现三:退化等级 $\gamma$ 提供了一个连续的"控制强度→画质"旋钮($\gamma$ 增大则运动更贴流但 FVD 变差),且 $\gamma\approx0.5$ 在多数任务上是好的默认;数据量消融显示用 33% / 12.5% 数据训练都会变差,换更弱的 CogVideoX-2B 基座也更差。→凝练结论:该方法的运动控制能力来自"数据 + 微调"而非推理技巧,基座规模与数据规模都直接决定上限。
六、局限与工程启示
局限与工程注意:README 的 TODO 显示细粒度微调代码、3D-to-Video 推理代码尚未发布(已发布 cut-and-drag 推理、T2V/I2V 运动迁移、AnimateDiff 模型与 ComfyUI 节点);深度 warp 只给出示例流程。工程启示:(1) 若已有一个视频扩散基座,最小成本的运动可控化路径就是"预处理数据生成 warp 噪声 + 原样微调",推理零额外开销;(2) 噪声密度跟踪 + 膨胀/收缩分解是一个可复用的通用技巧,任何需要"沿场输运高斯随机场"的场景都适用;(3) $\gamma$ 应作为产品化的一级参数暴露给用户;(4) 光流质量直接决定运动保真度,RAFT 之外可换更强的流估计器。
七、源码复现
官方 GitHub:https://github.com/WenzhouDing/Go-with-the-Flow;本地目录:复现代码/499-Go-with-the-Flow/。
真实目录树:
499-Go-with-the-Flow/ ├── README.md / LICENSE / requirements.txt / requirements_local.txt ├── make_warped_noise.py # 视频/URL -> warp 噪声(noises.npy) ├── cut_and_drag_gui.py # 无 GPU 的动画模板 GUI ├── cut_and_drag_inference.py # GPU 上的扩散推理(T2V / I2V / LoRA) └── assets/ # cut_and_drag_example_*.gif、Logo.png核心代码片段(make_warped_noise.py,把视频整理成 CogVideoX 尺寸并生成潜空间 warp 噪声):
FRAME = 2**-1 # 计算光流前先缩放的倍率 FLOW = 2**3 # 光流上采样倍率(更高 = 时序更一致,但更慢更吃显存) LATENT = 8 # 再下采样倍率:CogVideoX 中 8 像素 = 1 个 latent video = rp.resize_list(video, length=49) # CogVideoX 帧数 video = rp.resize_images_to_hold(video, height=480, width=720) video = rp.crop_images(video, height=480, width=720, origin='center') output = nw.get_noise_from_video( video, remove_background=False, visualize=True, save_files=True, noise_channels=16, output_folder=output_folder, resize_frames=FRAME, resize_flow=FLOW, downscale_factor=round(FRAME * FLOW) * LATENT, ) rp.save_image(video[0], rp.path_join(output_folder, 'first_frame.png'))cut_and_drag_inference.py中的基座与 LoRA 组织方式:
pipe_ids = dict(T2V5B="THUDM/CogVideoX-5b", T2V2B="THUDM/CogVideoX-2b", I2V5B="THUDM/CogVideoX-5b-I2V") base_url = "https://huggingface.co/Eyeline-Research/Go-with-the-Flow/resolve/main/" # 例如 T2V5B_blendnorm_i25000_DATASET_nearest_lora_weights.safetensors B, F, C, H, W = 1, 13, 16, 60, 90 # 默认潜空间形状,num_frames = (F-1)*4+1 = 49 PipeClass = CogVideoXImageToVideoPipeline if is_i2v else CogVideoXPipeline pipe = PipeClass.from_pretrained(hub_model_id, torch_dtype=torch.bfloat16, vae=vae, transformer=transformer, text_encoder=text_encoder) pipe.load_lora_weights(lora_path) pipe.enable_sequential_cpu_offload(device=device) # low_vram 模式预期运行路径:
git clone https://github.com/WenzhouDing/Go-with-the-Flow.git && cd Go-with-the-Flow # 1) 本地做动画模板(无需 GPU) pip install -r requirements_local.txt python cut_and_drag_gui.py # 生成 MP4 # 2) 在 GPU 机器上跑扩散 pip install -r requirements.txt python make_warped_noise.py <PATH_TO_VIDEO_OR_URL> --output_folder noise_warp_output_folder python cut_and_drag_inference.py noise_warp_output_folder \ --prompt "A duck splashing" --output_mp4_path "output.mp4" \ --device "cuda" --num_inference_steps 30权重从 HuggingFaceEyeline-Labs/Go-with-the-Flow(README 中亦作Eyeline-Research)下载,包含各 LoRA 微调权重;项目页https://eyeline-research.github.io/Go-with-the-Flow/。社区已有 ComfyUI 实现(kijai/ComfyUI-VideoNoiseWarp)与 AnimateDiff/HunyuanVideo 的移植版本。
⚠️ 复现路径/未运行:以下为源码结构与预期运行路径分析,非实际运行结果。
注意:make_warped_noise.py依赖rp包(会自动装齐其余依赖并下载模型),首次运行较慢;细粒度微调(fine-tuning)代码在 TODO 中尚未勾选发布,因此"训练自己的运动可控基座"这一步需按论文 3.3 节自行组织 CogVideoX 微调流水线。