Cosmos 3 方法原理全解

Cosmos 3 通俗原理讲解:从 VLA 到统一世界模型

image


0. 先用一句话说清楚

如果把 Pi0.5 简化成:

看图 + 读指令 + 读机器人状态,然后用 Flow Matching 生成未来动作。

那么 Cosmos 3 可以理解成:

把“未来动作”扩展成“未来视频、声音和动作”,再让这些连续输出在同一个 Generator 中联合去噪。

它还有一条普通 VLM 通路,可以回答问题、做 grounding(目标定位)和产生结构化 prompt。

flowchart LR OBS["图像 / 视频"] LANG["指令 / 问题"] STATE["机器人状态"] OBS --> C3["Cosmos 3"] LANG --> C3 STATE --> C3 C3 --> TEXT["文本回答<br/>像 VLM"] C3 --> VIDEO["未来视频<br/>像世界模型"] C3 --> AUDIO["同步声音"] C3 --> ACTION["未来动作<br/>像 VLA"]

Cosmos 3 最重要的设计只有三点:

  1. 两类 token:文本语义放进 AR 区;视频、音频、动作等连续量放进 DM 区。
  2. 两套 Transformer 参数:Reasoner 处理 AR,Generator 处理 DM。
  3. 一种任务表达:已知连续量保持 clean,待预测连续量加噪。改变 clean/noisy mask 就能切换任务。

0.1 先把几个词翻译成人话

术语 人话 在 Cosmos 3 里做什么
token 模型看到的一小块数据 一个词、一个图像小块、一个音频片段或一步动作
latent 压缩后的数据 VAE 把视频/声音压小后得到,生成结束再解码回像素/波形
clean 已知答案 作为条件原样放进去,不需要模型生成
noisy 被打乱的答案 从噪声开始,模型负责把它逐渐变好
velocity “下一步往哪走” Generator 每次前向真正输出的东西
sampler 按方向走很多小步的程序 重复调用 Generator,直到从噪声走到最终结果
flowchart LR N["noisy latent"] --> G["Generator:预测 velocity"] G --> S["sampler:走一步"] S -->|还没结束| N S -->|结束| X["最终 latent"] X --> D["VAE 解码 / 动作反归一化"]

0.2 和 Pi0.5 怎么对应

下面只是帮助建立直觉,不表示两者参数结构完全相同。

问题 Pi0.5 类 VLA Cosmos 3 Policy
已知条件 图像、指令、proprioception 图像、指令、proprioception
加噪目标 未来动作 未来动作 + 未来视频
学习方式 动作 Flow Matching 动作和视频联合 Flow Matching
部署输出 动作 动作;预测视频可以不解码
多出来的能力 主要做控制 还可做视频生成、世界预测、逆动力学、声音生成
flowchart TB subgraph VLA["Pi0.5 类 VLA 的直觉"] VOBS["观察 + 指令 + 状态"] --> AFLOW["Action Flow + sampler"] ANOISE["动作噪声"] --> AFLOW AFLOW --> AOUT["未来动作"] end subgraph COSMOS["Cosmos 3 Policy"] COBS["观察 + 指令 + 状态"] --> JFLOW["联合多模态 Flow + sampler"] CNOISE["动作噪声 + 视频噪声"] --> JFLOW JFLOW --> COUT["未来动作 + 预期视觉后果"] end

真正的升级点不是“多输出一个视频”这么简单,而是动作 token 与未来视频 token 在去噪时双向注意:模型生成动作时,也在同时形成“这个动作会造成什么后果”的内部预测。


1. 先看懂一次完整 Policy 采样

以 DROID Policy 为例,输入是:

  • 一条任务指令;
  • 当前三视角画面;
  • 当前机器人 proprioception,即关节和夹爪等自身状态。

训练目标是:

  • 未来 32 步动作;
  • 与这些动作对应的未来 RGB 画面。
flowchart LR INST["任务指令"] --> AR["AR 文本条件"] VIEW["当前三视角画面"] --> CLEAN["clean DM 条件"] PROP["当前机器人状态"] --> CLEAN NOISE["动作噪声 + 视频噪声"] --> X["当前 noisy 动作 / 视频"] AR --> GEN["一次 Generator 前向"] CLEAN --> GEN X --> GEN GEN --> VEL["动作 velocity<br/>+ 视频 velocity"] VEL --> STEP["Sampler 更新动作 / 视频"] STEP -->|还没到 sigma=0| X STEP -->|到达 sigma=0| FINAL["最终归一化动作<br/>+ 未来视频 latent"] FINAL --> ACT["反归一化后执行<br/>32 步动作"] FINAL --> FUT["可选:VAE 解码<br/>未来画面"]

