跳到正文
博客园· 罗西的思考·· 2 小时前AI 评分60

Nano World Models(NanoWM)分析笔记:世界模型与视频生成的区别及实现细节

【世界模型】Nano World Models(NanoWM)分析笔记 - 罗西的思考

AI 导读

罗西的思考发布 Nano World Models(NanoWM)分析笔记,梳理这个基于扩散强迫的极简世界模型代码库。文章区分世界模型与视频生成模型在条件信号、滚动误差累积、潜空间接口和 MPC 闭环上的差异,并逐项讲解 Diffusion Forcing 调度矩阵、x/ε/v 预测目标、五种动作注入机制和三种潜空间编码器。

正文

【世界模型】Nano World Models(NanoWM)分析笔记

0x00 概要

世界模型(ha2018recurrent; dawid2023introduction)已成为空间智能(yang2025cambrian; wang2026vagen)和现实世界决策(richens2025general; guo2025ctrl)的基石——它通过以智能体的历史观测和动作为条件,生成高保真的未来预测。

Nano World Models 是一个极简的、开箱即用的代码库,旨在推进一种审慎且科学的世界模型设计方法。

0x01 出发点

Nano World Model项目的动机很简单:虽然工业级世界模型实现了惊人的视觉效果,但它们所依赖的,本质上只是一小撮简单而成熟的技术:视频扩散(ho2022video; svd)、扩散强迫(chen2024diffusion)、一致性蒸馏(song2023consistency)等。

Nano World Models 作者认为,随着世界模型算法的逐步稳定,研究焦点将从"发明新技术"转向"对更细微科学设计决策发展更深入的理解"——包括架构选择、训练目标,当然还有数据组成和缩放行为。然而,如果不能轻易地对模型进行实验操作,就不可能真正理解其背后的科学。尤其是在当前世界模型研究高度碎片化的格局下,不同的数据集(brohan2022rt; pearce2022counter; zhou2024dino)、训练方案(yang2023diffusion; lipman2024flow; li2025back)、评估协议(vafa2024world; zhang2026worldinworld)和下游任务(alonso2024diffusion; quevedo2026worldgym; guo2025ctrl)分散在大量的独立来源中,使得严谨的科学研究变得极为困难。

Nano World Models 作为在上述碎片化格局中一个可用且极简的、开箱即用的世界模型实现。其代码库围绕扩散强迫(chen2024diffusion)模型进行专门构建。其支持基于 Hydra 的配置系统(Yadan2019Hydra),数据加载、模型设计、训练、评估和下游任务的模块化代码,以及精心整理的文档。具体来说,其支持以下功能:

  • 生成式建模目标。以扩散强迫(chen2024diffusion)为核心,Nano World Models 支持多种生成建模与预测目标。它支持扩散(rombach2022high; peebles2023scalable)和流匹配(lipman2022flow; lipman2024flow),以及 x 和 v 预测目标(li2025back)。
  • 架构规模与设计。Nano World Models 被设计为支持不同规模的架构。遵循图像生成社区的命名约定(ma2024sit; peebles2023scalable),我们包含四种不同规模的变体:NanoWM-S(40M)、NanoWM-B(160M)、NanoWM-L(600M)和 NanoWM-XL(830M)。在动作注入方法上,Nano World Models 支持逐元素加法、AdaLN(huang2017arbitrary)、与时间步融合的 AdaLN、FiLM(perez2018film)和交叉注意力。
  • 环境。Nano World Models 支持从简单仿真环境到游戏模拟和机器人操控的多种环境。对于简单仿真环境,当前支持来自标准机器人基准测试的环境,即 D4RL(fu2020d4rl)和 DeepMind Control Suite(tassa2018deepmind)。这些环境包括迷宫导航(Maze,Wall)、桌面推 T 形块精细操控(PushT)以及使用 XArm 的可变形物体操控(Rope,Granular)。在游戏模拟方面,我们支持知名的 CS:GO 数据集(pearce2022counter);在机器人操控方面,我们支持广泛使用的 RT-1(brohan2022rt)数据集。
  • 日志记录与评估。Nano World Models 同时支持 Tensorboard(abadi2016tensorflow)和 Wandb(wandb)日志系统。日志记录包括基于回调的验证、可靠的逐步检查点保存以及系统利用率信息。评估在固定随机种子下完全可复现。
  • 长程生成。Nano World Models 的能力超越了训练时的上下文长度。借助扩散强迫的自回归能力以及滑动窗口方法,Nano World Models 可以生成在时间上一致的、长度达到训练视野 4 倍的长视频。

0x02 什么是世界模型,世界模型的必要组成部分是什么

2.1 向十二岁的孩子解释

什么是世界模型?

你在打游戏的时候,比如玩《超级马里奥》,你看到前面有个坑——你的大脑会立刻"想象"出:如果我跳过去,就会安全落地;如果我直接走,就会掉下去。你之所以能"想象"出这个结果,是因为你的大脑里已经有一个关于这个世界的"小模型"——你知道重力是怎么回事、知道马里奥能跳多远。

世界模型(World Model)就是教计算机也拥有这种"想象能力"。 你给计算机看很多视频(比如机器人推东西、人玩游戏),计算机就从中学到了"这个世界是怎么运作的"。之后,你问它"如果做这个动作,接下来会发生什么?",它就能在它的"脑海"里想象出结果。

一个世界模型必须包含什么?

就像你需要三样东西才能玩好一个游戏:

  1. 眼睛看画面(编码器)——把"世界长什么样"变成计算机能理解的数据
  2. 大脑想规律(预测模型)——学会"如果做了动作 X,画面会变成 Y"
  3. 嘴巴说结果(解码器)——把脑子里的想法变回你能看懂的视频或图片

缺少任何一个,世界模型都运作不起来。


2.2 向半专业人士解释

什么是世界模型?

世界模型(World Model)是一种通过学习环境交互数据来模拟环境动态的生成式模型。它接受智能体的历史观测序列和动作序列作为输入,学习一个条件概率分布:

p(o_{t+1}, o_{t+2}, ..., o_{t+H} | o_{1:t}, a_{1:t+H-1})

即:给定已观测到的历史帧和待执行的未来动作序列,预测未来的观测序列。世界模型的核心价值在于将隐式的环境规则(物理规律、物体交互、场景演化)编码为可查询的参数化函数——智能体不需要在真实环境中试错,而是在模型的"想象"中推演不同行动的结果。

世界模型的必要组成部分:

从功能架构角度,一个完整的世界模型需要四个核心组件:

