Skip to main content

概述

Cosmos3 的 policy 路径和文生视频不是一回事。它是模型里会看场景、会读任务、会想下一步怎么动的那部分。给它一帧 observation 和一句任务,它预测一段 action chunk;给它一段 action,它推演一个可能的未来;给它一段已经发生的 transition,它反推中间用了什么动作。 这一页用的是 Cosmos3-Nano-Policy-DROID。想要 action 输出时,别拿通用的 Cosmos3-Nano 生成 checkpoint 来代替;那条路在 Cosmos3 生成模式 一个 cosmos3_policy 插件承担三种 mode,单卡多卡都行:
examples/cosmos3/run_cosmos3_policy.py 接好了三种 mode。它以 decode_video=True 运行,action 存成 JSON,返回像素时再写一段 rollout mp4。加 --cfg 2--tp N 就换到 managed worker 上跑。它一次只处理一个请求,是演示,不是服务。

架构

policy 路径和生成路径共用 Cosmos3 transformer。请求里多了 action latent、domain id 和 mode。视频和动作走同一个去噪循环,mode 只决定谁是干净的条件、谁要被生成。
phyai/src/phyai/models/cosmos3
main_cosmos3_policy.py
scheduler_cosmos3_policy.py
model_runner_policy_cosmos3.py
model_runner_vae_cosmos3.py
modeling_cosmos3.py
vae_wan.py
sampler_unipc.py

三种 mode

policy 是控制环的形状:observation 加任务进去,action chunk 出来。第一帧 observation 是干净条件,后面的视频和动作都从噪声里生成。它回答的是“看到这个场景,机器人该做什么”。 forward_dynamics 把 observation 和一段已知 action 交给模型,要它把视频推出来。action 是干净条件,视频是目标。它回答的是“这么动,接下来会发生什么”。这个 mode 必须传 --action-file inverse_dynamics 反过来。给它一段视频,它恢复出能解释这段变化的 action chunk。整段视频都是干净的,动作从噪声里恢复。它回答的是“从 A 到 B,中间做了什么”。

输入规范

Cosmos3PolicyProcessor.preprocess() 接收一个 dict。示例脚本从命令行参数拼出它:
图像会变成 (1, 3, T, H, W),范围 [-1, 1]。传 --video 时脚本读前 action_chunk_size + 1 帧,视频不够长就重复最后一帧。

Domain 与 action 维度

action 有两个宽度。action_dim 是模型内部宽度,默认 64raw_action_dim 是机器人动作空间的真实宽度。processor 把条件 action 补到 action_dim,再把输出切回 raw_action_dim 整数 domain_id 不带宽度信息,要一并传 --raw-action-dim

运行路径

1

准备权重

下载 Cosmos3-Nano-Policy-DROID。policy 路径至少需要:
2

构造 Engine

插件名是 "cosmos3_policy"decode_video=True 时会加载 VAE,解码后的 rollout 像素随 action 一起返回。
use_karras_sigmas=None 从 checkpoint 读采样调度;传 False 则改用 linear flow 加 flow_shift
3

构造 Processor

processor 负责缩放和补齐 observation、分词 prompt、补齐 action、解析 domain id,最后给输出切片。
4

Preprocess 输入

processed.video_shape 还是像素尺寸,构造请求时用 pixel_to_latent_shape 换成 latent grid。
5

构造 Request

6

Step 和后处理

action 总会返回,形状 (1, action_chunk, raw_action_dim)。引擎带 decode_video=True 时还有 pixels,范围 [0, 1]

脚本示例

从单张图预测 action:
.cache/ 下会落两个文件:cosmos3_policy_out_action.json 是 action chunk,cosmos3_policy_out.mp4 在解码了像素时出现。 用已知 action 推演视频:
action.json 两种写法都行,数值只是占位。DROID 的动作宽度是 10;chunk 短于 action_chunk_size 时,processor 重复最后一步补齐。
从一段 observation 视频反推 action:
不传 --condition-frames 时,单图以第 0 帧为条件,视频以第 0,1 帧为条件。

输出后处理

Cosmos3PolicyProcessor.postprocess() 从结果里取出 action,切到 raw_action_dim,如果给了 action_stats_path,再反归一化回物理单位: 没有 stats,action 就保持模型输出的归一化尺度。换 embodiment 时,权重、domain 和 stats 要一起换。

多卡运行

policy 插件用的 ParallelConfig 字段和生成插件一样。tp_size 切分 transformer,是这里真正有用的开关:示例用 guidance_scale=1.0,CFG 是关着的,cfg_size=2 只会多算一个随后被丢掉的分支(scheduler 见到会打 warning)。一次运行要 cfg_size * tp_size 张卡,在启动进程上用 CUDA_VISIBLE_DEVICES 选。
Python 里给 EngineConfig 加上 parallel,processor 用 device="cpu" 构造,请求就留在 CPU 上,GPU 归 worker。引擎放在 if __name__ == "__main__": 后面,因为 worker 用 spawn 启动,会重新 import 主模块。deployment 参数可选,这里只用来延长启动超时。
engine.step() 返回的是 output rank 上张量的 CUDA-IPC view,postprocessor 会把 action 搬到 CPU,有像素时一起搬。tp_size 要同时整除 attention head 数和 KV head 数(这个 checkpoint 是 1、2、4 或 8),dense 与 attention 的 TP 保持一致。多副本和外部启动器见 并行服务

完整代码