把它对照普通 VLA 看:

  1. 指令、当前画面和当前状态都是条件;它们不需要被生成。
  2. 未来动作从高斯噪声开始,这一点和 Flow Matching VLA 相同;Cosmos 3 还同时初始化一块未来视频噪声。
  3. 一次 Generator 前向只预测当前时刻的动作 velocity 和视频 velocity,并不会直接给出最终动作。
  4. sampler 根据 velocity 更新两种 noisy latent,再调用下一次 Generator 前向。
  5. 重复到 \(\sigma=0\) 后,才得到最终动作和未来视频 latent。
  6. 部署时只需反归一化动作;未来视频可以不做 VAE 解码,因此辅助世界预测不必增加视频解码延迟。

1.1 Forward、Inverse、Policy 的区别

三个任务用的是同一网络,只是“什么已知、什么待生成”不同。

flowchart LR subgraph FD["Forward Dynamics"] FCOND["已知:过去画面 + 动作"] --> FOUT["生成:未来画面"] end subgraph ID["Inverse Dynamics"] ICOND["已知:完整视觉变化"] --> IOUT["生成:动作"] end subgraph POLICY["Policy"] PCOND["已知:当前画面 + 指令 + 状态"] --> POUT["生成:动作 + 未来画面"] end
  • Forward Dynamics:问“执行这个动作,世界会怎样?”
  • Inverse Dynamics:问“画面发生了这种变化,动作应该是什么?”
  • Policy:问“我要完成任务,动作是什么,而且它会造成什么视觉后果?”

2. Cosmos 3 的核心:AR 区和 DM 区

Cosmos 3 把输入组织成一条序列:

\(S=[S_{AR},S_{DM}]\)

不用把这看成复杂的新数学。它只是把两种不同性质的数据放在同一条序列里。

区域 放什么 怎么预测 对应直觉
AR 文本;做理解任务时也可放 ViT 视觉 token causal next-token prediction 普通 VLM
DM 视频 VAE latent、音频 latent、动作向量 Flow Matching diffusion action expert / DiT
flowchart LR AR["AR 区<br/>文本 / 可选 ViT 视觉"] --> EOS["EOS"] --> BOG["BOG"] BOG --> CLEAN["DM clean 条件<br/>已知视频 / 音频 / 动作"] CLEAN --> NOISY["DM noisy 目标<br/>待生成视频 / 音频 / 动作"]

EOS 表示 AR 内容结束,BOG 表示接下来进入连续生成区。

DM 内部顺序固定:

  1. 所有 clean 条件在前;
  2. 所有 noisy 目标在后;
  3. 每组内部按视觉、音频、动作排列。

缺少的模态直接省略。

2.1 为什么一张图需要 ViT 和 VAE 两种编码

flowchart LR PIX["同一张图 / 同一段视频"] PIX --> VIT["ViT 编码"] PIX --> VAE["Wan2.2 VAE 编码"] VIT --> SEM["语义 token<br/>适合回答“是什么”"] VAE --> LAT["可重建 latent<br/>适合生成像素"] SEM --> AR["进入 AR"] LAT --> DM["进入 DM"]
  • ViT 路径保留语义,适合理解、问答、grounding,但不能直接还原像素。
  • VAE 路径保留生成细节,去噪后可以还原图像或视频。

因此,标准 I2V 的首帧是 VAE 编码后的 clean DM 条件,不是把同一张图再塞进 ViT。只有先调用 Reasoner 看图并扩写 prompt 时,图像才额外走 ViT。

2.2 clean/noisy mask 就是任务开关

模式 AR 条件 DM clean 条件 DM noisy 目标
T2I 文本 图像
T2V 文本 视频
T2V + Audio 文本 视频 + 音频
I2V 文本 首帧 后续视频,可含音频
V2V continuation 文本 视频前缀 未来视频
Transfer 文本 edge/depth/seg/WSM 控制视频 RGB 视频
Forward Dynamics 文本 过去画面 + 动作 未来画面
Inverse Dynamics 文本 完整视频 动作
Policy 指令 当前画面 + proprioception 动作 + 未来画面

模型没有论文定义的额外 task-ID embedding。仓库的 model_mode 主要负责构造对应的 token 布局和 mask。

这里的 WSMWorld Scenario Map。它不是从 RGB 逐像素提取的 edge、depth 或 segmentation,而是自动驾驶场景的结构化控制图:其中画有车道线、道路边界、交通灯/信号,以及车辆和行人的动态 3D 框。可以把它理解成“把驾驶世界中真正影响规划的对象和道路规则画成一张控制图”。

训练配置中的 T_cond=0/1/2 分别对应 T2V/I2V/V2V。因果 VAE 会单独编码首帧(prime frame),之后每个 latent chunk 对应 4 个像素帧,所以 V2V 的 2 个 clean latent frame 覆盖原视频前 5 帧。