组件 功能 类比 NanoWM 中的实现
感知编码器(Perception Encoder) 将高维观测(RGB图像)压缩到紧凑的潜空间 人的视觉皮层 — 把视网膜信号转成"物体"概念 SD-VAE / Web-DINO / V-JEPA 2.1
动力学预测器(Dynamics Predictor) 在潜空间中建模时序状态转移,条件于动作 人的小脑 — 预测"动了之后会怎样" NanoWM (DiT + Diffusion Forcing)
奖励/目标函数(Objective) 定义"好" vs "坏"的判定标准,用于指导规划 人的前额叶 — 判断"那样做好不好" MSE / Cosine 距离 vs 目标潜变量
规划/解码器(Planner / Decoder) 使用预测器搜索最优行动路径,或将潜变量解码回可理解的观测 人的运动皮层 — 把计划转化成实际行动 CEM Planner / VAE Decoder

这四个组件缺一不可:没有编码器,模型处理不了原始像素;没有预测器,模型没有"想象力";没有目标函数,无法判断哪个未来更好;没有规划/解码器,"想象力"无法落地为行动。


2.3 向专业人士解释

2.3.1 什么是世界模型

世界模型(World Model)是将环境交互动力学编码为可微参数化函数的生成式框架。形式化地,给定长度为 T 的历史观测序列 o_{1:T} 和动作序列 a_{1:T},世界模型学习未来观测 o_{T+1:T+H} 的条件分布:

p_θ(o_{T+1:T+H} | o_{1:T}, a_{1:T+H-1})

与传统动力学模型(如 Kalman 滤波器、高斯过程)的区别在于:

  1. 观测空间的高维度 —— 处理 RGB 图像(而非低维状态向量)
  2. 生成式不确定性建模 —— 不输出确定性的 o_{t+1} = f(o_t, a_t),而是建模完整的分布 p(o_{t+1} | ...)
  3. 长程时序依赖 —— 学习帧间的因果结构,而非 Markov 假设下的单步转移

世界模型在决策系统中的角色是可微的、可查询的模拟器——智能体通过"在想象中试错"来替代在真实环境中的昂贵交互。

2.3.2 世界模型分类

从学习范式的角度,现代世界模型可以分为三类:

范式 代表工作 核心思想 目标
重建导向(Reconstruction-based) DreamerV3, IRIS, NanoWM w/ SD-VAE 将观测压缩到可解码的潜空间,预测该空间的动态 像素级保真度 + 规划
表征导向(Representation-based) JEPA, DINO-WM 在语义/几何特征空间预测,不要求可解码 规划导向的抽象表征
像素导向(Pixel-based) Genie, GameNGen 直接在像素空间做预测(扩散/自回归) 极致视觉保真度(代价高)

2.3.3 必要组成部分

世界模型的必要组成部分(系统架构视角):

从第一性原理出发,一个可用于决策的世界模型必须包含以下五个子系统,它们之间存在严格的依赖关系:

1. 观测编码器(Observation Encoder)
enc: O → Z,其中 O 是观测空间(通常是高维连续空间如 RGB 图像,或离散空间如 token),Z 是潜空间。

必要性: o_t 的维度通常为 [3, H, W] ≈ 10^5-10^6,直接建模如此高维的分布p(o_{t+1} | o_t, a_t) 在统计上不可行。编码器将问题降维到可处理的潜空间(如 VAE 的 4×32×32 = 4096 维,压缩比约 200×)。
同时,编码器可以引入归纳偏置(如 VAE 的重建导向,DINO 的语义导向)。

2. 时序状态转移模型(Temporal Transition Model)
trans: Z_t × A_t → Z_{t+1},泛化为条件生成过程 p(z_{t+1:t+H} | z_{1:t}, a_{t:t+H-1})。

必要性: 这是世界模型的"核心智能"。没有转移模型,模型只能记忆已见过的轨迹,
无法泛化到未见过的情况。NanoWM 使用扩散强迫(Diffusion Forcing)实现这一功能—— 通过调度矩阵(scheduling matrix)控制每帧的噪声水平,在统一框架下实现 teacher-forcing、自回归生成和全序列生成。

3. 动作条件接口(Action Conditioning Interface)
inject: (Z_t, A_t) → Z_t',将动作信息注入到状态表示中。

必要性: 没有动作条件,模型只能做无条件视频预测("最可能发生的未来"),无法做反事实推理("如果我做动作 A 会怎样?")。反事实推理是规划的基础。
NanoWM 支持 5 种注入机制,复杂度从 additive(零额外参数)到 cross-attention(全参数化交互),提供了从"弱条件"到"强条件"的连续谱系。

4. 生成/解码器(Generator / Decoder)
dec: Z → O 或 gen: Z → p(O),将潜空间预测映射回观测空间。

必要性: 潜空间预测对下游任务(如规划)可能足够,但对人类理解和可视化不足。
解码器确保世界模型的输出是可解释的。此外,在 MPC 规划中,目标函数通常定义在
潜空间(cosine distance to goal latent),解码器不是规划的必要组件,但
是模型可解释性和验证的必要组件。

5. 推理/规划引擎(Inference / Planning Engine)
plan: (Z_init, Z_goal, trans) → A*,在学到的动力学模型上搜索最优动作序列。

必要性: 世界模型本身只是一个发生器(generator),不是决策器(decision-maker)。
要让它产生行动价值,必须有一个在模型之上运行的优化算法。CEM 是最常见的方案:
  1) 采样 N 条动作序列
  2) 对每条 rollout 得到未来轨迹
  3) 用目标函数打分
  4) 选 elite 更新采样分布
  5) 执行最优序列的第一动作 → 重规划 (MPC)

组件间的形式化依赖关系:

组件关系

数据流向:

数据流向

动作条件是 Transition Model 的一个输入接口,不是独立组件;整个系统只有 4 个必要组件——编码器、转移模型、解码器、规划器。

2.3.4 开放问题