3. 双通路 MoT 到底是什么

MoT 是 Mixture-of-Transformers,不是 MoE,也没有“每个 token 选专家”的 router。

可以把一层 MoT 看成同一楼层里的两个房间:

  • Reasoner 房间有自己的 LayerNorm、QKV 和 MLP;
  • Generator 房间也有自己的 LayerNorm、QKV 和 MLP;
  • Generator 的 attention 可以读取 Reasoner 的 K/V;反方向不允许。
flowchart TB ARIN["AR token"] --> R["Reasoner 参数<br/>causal attention + MLP"] DMIN["DM token"] --> G["Generator 参数<br/>full attention + MLP"] R --> RKV["Reasoner 的 K/V"] RKV --> G R --> AROUT["下层 AR"] G --> DMOUT["下层 DM"] BLOCK["AR 不读取 DM<br/>DM 可以读取 AR 和 DM"]

对应公式只有两条:

\(O_{AR}=Attn_{causal}(Q_{AR},K_{AR},V_{AR})\)

\(O_{DM}=Attn_{full}(Q_{DM},[K_{AR};K_{DM}],[V_{AR};V_{DM}])\)

直观解释:

  • Reasoner 仍然是合法的自回归模型,不能偷看待生成视频或动作。
  • Generator 的每个 query 都能读取完整文本条件,以及同一样本的全部 DM token。
  • 视频、音频和动作在 DM 内是双向注意,所以可以联合协调。

3.1 一个容易误解的点

Generator 工作时,Reasoner 通路通常只是把 prompt 编码成固定条件。它不需要先生成一段 CoT,再调用另一个视频模型

flowchart LR PROMPT["文本 prompt"] --> R["Reasoner 通路<br/>得到 AR K/V"] CLEAN["可选 clean DM 条件"] --> G["一次 Generator 前向"] NOISE["连续模态噪声"] --> X["当前 noisy latent"] X --> G R --> G G --> V["当前 velocity"] V --> S["Sampler 更新一次"] S -->|还没到 sigma=0| X S -->|到达 sigma=0| D["VAE 解码 / 动作反归一化"] D --> OUT["视频 / 音频 / 动作"]

Prompt upsampling 是可选的额外步骤:先让 Reasoner 把短 prompt 扩写成结构化 JSON,再把 JSON 交给 Generator。它不是 MoT 的必经步骤。

3.2 为什么参数量接近两倍

每层有两套 Transformer 参数,所以总参数大约是基础 Transformer 的两倍:

版本 总参数 每条通路对应的基础规模 层数 hidden
Edge 4B 2B 28 2048
Nano 16B 8B 36 4096
Super 64B 32B 64 5120

这不表示每个 token 都同时经过两套 MLP:AR token 走 Reasoner,DM token 走 Generator。


4. 连续模态怎样进入模型

4.1 视频与音频

模态 编码方式 压缩后速率
视频 冻结 Wan2.2 causal VAE 时间约 4 倍压缩,空间每 32×32 像素一个位置
音频 冻结 Audio VAE 48 kHz,hop=1920,即 25 token/s

例如 832×480 视频的 latent 空间网格是 26×15。189 帧视频的 latent 时间长度是:

\(T_{latent}=1+\frac{189-1}{4}=48\)

所以共有:

\(48\times 26\times 15=18{,}720\)

个视觉位置,每个位置还有通道维。

4.2 动作

通用基座不直接共享所有机器人的底层控制格式,而是先统一几何含义,再使用域专属投影。

flowchart LR RAW["原始动作 / 位姿"] --> GEO["统一动作表示<br/>相对 SE(3) 等"] GEO --> NORM["逐维归一化到约 [-1,1]"] NORM --> USE{"这段动作已知吗?"} USE -->|已知| CLEAN["固定 clean 动作条件"] USE -->|待生成| X["当前 noisy 动作变量"] CLEAN --> WIN["域专属 W_in<br/>映射到 hidden"] X --> WIN WIN --> MOT["一次 Generator 前向"] MOT --> WOUT["域专属 W_out<br/>输出动作 velocity"] WOUT --> SAMPLE["Sampler 更新一次"] SAMPLE -->|还没到 sigma=0| X SAMPLE -->|到达 sigma=0| FINAL["最终归一化动作"] FINAL --> DENORM["反归一化"] DENORM --> SVD["需要时用 SVD<br/>恢复合法旋转矩阵"] SVD --> CTRL["下游控制器"]

因此,W_out 输出的不是最终控制量,而是当前 \(\sigma\) 下的动作 velocity。sampler 先在归一化动作空间完成积分,最后才做反归一化和旋转修正。clean 动作作为条件时也走 W_in,但它保持不变,不参与 Flow loss。

相邻位姿先变成相对运动:

\(\Delta T_t=T_{t-1}^{-1}T_t\)

常见通用表示:

每步动作
相机 / 自动驾驶 ego pose 9D = 3D 平移 + 6D 旋转
单臂机器人 10D = effector 9D + gripper 1D
双臂机器人 20D
第一视角双手 57D
人形机器人 29D

动作投影按机器人/动作域分别初始化,但共享 MoT 主干。模型输出还在归一化空间,必须用对应训练域的统计量反归一化,不能把一个机器人的尺度直接套给另一个机器人。

报告的旋转约定是:z 轴沿手指/夹爪方向,x 轴向右;6D rotation 最后通过 SVD 投影回合法的 3×3 旋转矩阵。

DROID Policy 是专项例外:它不用通用单臂 10D 相对末端位姿,而是预测 32 步、每步 8D 的绝对 joint_pos,即 7 个关节位置加 1 个夹爪量。


5. 视频、声音、动作如何对齐时间

如果只按 token 序号做位置编码,24 FPS 视频、25 token/s 音频和 15 Hz 动作会把“同一秒”放到不同位置。

Cosmos 3 给每个 token 分配 3D MRoPE 坐标 (t,h,w)

  • 文本:t=h=w,退化成普通 1D RoPE;
  • 视频:t 表示时间,h,w 表示空间网格;
  • 音频、动作:只使用 th=w=0

视频经过 4 倍时间压缩,所以:

\(TPS_{video}=FPS/4\)

以 24 FPS 视频为基准,时间步长按真实速率缩放:

\(\Delta t=\frac{6}{TPS}\)

flowchart LR REAL["同一段真实时间"] REAL --> V24["24 FPS 视频<br/>latent TPS=6<br/>步长=1"] REAL --> A25["音频 TPS=25<br/>步长=0.24"] REAL --> ACT15["动作 15 Hz<br/>步长=0.4"] V24 --> AXIS["共享物理时间轴"] A25 --> AXIS ACT15 --> AXIS

两个额外规则:

  1. AR 与 DM 的时间坐标之间固定跳过 15000,缓解首帧过饱和和棋盘格;这只是坐标偏移,不会插入 15000 个 token。
  2. I2V/V2V 的 clean 前缀和 noisy 未来沿同一视频时间轴连续;Transfer 的控制视频与 RGB 目标使用对齐的 (t,h,w)

MRoPE 只提供“谁应该与谁对齐”的位置先验,真正的同步仍要靠配对数据和联合训练学出来。


6. 训练:先学理解,再学生成

6.1 四个阶段

flowchart LR VLM["Qwen3-VL 风格初始化"] --> RP["1. Reasoner 预训练<br/>理解与 grounding"] RP --> RS["2. Reasoner SFT<br/>Physical AI + prompt upsampling"] RS --> COPY["复制 Reasoner 权重<br/>初始化 Generator"] COPY --> GP["3. Generator 预训练<br/>图像 / 视频 / 音频"] GP --> GM["4. Generator 中期训练<br/>动作 + Transfer"] GM --> POST["专项后训练<br/>T2I / I2V / DROID Policy"]

关键点:

  • Reasoner 用 next-token CE 学习。
  • Generator 从训练好的 Reasoner 权重初始化,因此一开始就带有语义知识。
  • Generator 预训练只更新生成侧参数,Reasoner 冻结。
  • 中期训练加入动作和控制视频;报告没有重新列出完整 freeze 清单。
  • DROID 后训练重新初始化 action encoder、action-decoding MLP 和 action embedding,动作参数使用 5 倍学习率。

6.2 数据各自负责什么

数据 主要教会模型什么
Reasoner 图文 / 视频文本 / 纯文本 识别、空间关系、时序理解、grounding、规划
图像 / 视频 外观、运动和世界变化
音视频 看得见的事件与声音同步
视频 + 动作 动作和状态变化之间的因果关系
Transfer edge/depth/seg/WSM 控制与 RGB 的空间对应
结构化 JSON caption 主体、镜头、时间段、动作和声音的细粒度控制
flowchart LR UNDER["Reasoner 数据<br/>22.0M 预训练 + 2.17M SFT"] --> R["语义与推理"] WORLD["图像 / 视频 / 音频"] --> G["生成先验"] ACTION["8.4M 动作 episodes"] --> G TRANS["4M Transfer"] --> G R --> C3["Cosmos 3"] G --> C3

6.3 Loss:只关注 Cosmos 3 多出的三件事

基本 Flow Matching 路径仍是:

\(x_\sigma=\sigma\epsilon+(1-\sigma)x_0,\qquad v^*=\epsilon-x_0\)

Generator 对 noisy 目标预测速度,使用 masked MSE:

\(\mathcal{L}_{m} = \mathbb{E}_{j:M_{m,j}=1} \left[ \left\lVert v_{\theta,m,j}-(\epsilon_{m,j}-x_{0,m,j}) \right\rVert_2^2 \right]\)

多模态总 loss 是:

\(\mathcal{L}_{DM} = \lambda_v\mathcal{L}_{vision} +\lambda_s\mathcal{L}_{audio} +\lambda_a\mathcal{L}_{action}\)

Cosmos 3 的特殊点:

  1. clean 条件参与 attention,但 mask 为 0,不计算 Flow loss。
  2. 视频、音频、动作各自独立采样噪声时间。 同一样本里,视频可以很噪,动作可以较干净。
  3. 中期训练 action loss 乘 10。 因为归一化动作的逐元素 MSE 通常比视觉小。
flowchart TB SAMPLE["一个视频 + 音频 + 动作样本"] SAMPLE --> TV["独立 sigma_visual"] SAMPLE --> TS["独立 sigma_audio"] SAMPLE --> TA["独立 sigma_action"] TV --> PACK["组合为一个 DM 输入"] TS --> PACK TA --> PACK PACK --> LOSS["各模态 masked MSE<br/>action 基础项 10x"]

时间采样分布是:

  • 图像、音频、动作:logit-normal;
  • 视频:mode sampling;
  • shift 把采样分布偏向高噪声区域,不是把 latent 数值乘一个常数。

shift 的定义是:

\(\bar t=1-t,\qquad \sigma=\frac{s\bar t}{1+(s-1)\bar t}\)

报告说中期动作“继承视觉 noise schedule”,但没有展开具体超参数。它不表示动作改用视频的 mode sampling,也不表示动作和视频共享同一个 sigma

6.4 训练伪代码

# 伪代码:同一段代码覆盖视频、音频和动作生成
def train_generator(batch):
    ar = encode_text(batch.prompt)
    clean_latents = encode_video_audio_action(batch)

    dm_parts = []
    targets = {}

    for modality in active_modalities(batch.task):
        x0 = clean_latents[modality]
        is_condition = condition_mask(batch.task, modality)

        # 每个模态独立采样噪声强度
        sigma = sample_sigma(modality, batch.resolution)
        eps = randn_like(x0)
        x_sigma = sigma * eps + (1 - sigma) * x0

        # 已知位置放 x0;待生成位置放 x_sigma
        dm_input = where(is_condition, x0, x_sigma)
        dm_parts.append((modality, dm_input, is_condition))
        targets[modality] = (eps - x0, ~is_condition)

    # 固定顺序:clean 视觉/音频/动作 -> noisy 视觉/音频/动作
    dm = pack_dm(dm_parts)
    velocity = model(ar, dm, sigma_per_modality=True)

    loss = sum(
        modality_weight(m) * masked_mse(velocity[m], targets[m])
        for m in targets
    )
    loss.backward()

7. 推理:Reasoner 和 Generator 是两种流程

7.1 Reasoner 推理

如果任务是问答、grounding 或 Action-CoT,DM 根本不启用。它就是普通 VLM:

文本 + ViT 视觉 -> causal next-token generation -> 文本 / JSON

7.2 Generator 推理

sequenceDiagram participant E as 编码器 participant R as Reasoner 通路 participant S as Sampler participant G as Generator 通路 participant D as 解码器 E->>R: 正向 prompt 与 baseline prompt(空文本或 negative prompt) R-->>S: 缓存两套固定 AR K/V E-->>S: clean DM 条件 S->>S: 待生成模态初始化为高斯噪声 loop sigma 从 1 到 0 S->>G: 当前 latent + clean 条件 + 正向 AR G-->>S: v_cond S->>G: 当前 latent + clean 条件 + baseline AR G-->>S: v_base S->>S: CFG 合成速度并更新 latent end S->>D: 最终 latent D-->>S: 图像 / 视频 / 音频 / 动作

CFG 是熟悉的:

\(v_{cfg}=v_{base}+w(v_{cond}-v_{base})\)

这里叫 v_base,而不总叫 v_uncond,因为 baseline 可能使用非空 negative prompt。

公开 Diffusers notebook 使用 UniPCMultistepScheduler。用 Euler 直观理解时:

\(x_{next}=x+(\sigma_{next}-\sigma)v_\theta(x,\sigma,c)\)

因为 sigma_next < sigma,积分方向从噪声走向数据。

7.3 统一推理伪代码