当前世界模型架构的开放问题:

  • 潜空间选择与可控性的权衡:语义潜空间(DINO/V-JEPA)在规划任务中表现不佳(Finding #4),很可能是因为扩散损失 + 高维语义特征的组合无法有效驱动动作条件分支。这是当前世界模型设计中的一个根本性矛盾——"好的表征"和"可控的动力学"似乎需要不同的潜空间属性。
  • 扩散 vs 单步预测的精度-代价权衡:扩散模型需要数十至数百步去噪,严重制约了 MPC 规划中的实时性(每次 rollout 都要完整采样)。
  • 长程生成的误差累积:即使用了 Diffusion Forcing 的滑动窗口,自回归生成不可避免地漂移(Finding #5),目前缺乏理论上有保证的纠错机制。

0x03 世界模型 vs 视频生成模型

单看 backbone,世界模型和视频生成模型的差异确实不大。核心区别不在"用什么骨架",而在四个根本性的不同:

3.1 条件信号不同:视频生成 vs 世界模型

视频生成模型(SVD, Genie等) 世界模型(NanoWM等)
输入条件 文本/图像 动作序列(连续向量)+ 历史帧
输出语义 "最可能的未来" "如果做了这个动作,会发生的未来"
反事实推理 ❌ 不具备 ✅ 可以查询:如果动作 X 会怎样?如果动作 Y 会怎样?

视频生成模型学的是 p(video | text)——给定文本,生成一个视频。世界模型学的是 p(o_{t+1:t+H} | o_{1:t}, a_{t:t+H-1})——给定历史和动作,生成受动作控制的未来。

这是反事实(counterfactual)推理的基础。举个例子:

世界模型的"泛化"不是"生成好看的视频",而是
—— 训练时只见过 左转→画面左移、右转→画面右移
—— 测试时问你:如果 上推摇杆 会怎样?
—— 正确回答:画面向上移动(即使没在数据中见过精确的"上推"场景)

视频生成模型做不到这一点——它没有"动作"通道来接受这种查询。


3.2 滚动误差累积(Rollout Error Accumulation)——世界模型特有的挑战

视频生成模型做一次完整生成就够了(文本→视频)。世界模型需要重复使用自己的输出来做下一步的输入:

视频生成 (single-pass):
  text → [o₁, o₂, ..., o₁₆]     ← 一次性生成16帧,误差不跨步

世界模型 (auto-regressive rollout):
  1: o₁, o₂ → predict o₃          ← 第1步
  2: o₂, o₃ → predict o₄          ← o₃ 已包含第1步误差
  3: o₃, o₄ → predict o₅          ← o₄ 包含前两步累积误差...
  ...
  50: o₄₉, o₅₀ → predict o₅₁     ← 误差指数级累积

这就是误差累积。视频生成模型不存在这个问题,因为它的生成不依赖自己的输出作为后续输入。

这直接决定了世界模型的架构设计必须包含:

  • 滑窗长度 vs 计算量的权衡
  • 历史稳定化(History Stabilization)——给已生成帧加微量噪声再重新去噪
  • 生成步数越多,采样步数需要越多(NanoWM 论文 Fig.6)

3.3 潜空间接口与编解码协议

视频生成模型通常固定在像素空间或单一潜空间。世界模型必须暴露一个多功能接口:

# 世界模型的 latent_codec 必须同时支持:
z = latent_codec.encode(o)           # 编码:o → 潜空间(用于预测)
ô = latent_codec.decode(z)           # 解码:潜空间 → 像素(用于可视化)
dist = cosine(z_pred, z_goal)        # 潜空间内比较(用于规划目标函数)

这意味着世界模型的编码器设计必须考虑三个用途的权衡:

  • 可解码性(VAE):需要保留足够像素信息
  • 语义性(DINO):需要抽象出与任务相关的特征
  • 可比性(规划时距离度量):潜空间中的距离必须反映任务相关差异

NanoWM 的 Finding #4 就暴露了这种权衡的困难——DINO/V-JEPA 的潜空间虽然语义好,但在扩散框架下无法学到可控动力学。


3.4 推理时的交互范式:MPC 闭环

视频生成是开环的——输入条件,输出生成,结束。

世界模型是闭环的——它被嵌入到一个决策循环中:

每步决策循环:
  1. 从环境拿到最新观测 o_t
  2. 用世界模型 rollout 多个候选动作序列
  3. 对比每个 rollout 结果与目标
  4. 选最优动作 → 执行第1步到环境
  5. 环境返回新观测 o_{t+1}
  6. 回到步骤 1(重规划)

这叫 Model Predictive Control (MPC) —— 世界模型作为"可查询的模拟器"。

这个循环对世界模型提出了额外的工程要求:

  • 批量 rollout:同时为 N 个候选动作序列做预测(batch_rollout)
  • 潜空间目标函数:不需要 decode 到像素就能打分(效率关键)
  • 部分可观测性处理:决策时只看到历史窗口,不是完整轨迹

3.5 总结:为什么不能把世界模型简单等同于 DiT 视频骨干?

对比

  • 视频生成模型 = DiT 骨干 + 文本/图像条件
  • 世界模型 = DiT 骨干 + 动作条件 + 滚动推理 + MPC 闭环 + 潜空间多用途接口

骨架一样,但外围系统、使用方式、工程挑战完全不同。打个比方:卡车和赛车的发动机可能都是 V8,但你不能说"赛车和卡车没啥区别"——底盘、传动、悬挂、用途都完全不同。

但你的质疑有一个点是完全正确的:当骨架趋同后,世界模型研究的"护城河"确实不在模型架构本身,而在如何让这个骨架学会可控的、规划可用的动力学——而这正是 NanoWM 论文通过 6 个发现试图回答的问题。

0x04 从三个视角理解 Nano World Models

4.1 视角一:假如我是个十二岁的孩子

想象你在玩一个电子游戏,比如《我的世界》。你在这个世界里走来走去,推开障碍物,捡起物品……你的大脑在不知不觉中学会了"预测下一秒会发生什么"——比如你推一块石头,它就会向前滚动。

Nano World Models(纳米世界模型,简称 NanoWM)就是教计算机学会这种"预测未来"的能力。

具体来说,我们给计算机看一堆视频,比如机器人推东西、人打 CS:GO 游戏。然后我们问计算机:"如果现在做这个动作,下一秒画面会变成什么样?"计算机通过学习视频里的规律,就能像人一样"想象"出未来的画面。

这个项目的厉害之处在于:

  • 它很小巧——不像那些需要超大计算机才能运行的模型,NanoWM 的设计很精简,普通人也能理解和改进。
  • 它能做很多事——不但能预测未来画面,还能帮机器人做规划("该怎么动才能达到目标?"),甚至能把生成的视频变成 3D 立体场景。
  • 它很开放——所有的代码、训练好的模型、数据都公开了,其他研究者可以直接拿来用。

简单说:NanoWM 是一个让计算机学会"想象未来"的工具箱,而且这个工具箱既简单又强大。


4.2 视角二:假如我是半个专业人士

Nano World Models 是一个基于扩散强迫(Diffusion Forcing) 范式的世界模型代码库。所谓"世界模型",就是通过学习大量时序观测数据(视频帧序列),让模型掌握环境的动态演化规律,从而能够根据当前状态和动作序列,预测未来的观测。

核心能力一览:

能力 说明
未来视频预测 给定若干历史帧 + 动作序列,模型生成后续帧
长程自回归生成 用滑动窗口超越训练长度,生成长达 50+ 帧的视频
动作条件建模 支持 5 种动作注入机制(加法、AdaLN、AdaLN-Fuse、FiLM、交叉注意力)
多种扩散目标 支持 x-prediction、ε-prediction、v-prediction 以及 Flow Matching
多尺度架构 NanoWM-S(40M)/ B(160M)/ L(600M)/ XL(830M)四种规模
多种潜空间编码器 SD-VAE(可解码回像素)、Web-DINO(语义特征)、V-JEPA 2.1(视频预训练特征)
下游应用 MPC 规划(CEM 算法)、视频转 3D 点云、长时 rollout
统一配置系统 基于 Hydra 的模块化 YAML 配置,所有组件可插拔

技术栈: PyTorch + PyTorch Lightning + Hydra + OmegaConf,扩散过程采用自定义实现的 GaussianDiffusion 和 FlowMatching,核心模型为 DiT(Diffusion Transformer)架构。


4.3 视角三:假如我是专业人士

Nano World Models 是一个面向未来视频预测的模块化、可复现研究框架,核心贡献在于:

  1. 统一化接口设计:以扩散强迫(Diffusion Forcing, Chen et al. 2024)为核心抽象,将不同的预测目标(x/ε/v/flow)、架构尺度(S/B/L/XL)、动作注入机制(additive/adaLN/FiLM/cross-attention)、潜空间编码器(SD-VAE/Web-DINO/V-JEPA)、数据集格式(D4RL/HDF5/LeRobot)统一到同一个训练-采样管线中——这在现有开源实现中是罕见的。

  2. 可扩展的 DiT 视频骨干:采用交替时空注意力(Spatial-Temporal Transformer)取代传统 UNet,通过 2D + 1D Rotary Position Embedding 编码位置信息,支持因果掩码以实现自回归生成。patch size(1/2/4/8)控制潜空间 token 数,天然支持变长序列。

  3. 扩散强迫调度矩阵:自定义调度矩阵支持三种采样模式——full_sequence(传统全序列去噪)、pyramid(逐帧错开起始噪声)、sequential(逐帧自回归去噪),首次在单一框架内统一了 teacher-forcing 和自回归生成。

  4. MPC(model predictive control)规划接口:将世界模型包装为批量化 rollout 函数,与 CEM(Cross-Entropy Method)规划器解耦,支持在潜空间直接计算目标距离(MSE / cosine),实现零样本规划。

  5. 规模化的消融实验:论文在 RT-1、PushT、CS:GO、Point Maze 等 6+ 数据集上系统比较了预测目标、模型规模、动作注入方式、潜空间类型对视频质量和规划性能的影响,提供了可复现的基线。

4.4 论文核心发现

论文的 6 个核心发现:

# 发现 实验依据
#1 v-prediction 和 x-prediction 优于 ε-prediction。v-prediction FID 最优(42.27),x-prediction PSNR 最优(23.37)。ε-prediction 最差(FID=48.86) RT-1 上 50K 步消融,余弦+ZTSNR 调度
#2 模型越大性能越好。从 NanoWM-S/2(40M)→B/2(160M)→L/2(~460M),PSNR、SSIM、LPIPS、FID 全部单调提升 RT-1 消融,所有超参数固定
#3 动作注入效果与任务相关。FiLM 在 RT-1 上 FID 最优(40.62),但 additive 在 PushT 上 FID 最优(23.89),且参数量-质量平衡最好 RT-1 + PushT 双任务消融,5 种注入机制对比
#4 语义潜空间(Web-DINO、V-JEPA 2.1)不自动适合规划。动作嵌入 RMS 接近 0(0.002 vs SD-VAE 的 0.112),导致 MPC 规划成功率 0%。原因:扩散目标 + 语义潜空间无法迫使模型学习可控动力学 PushT goal-reaching 规划实验
#5 长程 rollout 会累积误差,但增加 DDIM 采样步数可以缓解。50 帧 CS:GO 生成中 LPIPS 随帧数单调增长,250 步 DDIM 优于 50 步 CS:GO 长 rollout 实验
#6 同一训练评估配方跨域有效,但简单域(Point Maze FID=9.66)远好于复杂域(Granular FID=40.05, RT-1 FID=35.08) 6 个数据集的标准化评估

0x05 相关背景知识

5.1 Diffusion Forcing

5.1.1 向十二岁孩子解释 Diffusion Forcing

想象你在完成一幅拼图,但不是一次性拼完——你桌子上有 4 块拼图区域,分别对应视频的 4 帧画面:

  • 传统方法:4 块区域全部打碎成粉末,然后同时开始拼。每拼一步,4 块都清晰一点点,最后 4 块同时完整。
  • Diffusion Forcing(扩散强迫):你可以给每块区域设定不同的初始混乱程度。
    • 第 1 块(已经看过的画面):保持原样,不用拼
    • 第 2 块(马上要预测的):稍微打碎,很快拼好
    • 第 3 块(更远的未来):打得碎一点,慢慢拼
    • 第 4 块(最远的未来):打成粉末,最后才拼

更棒的是,你还可以换玩法:

  • "一次全部生成":和传统一样,所有区域同时拼
  • "逐帧生成":先拼好第 2 块,然后用第 1+2 块当线索去拼第 3 块,再用第 1+2+3 块拼第 4 块……
  • "金字塔生成":第 2 块拼到一半时,第 3 块开始拼,像多米诺骨牌一样

关键区别:传统方法像是"所有同学同时从同一个起跑线出发跑步";Diffusion Forcing 像是"每个同学可以从不同的起跑线出发,也可以在不同的时间出发"——这让模型能更灵活地处理"哪些帧我们已经确定,哪些帧需要生成"的问题。

5.1.2 向半专业人士解释 Diffusion Forcing

标准扩散模型(如 DDPM、DDIM)的采样方式是:对所有帧同时施加相同的噪声水平,然后逐步同步去噪。这在处理条件视频生成时有个根本局限——上下文帧(已观测到的)和未来帧(待生成的)应该处于不同的噪声水平,但标准扩散强制它们使用相同的噪声调度。

Diffusion Forcing(DF) 的核心改进是:每个时间步的每一帧都可以有独立的噪声水平。具体来说:

传统视频扩散:                 Diffusion Forcing:
step:  [250, 250, 250, 250]   step: [ -1, 250, 200, 150]
                                (-1 = 干净,已经是最终结果)

调度矩阵(scheduling matrix)是 DF 的数学抽象——它是一个 [T×F] 的矩阵,其中 T 是采样步数、F 是帧数。矩阵的每个元素表示对应帧在该采样步的噪声水平(-1 表示已经完成)。通过改变这个矩阵,DF 统一了三种生成模式:

模式 调度矩阵特征 语义
full_sequence 所有帧共享同一噪声水平,同步下降 传统无条件视频生成
sequential 每帧依次从高噪声→干净,下一帧等上一帧完成 自回归生成(teacher-forcing)
pyramid 帧间噪声起始时间错开(overlap),多帧并行但有先后 平衡了并行效率和因果性

训练时:DF 的每帧 t 也是独立采样(t ∈ [B, F] 或 [B]),这意味着模型必须学会:即使相邻帧处于完全不同的噪声水平,也能做出正确的预测。这迫使模型学到更鲁棒的时序表征。

对比标准 Diffusion Forcing(原文 Chen et al. 2024)与 NanoWM 的实现:NanoWM 的 DF 实现简化了一些——它主要通过调度矩阵控制采样过程,而训练的损失计算仍使用 GaussianDiffusion 的标准 MSE。其核心价值在于在一个模型内同时支持 teacher-forcing 和 自回归生成,而不需要修改模型架构。

5.1.3 向专业人士解释 Diffusion Forcing

问题背景

标准扩散模型(DDPM/DDIM)的定义是:对所有数据维度(如图像的所有像素、视频的所有帧)施加同一步调的噪声破坏与去噪。形式化地:

对于视频 x_{1:F},前向过程是 q(x_t | x_0) = N(√ᾱ(t)·x_0, (1-ᾱ(t))·I),同一 ᾱ(t) 作用于所有帧。

这在实际应用中产生了一个矛盾:在条件视频生成(如世界模型)中,上下文帧(context)和目标帧(future)应处于不同的噪声状态——上下文已知(应接近干净),未来未知(应高度噪声)。但标准扩散强迫两者共享同一噪声水平。

Diffusion Forcing 的形式化

Diffusion Forcing 将扩散扩展为帧粒度的噪声调度(frame-wise noise scheduling):

定义噪声索引集合 K ⊂ R。对轨迹 x_{1:F},每个帧 x_f 被分配一个独立的噪声索引 k_f ∈ K。模型在输入噪声轨迹 x_{k_1}, ..., x_{k_F}(其中 x_{k_f} = √ᾱ(k_f)·x_f + √(1-ᾱ(k_f))·ε_f)上进行训练,并学习预测干净数据或噪声。

调度矩阵 S ∈ R^{T×F} 是 DFoT(Diffusion Forcing of Time)的核心抽象:

# generate_scheduling_matrix(full_sequence, T=250, F=4):
S_full = [[250, 250, 250, 250],   # step 0: 全部高噪声
          ...,
          [  0,   0,   0,   0]]   # step 250: 全部干净

# generate_scheduling_matrix(sequential, T=250, F=4):
S_seq = [[250,  -1,  -1,  -1],    # step 0: 仅第1帧去噪
         ...
         [  0,  -1,  -1,  -1],    # step 250: 第1帧完成
         [  0, 250,  -1,  -1],    # step 251: 开始第2帧
         ...
         [  0,   0,   0,   0]]    # step 1000: 全部完成

其中 -1 表示该帧在此步骤是"冻结的"(已生成完成,不再参与去噪)。

与现有框架的关系
视角 等价关系
Teacher Forcing Sequential 模式:每帧以已生成的前帧为条件生成
Masked Autoregressive 通过噪声水平控制可见/掩码程度(非二值掩码,而是连续噪声水平)
DDPM Full-sequence 模式严格等价于标准 DDPM/DDIM
冷扩散(Cold Diffusion) DF 是冷扩散的一种推广——允许不同维度有不同退化程度

5.1.4 伪代码实现

基于 NanoWM 的实现,给出完整的两阶段伪代码:训练(diffusion forcing)和采样(DFoT)。


1. 训练阶段(每帧独立时间步)
# ──────────────────────────────────────────────────────────────
# 训练: Diffusion Forcing 单步
# 核心区别: t 是 [B, F] 而非 [B], 每帧有自己独立的噪声水平
# ──────────────────────────────────────────────────────────────
def train_step(model, diffusion, optimizer, batch):
    # batch.video: [B, F, 3, H, W]   原始像素视频
    # batch.action: [B, F, act_dim]  动作序列

    # (1) 编码到潜空间 (冻结 latent_codec)
    with torch.no_grad():
        x = rearrange(batch.video, 'b f c h w -> (b f) c h w')
        z = latent_codec.encode(x)             # [B*F, C_lat, H_lat, W_lat]
        z = rearrange(z, '(b f) c h w -> b f c h w', b=B)

    # (2) 每帧独立采样时间步  ←←← Diffusion Forcing 的核心
    t = sample_timesteps(shape=[B, F],        # 形状是 [B, F] 不是 [B]!
                         max=diffusion.num_timesteps)   # 每帧随机一个 t_f ~ U[0,1000)

    # (3) 前向加噪: 每帧按自己的 t 加噪
    noise = randn_like(z)                      # [B, F, C, H, W]
    z_t = q_sample(z, t, noise)                # z_t = √ᾱ(t)·z + √(1-ᾱ(t))·ε
                                               # 注意 ᾱ 是逐帧取的!

    # (4) 模型前向: 输入带噪声的 z_t 和每帧的 t
    pred = model(z_t, t=t, action=batch.action)
    #      model内部: t 是 [B,F] → flatten → t_embedder → 每帧独立条件
    #      输出: [B, F, C, H, W]

    # (5) 计算目标 (v-prediction 默认)
    target = v(z, t, noise)                    # v = √ᾱ·ε - √(1-ᾱ)·z

    # (6) 损失: 带 Min-SNR-gamma 加权
    mse = mean((pred - target)², dim=[-3,-2,-1])      # [B, F]
    weight = clamp(SNR(t), γ) / SNR(t)                # 低噪声步降权
    loss = mean(mse * weight)

    # (7) 反向传播
    loss.backward()
    clip_grad_norm_(model.parameters(), 0.1)          # step>20000 后启用
    optimizer.step()

2. 调度矩阵生成
# ──────────────────────────────────────────────────────────────
# 调度矩阵: 采样的"总谱"
# 形状 [num_steps, F], 元素 = 该帧在该采样步的噪声水平
# 特殊值 -1 = 该帧已冻结 (不参与去噪)
# ──────────────────────────────────────────────────────────────
def generate_scheduling_matrix(F, num_timesteps, sampling_steps, mode, n_context):
    # 只对需要生成的帧生成 (上下文帧最后直接置 -1)
    G = num_gen_frames = F - n_context

    if mode == 'full_sequence':           # 传统: 所有帧同步去噪
        schedule = np.arange(sampling_steps, -1, -1)      # [steps+1, 1]
        schedule = schedule.repeat(G, axis=1)              # [steps+1, G]
        # 形状: (sampling_steps+1, G)

    elif mode == 'pyramid':               # 错峰: 帧间 delay 1步
        schedule = np.zeros((sampling_steps + G, G), dtype=int)
        for step in range(sampling_steps + G):
            for f in range(G):
                eff = step - f                          # 帧 f 延迟 f 步
                if   eff < 0:             schedule[step,f] = sampling_steps     # 未开始→纯噪声
                elif eff >= sampling_steps: schedule[step,f] = 0                # 已完成
                else:                     schedule[step,f] = sampling_steps - eff
        # 形状: (sampling_steps + G, G)

    elif mode == 'sequential':            # 逐帧: 完成一帧才开始下一帧
        schedule = np.full((sampling_steps * G + 1, G), sampling_steps)
        for f in range(G):
            start = f * sampling_steps
            for s in range(sampling_steps + 1):
                schedule[start+s:, f] = sampling_steps - s
        # 形状: (sampling_steps * G + 1, G)

    # 上下文帧: 置 -1 (冻结)
    if n_context > 0:
        schedule = concat(zeros(steps, n_context), schedule, axis=1)
        # context列 = 0 → 映射到 -1

    # DDIM index → 真实 timestep 映射 (0→-1, sampling_steps→999)
    return ddim_idx_to_timestep(schedule, num_timesteps, sampling_steps)

三种模式对比(假设 sampling_steps=4, G=3):

full_sequence:  [4 4 4] → [3 3 3] → [2 2 2] → [1 1 1] → [0 0 0]   (5步)
pyramid:        [4 4 4] → [3 4 4] → [2 3 4] → [1 2 3] → [0 1 2] → [-1 0 1] → [-1 -1 0] → [-1 -1 -1]   (7步)
sequential:     [4 4 4] → [3 4 4] → [2 4 4] → [1 4 4] → [0 4 4] → [-1 3 4] → ... → [-1 -1 -1]   (13步)

3. DFoT 采样(多步去噪)
# ──────────────────────────────────────────────────────────────
# DFoT 采样: 按照调度矩阵逐帧去噪
# ──────────────────────────────────────────────────────────────
def dfot_sample(diffusion, model, shape, context, n_context,
                scheduling_mode, num_sampling_steps, model_kwargs):
    B, F = shape[:2]

    # (1) 生成调度矩阵
    S = generate_scheduling_matrix(F, diffusion.num_timesteps,
                                   num_sampling_steps, scheduling_mode, n_context)
    # S: [num_steps, B, F] (expand到batch)

    # (2) 初始化: 全噪声
    z = randn(*shape)                     # [B, F, C, H, W]

    # (3) 上下文帧替换为真实帧
    if n_context > 0:
        z[:, :n_context] = context        # 前n_context帧 = 真实观测的潜变量

    # (4) (可选) 历史稳定化: 给上下文帧加微量噪声
    if history_stabilization > 0:
        t_stab = int(history_stabilization * (num_timesteps - 1))
        z[:, :n_context] = q_sample(z[:, :n_context], t_stab)

    # (5) 主去噪循环: 每一步整批调用模型
    for step in range(num_steps - 1):
        curr_t = S[step]      # [B, F] 当前每帧噪声水平
        next_t = S[step+1]    # [B, F] 下一步每帧噪声水平

        z_prev = z.clone()    # 备份 (用于恢复上下文帧)

        # 单步 DDIM: 模型一次推理, 所有帧同时更新
        out = dfot_ddim_step(model, z, curr_t, next_t, model_kwargs)
        z = out['sample']

        # 上下文帧恢复: 用掩码确保冻结帧不变
        z = where(context_mask_expanded, z_prev, z)

    # (6) 返回完全去噪的潜变量
    return z                  # [B, F, C_lat, H_lat, W_lat]

4. 单步 DDIM(带逐帧噪声水平)
# ──────────────────────────────────────────────────────────────
# DFoT DDIM 单步: 一次模型推理, 处理所有帧 (无论噪声水平是否相同)
# ──────────────────────────────────────────────────────────────
def dfot_ddim_step(model, z, curr_t, next_t, model_kwargs):
    # z: [B, F, C, H, W]
    # curr_t, next_t: [B, F]   每帧的当前/目标噪声水平
    #                      -1 表示该帧已冻结

    # 掩码: 只需更新 curr_t > 0 且 非 -1 的帧
    mask = (curr_t != -1) & (next_t < curr_t)      # [B, F]

    # 模型推理 (一次, 不是逐帧!)
    pred = model(z, t=curr_t, **model_kwargs)      # 预测 target (如 v)
    #      ↑ 模型必须能处理每帧不同噪声水平的输入
    #        (通过 per-frame timestep embedding 实现)

    # 从预测还原 x₀
    x0 = v_predict_to_x0(z, pred, curr_t)          # 或 ε/x₀ 相应还原

    # 计算去噪后的 z (DDIM deterministic, eta=0)
    z_next = z + (sqrt(ᾱ(next_t)) - sqrt(ᾱ(curr_t))) * x0

    # 只更新需要更新的帧
    z = where(mask.unsqueeze(-1).unsqueeze(-1).unsqueeze(-1), z_next, z)
    return {'sample': z}

5. 汇总:DF 训练 vs 采样的对应关系
维度 训练(单步) 采样(多步)
时间步形状 t: [B, F] 随机采样 S 矩阵 [steps, B, F] 预定义
模型调用次数 1 次 sampling_steps 次
帧间噪声关系 独立随机 由调度矩阵约束
上下文帧 无(全部是训练数据) 冻结(-1 或历史稳定化)
梯度 有 无(no_grad)
加噪方向 干净 → 带噪(正过程) 带噪 → 干净(逆过程)

核心思想的统一:训练和采样共用同一个关键机制——每帧有独立的噪声水平 t_f。训练时这个 t_f 是随机采样的,采样时它由调度矩阵决定。模型学到的是"给定任意噪声水平的帧序列,预测去噪目标",这个能力在两种阶段完全复用。

5.1.5 在 NanoWM 中的实现细节

独立性体现

NanoWM 的 DF 实现通过两个级别的独立性体现:

1. 训练时:时间步独立采样

# train_experiment.py, training_step()
if diffusion_mode == "diffusion_forcing":
    t_shape = (x.shape[0], x.shape[1])  # [B, F] — 每帧一个时间步
elif diffusion_mode == "full_seq_diffusion":
    t_shape = (x.shape[0],)             # [B] — 所有帧共享一个时间步

当 t 是 2D [B, F] 时,forward 中每个帧获得独立的时间步嵌入:

# nanowm.py forward()
if t.ndim == 2:
    t_flat = t.flatten()               # [B*F]
    t_emb_flat = self.t_embedder(t_flat)  # [B*F, D]
    timestep_spatial = t_emb_flat       # [B*F, D] — SpatialBlock 使用
    timestep_temp = repeat(t_emb, ...)   # [B*P, F, D] — TemporalBlock 使用

这意味着 SpatialBlock 的 adaLN_modulation 接收的是帧特定的条件向量——第 1 帧(干净)和第 4 帧(高噪声)走的是不同的 adaLN 路径。

TemporalBlock:当 SpatialBlock 处理完帧内的 patch 间关系后,rearrange 将形状从 [(B*F), P, D] 转为 [(B*P), F, D]——即每个 patch 位置观察它在 F 帧上的变化。TemporalBlock 在这上面做 1D RoPE 自注意力,让帧之间通信。如果 causal=True,帧 t 只能看帧 ≤t,实现自回归。一句话:SpatialBlock 处理"一帧之内",TemporalBlock 处理"跨帧之间"。

2. 采样时:调度矩阵驱动

dfot_sample() 函数接收 scheduling_mode 和 n_context_frames:

z_sample = dfot_sample(
    diffusion=self.diffusion,
    model=eval_model,
    shape=z.shape,                      # [B, F, C, H, W]
    context=z[:, :n_context],           # 前 n_context 帧作为干净上下文
    n_context_frames=n_context,
    scheduling_mode=scheduling_mode,    # "sequential" / "pyramid" / "full_sequence"
    num_sampling_steps=num_sampling_steps,
    model_kwargs=model_kwargs,
    ...
)

内部逻辑是:

  1. 初始化 z = torch.randn(shape),但将 z[:, :n_context] 替换为真实上下文帧
  2. 调用 generate_scheduling_matrix() 生成去噪路径矩阵
  3. 对每个 step,按矩阵中定义的每帧噪声水平:
    • 如果 curr_t == -1:跳过(帧已完成)
    • 否则:对帧 f 执行一步 DDIM 采样
关键优势
  1. 框架统一:无需为 teacher-forcing、自回归、全序列生成维护三套独立的代码
  2. 平滑插值:噪声水平是连续的,允许部分帧处于"部分噪声"状态——比掩码语言模型的二值掩码更灵活
  3. 滑窗长程生成:sequential 模式天然支持生成远超训练长度的序列——每次只生成一帧,然后将其滑入上下文窗口
  4. 历史稳定化(History Stabilization):论文实验发现,在 sequential 模式中,对已生成帧施加微量噪声再重新去噪,可以缓解误差累积
局限与开放问题
  • 不同调度模式之间的最优选择与任务相关,目前缺乏自动选择机制
  • Sequential 模式的采样步数 = sampling_steps × horizon + 1,代价随生成长度线性增长
  • 训练时每帧独立时间步意味着模型需要适应高度异质的输入噪声分布——这对模型容量的要求高于全序列模式

5.2 三种扩散预测目标(x / ε / v)+ Flow Matching

先回顾扩散前向过程的核心公式:

x_t = √ᾱ·x₀ + √(1-ᾱ)·ε    (高斯扩散)

其中 x₀ 是干净数据,ε ~ N(0,I) 是噪声,ᾱ 由噪声调度决定(t 越大 ᾱ 越接近 0)。

模型在训练时接收 x_t 和时间步 t,需要预测某个目标。不同目标相当于教模型用不同的"视角"理解去噪过程:


5.2.1 ε-prediction(预测噪声)

  • 直观:模型问"这张图被加了多少噪声?",猜出噪声后通过 x₀ = (x_t - √(1-ᾱ)·ε_θ) / √ᾱ 还原
  • 预测目标:模型输出 ε_θ(x_t, t),让它尽量接近真实噪声 ε,即target = ε(加进去的高斯噪声)
  • 损失:MSE(ε_θ, ε)
  • 采样时:x_{t-1} = (x_t - √(1-ᾱ)·ε_θ) / √ᾱ(去噪公式)
  • 特点:DDPM 原始方案。但问题在于——当 t 接近 0(几乎无噪声)时,模型预测噪声的任务变得病态(从几乎干净的图像中猜噪声是哪来的 / 模型在猜一个几乎不存在的量),导致质量受限,导致低噪声步严重偏置
  • 论文结论:在 RT-1 上表现最差(FID=48.86)

5.2.2 x₀-prediction(预测干净数据)

  • 直观:模型问"这张图去噪后应该是啥样?",直接输出结果
  • 预测目标:模型输出直接就是 x₀_θ(x_t, t),让它接近原始干净数据 x₀,即target = x₀(原始干净图)
  • 损失:MSE(x₀_θ, x₀)
  • 特点:更直观——"从噪声版本中还原原图"。但问题是对每个 t 的输入变动巨大(t=0 时几乎原图,t=T 时几乎纯噪声,要求模型从几乎纯噪声中猜原图,高噪声步病态),模型需要适应变化极大的输入分布
  • 论文结论:像素级指标最好(PSNR=23.37,SSIM=0.783),但分布级指标(FID=42.99)不如 v-prediction

5.2.3 v-prediction(预测速度,默认方案)

  • 直观:不猜噪声也不猜原图,而是猜"去噪的方向和速度"
  • 预测目标:定义为 v = √ᾱ·ε - √(1-ᾱ)·x₀,即"数据→噪声"方向上单位速度的矢量(x_t 对 t 的导数方向)
  • 数学等价性:v = α̇·x₀ + β̇·ε,对 (1) 式两边求导,v 实际上代表了"从 x₀ 走向 ε"的速度向量,即扩散过程中 x_t 对 t 的导数方向。
  • 损失:MSE(v_θ, v)
  • 特点:
    • 平衡了 ε 和 x₀ 两种极端:既不要求模型在低噪声时精确猜噪声,也不要求模型在高噪声时精确猜原图,即t→0 时 v≈-x₀(聚焦信号),t=T 时 v≈ε(聚焦噪声),动态适应
    • 配合 Zero-Terminal-SNR(最终时刻完全无信号)效果最好
  • 论文结论:FID 最优(42.27),被选为默认方案

5.2.4 Flow Matching(流匹配)

跟上面三个高斯扩散不同,Flow Matching 换了一个底层逻辑:

x_t = (1-τ)·x₀ + τ·ε       ← 线性插值,而非指数衰减
τ = 1 - (t+1)/T             ← 时间参数从 0→1 均匀变化

  • 预测目标:向量场 u = x₀ - ε(也就是 x₀ 指向 ε 的恒定方向 / 从数据指向噪声的恒定方向)
  • 采样:Euler ODE 积分 x₀ ← x_t - u·Δt,而不是 DDIM/DDPM
  • 特点:正向过程更简单(均匀插值),采样时用 ODE 求解器而非离散去噪公式。训练损失无加权(均匀权重)
  • 优势:更灵活的推理步数控制,理论上有更好的连续性 / 正向过程更简单,推理步数更灵活,训练无加权

5.2.5 关键区别一图流

关键区别一图流

5.3 五种动作注入机制

NanoWM 的核心挑战是:如何让视频预测受动作控制? 即给定过去帧 + 动作序列,模型需要正确预测动作对应的未来帧。

动作注入发生在每个 TransformerBlock 中,有 5 种方式,按复杂度升序排列:


① Additive(加法注入,最简单)

做法:将动作嵌入直接加到 patch token 上

# Spatial block: action_emb [B*F, 1, D]
x = x + action_emb              # 加到所有 patch token
# Temporal block: action_emb [B*P, F, D]
x = x + action_emb              # 加到所有帧 token

优点:零额外参数,简单高效 缺点:表达能力有限——动作只是"加性偏置",不能动态调节特征处理方式 论文结果:PushT 上最优(PSNR=26.20),参数量-质量权衡最佳


② AdaLN(Adaptive Layer Normalization)

adaLN_modulation(Adaptive Layer Normalization Modulation):它是一个 nn.Sequential(SiLU, Linear(hidden_size, 6*hidden_size))。作用是根据时间步(或时间步+动作融合后的条件向量 c)动态生成 6 个参数,分别控制两个子层(Self-Attention 和 MLP)的 shift、scale、gate。让模型能根据"当前去噪到什么程度"来调节特征处理方式。

背景:NanoWM 的主干使用的是 adaLN-Zero——即 timestep 嵌入通过 MLP 生成 6 个参数(shift/scale/gate × 2 个子层),用这些参数调节 LayerNorm + 门控残差。

AdaLN 做法:给动作单独一个并行的 adaLN 分支,生成的 shift/scale/gate 与 timestep 的对应参数相加:

t_params = adaLN_modulation(c)        # [6*D] from timestep
a_params = action_adaLN_modulation(a) # [6*D] from action
shift = t_shift + a_shift,scale = t_scale + a_scale,gate = t_gate + a_gate

优点:动作可以动态调节每层的激活分布(哪些特征重要,哪些不重要) 缺点:每个 Block 额外 6×D → D 的线性层,增加参数量


③ AdaLN-Fuse(融合注入)

与 adaLN 的区别:动作不通过独立的 adaLN 分支,而是直接将动作嵌入加到 timestep 条件向量 c 上,让同一个 adaLN 调制器同时处理 timestep + action 信息:

c = c + action_emb     # 融合
shift, scale, gate = adaLN_modulation(c)  # 单一分支处理融合条件

优点:不增加额外 adaLN 参数,动作与 timestep 通过同一个非线性映射交互 缺点:动作和时间的混合是"固定的"(加法),灵活性略低于独立分支


④ FiLM(Feature-wise Linear Modulation)

FiLM 的做法是:在 Self-Attention 之后、MLP 之前,用动作嵌入生成两个向量 γ 和 β,对特征做逐元素仿射变换:

# After self-attention, before MLP:
gamma, beta = film_modulation(action_emb)  # [D] 形状
x = (1 + gamma) * x + beta                # 特征调制

这与 adaLN 的区别:

  • adaLN 调节的是 norm 层的输入,影响的是 attention + MLP 全过程
  • FiLM 调节的是 attention 的输出,影响的是 MLP 的输入
  • 两者是互补的,可以共存

优点:直观的"门控"语义——"如果动作是左转,那就增强代表左转的特征通道" 论文结果:在 RT-1 上表现最好(FID=40.62,PSNR=23.20)


⑤ Cross-Attention(交叉注意力)

做法:在 Block 最后,用 video token 做 Q、action 做 K/V,通过交叉注意力让每个视觉位置从动作序列中"查询"相关信息:

x = x + cross_gate * cross_attn(norm_cross(x), action_emb)
# Q from video tokens, K/V from action embeddings

优点:最灵活——动作可以以非局部的、内容自适应的方式影响每个视觉 token。不同 patch 可以从同个动作中学到不同信息 缺点:

  • 参数量最大(187M vs 158.6M baseline)
  • 容易过拟合——模型学到"忽略动作"也能预测好(因为相邻帧高度相关)
  • 论文结果:RT-1 上表现最差(PSNR=20.82,FID=51.12)

5.4 三种潜空间编码器

5.4.1 SD-VAE(Stable Diffusion VAE)

属性 值
来源 stabilityai/sd-vae-ft-mse
架构 卷积 VAE(编码器 + 解码器)
输入尺寸 256×256 RGB
潜变量形状 [4, 32, 32]
下采样倍数 8×
有解码器? ✅ 可还原回 RGB
潜空间特性 重建导向——通道数少(4),"物质性"强,像素对齐好

工作原理:标准 VAE 结构——编码器通过卷积逐步下采样,在低维空间学到一个紧凑的高斯分布表示(均值+方差),解码器从该分布重建原图。使用 KL 正则化和 MSE 重建损失训练。

为什么用作世界模型潜空间? 4 通道 × 32×32 是非常小的"令牌空间"(共 1024 个数值),但包含了足够重建 256×256 图像的信息。模型在这个紧凑空间里做扩散预测,计算效率远高于像素空间。

关键结果:SD-VAE 是唯一成功支持 MPC 规划的潜空间(PushT 成功率 25%),因为模型学会了使用动作条件。


5.4.2 Web-DINO(语义特征编码器)

属性 值
来源 facebook/webssl-dino300m-full2b-224
架构 ViT-L/14(Vision Transformer)
输入尺寸 224×224 RGB
潜变量形状 [1024, 16, 16]
下采样倍数 14×(patch size)
有解码器? ❌ 编码器-only
潜空间特性 语义导向——通道数多(1024),强调物体级不变性

工作原理:DINOv2 通过自监督学习(无标签),让模型学会关注图像的语义内容而不是像素细节。同一物体在不同视角、光照下会得到相似的 DINO 特征。Web-DINO 是 DINO 的大规模变体。

为什么用作世界模型潜空间? 理论上,语义特征更有利于规划——"我不需要精确知道椅子每个像素的 RGB 值,只需要知道那里有一把椅子"。但实验表明 DINO 特征做扩散时,模型会"偷懒"——因为相邻帧的 DINO 特征本身就非常相似,模型发现不需要动作也能做出还可接受的预测,于是动作分支的权重被迫收敛到 0(RMS=0.002)。

关键结果:规划成功率 0%。模型学会了忽视动作。


5.4.3 V-JEPA 2.1(视频预训练特征编码器)

属性 值
来源 Video-JEPA 2.1
架构 ViT-L/16
输入尺寸 384×384 RGB
潜变量形状 [1024, 16, 16]
下采样倍数 16×(patch size)
有解码器? ❌ 编码器-only
潜空间特性 视频预测导向——在大量视频上预训练,学习视频的动态规律

工作原理:V-JEPA(Video Joint Embedding Predictive Architecture)是一种自监督视频学习范式:给定视频的一部分(可见 block),预测被遮挡部分的特征表示。它在视频层面预训练,因此理论上更擅长捕捉时序动态。

为什么用作世界模型潜空间? 虽然 V-JEPA 本身是在视频预测任务上预训练的,但作为世界模型的潜空间时表现却与 Web-DINO 类似——动作嵌入 RMS 仅 0.00129,规划成功率 0%。论文分析认为,扩散损失 + 语义潜空间的组合,不足以迫使模型学习可控动力学。可能的原因:

  1. 语义特征空间本身"光滑"——微小动作变化在语义空间中的差异太小
  2. 扩散模型在解码时倾向于"填充平均值"而非精确动作条件

5.4.4 三个编码器在动作利用能力上的系统性对比

编码器 动作嵌入 RMS GT 动作 vs 随机动作的 MSE 差异 规划成功率
SD-VAE 0.112 0.015 vs 0.081(6倍差异) 25%
Web-DINO 0.002 0.834 vs 0.834(几乎无差异) 0%
V-JEPA 2.1 0.001 0.584 vs 0.584(几乎无差异) 0%

这说明:不是语义潜空间本身不好,而是扩散训练框架下的语义潜空间很难学到 action-conditioned dynamics。这是当前世界模型研究的一个重要开放问题。

TransFormer-封面

0xFF 参考

来源:博客园 · cnblogs.com