# 伪代码:T2V、I2V、音视频和动作共享同一骨架
def generate(request):
    # 首帧、控制视频、已知动作等都编码为 clean DM 条件
    clean = encode_clean_conditions(request)

    # 每个待生成模态从独立高斯噪声开始
    x = {
        m: randn(target_shape(m, request))
        for m in request.output_modalities
    }

    cond_ar = cache_reasoner(request.prompt)
    base_ar = cache_reasoner(request.negative_prompt)

    for sigma, sigma_next in noise_schedule(request):
        dm = pack_clean_then_noisy(clean, x)

        v_cond = generator(cond_ar, dm, sigma)
        v_base = generator(base_ar, dm, sigma)
        v = v_base + request.guidance * (v_cond - v_base)

        x = sampler_update(x, v, sigma, sigma_next)

    # 动作还需要 W_out、域反归一化和可选 rotation SVD
    return decode_modalities(x)

7.4 Transfer 为什么每步要三次预测

普通 CFG 只控制“是否服从文本”。Transfer 还要单独控制“是否紧跟 edge/depth/seg 等结构”。

flowchart LR X["当前 RGB noisy latent"] --> FULL["文本 + 控制视频<br/>v_full"] X --> TEXT["仅文本<br/>v_text"] X --> CTRL["控制视频 + negative caption<br/>v_ctrl"] FULL --> CG["control guidance"] TEXT --> CG FULL --> TG["text guidance"] CTRL --> TG CG --> V["最终 velocity"] TG --> V

因此 Transfer 每个 step 做三次 Generator 预测。报告推荐 text guidance 3、control guidance 1.5;仓库对 segmentation 和 WSM 使用不同权重,详见附录。

7.5 长时间 Forward Dynamics

一次生成长度有限,所以长 rollout 按 action chunk 分段:

flowchart LR I0["初始图像"] --> G1["Generator 1"] A1["动作 chunk 1"] --> G1 G1 --> V1["视频 1"] --> F1["最后一帧"] F1 --> G2["Generator 2"] A2["动作 chunk 2"] --> G2 G2 --> V2["视频 2"] --> F2["最后一帧"] F2 --> G3["Generator 3"] A3["动作 chunk 3"] --> G3

上一段最后一帧和下一段动作是并列条件。代价是上一段的视觉误差会进入下一段并累积。


8. 两个完整例子

8.1 I2V + Audio

目标:输入 832×480 首帧,生成 189 帧、24 FPS、约 8 秒的带声音视频。

flowchart LR P["结构化文本"] --> AR["AR 条件"] I["首帧"] --> VAE["视频 VAE"] --> C["1×15×26<br/>clean 视觉网格"] VN["47 个未来<br/>视觉 latent 帧噪声"] --> DM["DM 联合去噪"] AN["约 200 个<br/>音频 token 噪声"] --> DM AR --> DM C --> DM DM --> VV["48 个视觉 latent 帧"] DM --> AA["音频 latent"] VV --> VD["VAE 解码为 189 帧"] AA --> AD["解码为 48 kHz 音频"] VD --> MP4["与音频合并封装为 MP4"] AD --> MP4

为什么视觉目标是 47 个未来 latent 帧?总 latent 长度为 48,首个 latent frame 是 clean 条件,所以剩余 47 个从噪声生成。

8.2 DROID Policy

项目 论文和 finetune recipe
输入画面 540×640 三视角 canvas
proprioception 当前机器人内部状态
动作 32 步 × 8D absolute joint_pos
频率 15 Hz
辅助目标 未来 RGB
推理 4 steps,guidance 3,shift 5
部署 可跳过视频 latent 解码

三视角 canvas 的组成:

  • 上方:一张 360×640 wrist view;
  • 下方:两张 180×320 external view 左右拼接;
  • 最终:540×640

当前 SGLang notebook 与论文存在未解释的不一致:它同样加载 Cosmos3-Nano-Policy-DROIDdroid_lerobot,却请求 raw_action_dim=10、17 帧、30 steps、guidance 1。公开材料没有说明这是服务适配、示例漂移还是隐藏的接口转换,因此不能把这套参数当作论文 8D/32-step 接口的直接等价物。


9. 一页心智模型

flowchart TB TEXT["文本 + 用于理解的 ViT 视觉"] --> AR["AR token"] CONT["VAE 视频 / 音频 latent<br/>+ 动作向量"] --> DM["DM token"] AR --> R["Reasoner<br/>causal"] AR --> G["Generator 条件"] DM --> G["Generator<br/>full attention"] R --> TEXT_OUT["next-token 文本"] G --> VEL["多模态 velocity"] VEL --> TRAIN["训练:masked Flow MSE"] VEL --> SAMPLE["推理:CFG + sampler"] SAMPLE --> DECODE["VAE / 动作反归一化"] DECODE --> OUT["图像 / 视频 / 声音 / 动作"]

只记住下面五句话:

  1. Cosmos 3 是“VLM + 多模态 Flow expert”的统一扩展。
  2. Reasoner 管离散语义,Generator 管连续生成。
  3. Generator 能读 Reasoner;Reasoner 不能读待生成的 DM。
  4. 任务差异来自 clean/noisy mask,不来自换网络。
  5. Policy 比普通 VLA 多联合预测一个视觉未来,部署时可只取动作。

第二部分:精确细节,按需查阅

10. 数据细节

10.1 Reasoner 数据

flowchart LR RAW["图文 / 视频文本 / 纯文本"] --> EMB["conversation embedding"] EMB --> KM["K-means 分桶"] KM --> DEDUP["桶内 cosine > 0.95<br/>去近重复"] DEDUP --> JUDGE["Gemma-4-31B-it 评分"] JUDGE --> PRE["预训练:阈值 2"] JUDGE --> SFT["SFT:阈值 5"]

Judge 评价 faithfulness、completeness、correctness。

阶段 图文 视频-文本 纯文本 总计
预训练 18,814,952 1,016,299 2,170,762 22,002,013
SFT 1,051,513 1,079,200 40,960 2,171,673

预训练以 OCR、2D grounding、视觉 QA 为主。SFT 把视频提高到约一半,并加入自动驾驶、机器人、智慧基础设施、Action-CoT 和 prompt upsampling。

10.2 Generator 数据

阶段 图像 视频 音视频 动作 Transfer
预训练 767M 348M 139M - -
中期训练 16M 75M 19M 8.4M episodes 4M

计数是训练 stream 口径,不是互斥媒体总数:

  • 预训练音视频池由预训练视频池筛出;
  • 中期音视频池又从音视频池继续过滤;
  • 动作数据中的 1.9M camera-motion clips 来自预训练视频集;
  • 其余动作/Transfer 与普通视频池的完整重叠关系未公开。

图像和视频从 7.8B 原始图像、3B 源视频开始,经场景切分、黑边清理、标准化编码、去重、47 类语义标注和质量过滤。中期训练加入 PhyxSim、RobotSim、DriveSim、SynHuman、Warehouse 五类合成 Physical AI 数据。

10.3 为什么 caption 很长

Generator 训练使用结构化 JSON,而不只是“一只机器人在倒水”:

flowchart LR SHORT["短意图"] --> JSON["结构化 JSON"] JSON --> A["主体 / 外观 / 空间"] JSON --> B["镜头 / 光照 / 美学"] JSON --> C["分段动作时间线"] JSON --> D["声音与来源"] JSON --> E["分辨率 / FPS / 时长"]

Prompt upsampling 的作用是把用户短意图变成这种训练分布。Reasoner 直接输出 schema-constrained JSON;论文没有定义额外的后置 checker。

10.4 音频与动作数据

音频处理中,SAM-Audio 分离语音和其他声音;有脸且 lip-sync confidence ≥ 3 的样本进入同步语音分支,其余重点保留能由画面解释的物理声音。中期得到约 12.8M 非语音和 6M 同步语音样本。

动作中期训练共有约 61.3K 小时、8.4M episodes:

类型 占比
第一视角手部 67.4%
自动驾驶 16.3%
机器人 8.7%
相机运动 7.5%

机器人数据保留成功和失败轨迹;idle 不直接删除,而是记录数量供采样器平衡。


11. 训练配置细节

11.1 Reasoner

配置 预训练 SFT
数据 22.0M,2 epochs 2.17M,8200 iterations
最大上下文 16K 16K
LM/projector LR 5e-5 1e-5
ViT LR 5e-6 1e-6
Adam betas (0.9,0.999) (0.9,0.95)
weight decay 0.05 0.1
grad clip 1.0 1.0

Reasoner loss 是 teacher-forcing cross entropy:

\(\mathcal{L}_{AR} = -\sum_i m_i\log p_\theta(y_i\mid y_{<i},\text{vision},\text{instruction})\)

报告未公开精确 loss mask,也没有给出 square-root normalized per-token weighting 的完整代数形式。

预训练先做 10% linear warmup,再 cosine decay 到峰值的 0.1 倍。SFT warmup 1000 steps,之后同样 decay 到 0.1 倍;训练还按 1:4 的预训练:SFT 预算回放旧数据,并混入 800K instruction 数据缓解遗忘。

11.2 Generator 预训练

多分辨率 stream:

stream 视频帧数 shift 数据限制
image 单帧 随分辨率 图像
video 256p 5~400 1 所有源分辨率
video 480p 5~400 3 源 ≥ 480p
video 720p 5~300 5 源 ≥ 720p

四个 stream 采样比为 image : video256 : video480 : video720 = 1:1:2:1

任务比例:

T2I T2V I2V V2V
20% 56% 16% 8%

优化配置:

  • 固定 74K token budget,无 padding sequence packing;
  • FusedAdamW,LR 1e-4,betas (0.9,0.99)
  • weight decay 0.05,grad clip 1.0;
  • warmup 后线性下降到峰值 LR 的 0.30 倍;
  • 10% text dropout 训练 CFG baseline;
  • Nano:1024 GB200,31.05T token;
  • Super:2048 GB200,17.86T token。

11.3 Generator 中期训练

stream 比例
T2I 10%
T2V / I2V / V2V 32%
视频 + 音频 8%
Forward / Inverse / Policy 25%
通用 Transfer 20%
驾驶 WSM Transfer 5%

中期仍使用 74K context;256p/480p/720p shift 提高到 3/5/10。优化器为 FusedAdamW,LR 1e-4、weight decay 0.05、grad clip 1.0;LambdaLinear start factor 0.4、cycle 100K。Nano/Super 分别训练 2.4T/1.9T token。

11.4 专项后训练

checkpoint 数据和目标 训练配置
Super-T2I 45% 真实、40% 合成、15% 文字渲染,再用 470K 高质量数据精炼 20K + 2K steps,LR 1e-4,70K context
Super-I2V 平衡视频 + 1K 人工精选 + 约 20K 合成,混入 20% T2I token 480p、189 帧、24 FPS、10K iters、LR 1e-5
Nano-Policy-DROID 三视角、proprioception、32×8D joint action、辅助 RGB 15 Hz、LR 2e-4、动作参数 5× LR、10K iters

DROID 公开复现配置为 BF16、HSDP 32×8、global batch 8192。


12. 推理参数与能力边界

12.1 报告推荐参数

模型 / 模式 steps guidance shift
Nano/Super 音视频 50 6 10
Super-T2I 50 4 3
Super-I2V 50 6 5
Nano/Super Forward/Inverse 50 1 5
Nano-Policy-DROID 4 3 5
Nano/Super Transfer 50 text 3 / control 1.5 10

仓库示例与报告并非总是相同:

  • Diffusers cookbook 为统一演示使用 35 steps、guidance 6、shift 10。
  • Transfer spec 都使用 50 steps、shift 10;edge/depth/blur/multi-control 的 text/control 为 3/1.5,seg 为 3/2,WSM 为 1/3
  • SGLang Policy 使用 30 steps、guidance 1、shift 5,并存在前述 10D/17-frame 接口差异。

12.2 Edge 与 Nano/Super

Edge 当前能力边界:

  • 没有音频模块;
  • 不支持 V2V Transfer;
  • 支持 256p/480p;
  • 支持 50~150 帧。

完整音频、720p 和更完整 Transfer 能力不能无条件外推给 Edge。

12.3 已公开分辨率

分辨率 16:9 4:3 1:1 3:4 9:16
256p 320×192 320×256 256×256 256×320 192×320
480p 832×480 736×544 640×640 544×736 480×832
720p 1280×720 1104×832 960×960 832×1104 720×1280

训练视频 FPS 范围是 10~30。

12.4 编码器与模型规格

视觉理解侧使用 16×16 ViT patch,再通过 MLP 合并 2×2 token,并使用 DeepStack 和视频时间戳。生成侧使用冻结的 Wan2.2 causal VAE;音频侧使用冻结的 48 kHz 立体声 Audio VAE。

版本 总参数 层数 hidden Q/KV heads FFN
Edge 4B 28 2048 16 / 8 9216
Nano 16B 36 4096 32 / 8 12288
Super 64B 64 5120 64 / 8 25600

Reasoner 的仓库采样 profile 并不唯一:无显式 reasoning 的示例是 temperature 0.7、top-p 0.8、top-k 20;reasoning profile 是 0.6/0.95/20;Transformers quickstart 也可使用 greedy。


13. 大规模训练为什么能跑起来

主要问题是:一张图、400 帧视频和动作 episode 的 token 数差异巨大,固定样本数 batch 会产生大量 padding 和 GPU 负载不均。

flowchart LR STREAM["按模态独立 stream"] --> SYNC["所有 rank 同步选择 stream"] SYNC --> PACK["按 74K token budget 贪心 packing"] PACK --> LOOK["最多 look-ahead 10 个样本"] LOOK --> BATCH["长度相近的 packed batch"]
  • rank-synchronous stream selection 提升约 54% 吞吐;
  • look-ahead 让有效序列长度提高约 8%;
  • HSDP 分片模型、梯度和 optimizer state;
  • Ulysses context parallelism 切分长序列;
  • selective activation checkpointing 重点保存昂贵 attention 输出;
  • torch.compile + 分布式 AOT 编译 45 种 VAE shape;
  • 异步 checkpoint 保存模型、optimizer、RNG 和 loader state。

论文训练硬件上的 VAE 编码 chunk 经验值是 256p/480p/720p 对应 68/24/12 帧。它依赖显存,不能直接当作所有硬件的默认值。



posted @ 2026-07-21 21:06  S-X-Q  阅读(82)  评论(0)    收藏  举报