Skip to main content

概述

Cosmos3 的生成路径把一句话变成一段视频。打开 sound stream,同一次去噪还会写出一条跟着画面走的音轨。T2V 只出视频;T2AV 让视频 latent 和 sound latent 在同一条时间轴上一起推进,画面从噪声里慢慢显影,声音在旁边同步成形。 一个 cosmos3 插件同时覆盖两条路径和两种机器规模。默认 cfg_size=tp_size=1,引擎就在你的进程里 inline 运行。加上 --cfg 2--tp N,它改为在前几张可见 GPU 上给每个 rank 起一个 worker;请求和输出都不变。
这条路径以正确和对齐参考实现为先,不以速度为先。去噪循环是 Python 层的 UniPC 循环,CUDA graph 关闭,也还没有专用 kernel 和 batching。手头测到的任何耗时都请当作基线。

架构

这条路径沿用 PhyAI 一贯的 。插件内部把工作拆成几块:
phyai/src/phyai/models/cosmos3
main_cosmos3.py
scheduler_cosmos3.py
model_runner_cosmos3.py
model_runner_vae_cosmos3.py
modeling_cosmos3.py
vae_wan.py
avae_sound.py
sampler_unipc.py
configuration_cosmos3.py

运行路径

1

准备权重

下载 Cosmos3-Nano。示例假设目录长这样:
2

构造 Engine

T2V 需要 transformer 和 VAE。T2AV 还要从 sound_tokenizer 加载 AVAE,load_sound=True 要的就是它。
flow_shift=10.0use_karras_sigmas=False 是原生的 linear-flow UniPC 调度,示例脚本用的也是这组值。
3

Tokenize prompt

scheduler 不碰原始文本。Cosmos3Processor 套上 chat template,追加 eos<|vision_start|>,返回正负 prompt 的 token id。
negative_prompt=None 用的是 Cosmos3 内置的结构化负向 prompt;想留空就传 ""
4

构造请求

Cosmos3T2VRequest 装着分词后的条件、latent grid 和采样设置。
pixel_to_latent_shape 按 VAE 压缩比把像素尺寸换成 latent grid:时间维除 4,空间两维各除 16
5

运行生成

T2V 返回 (B, 3, T, H, W) 的像素张量,范围 [0, 1]。T2AV 返回一个 dict:
6

保存媒体

postprocessor 把结果搬到 CPU,把帧转成 uint8 RGB,有音频时把波形一起 mux 进同一个 mp4。

端到端示例

examples/cosmos3/run_cosmos3.py 把这些步骤串成了一条命令。最普通的 T2V:
加上 CFG 和 tensor parallel,同一个脚本就能铺到八张卡上。8 个 rank 要 8 张可见 GPU,在启动进程上先选好:
--sound 就是 T2AV。声音流会加载 AVAE,并且每一步多推进一条 latent,显存和耗时都会上去:
默认是 720×1280189 帧、35 步,要跑一阵子。第一次冒烟测试先把尺寸缩小:
脚本会打印 model_loadpreprocessinferenceto_cpuencode 五段耗时。inference 包含去噪循环和 VAE 解码,encode 是 PyAV 写文件的时间。

多卡运行

起作用的是 ParallelConfig 里的两个字段。cfg_size=2 让 conditional 和 unconditional 两个分支并排跑在两个 rank group 上,而不是在一张卡上一前一后。tp_size=N 把每个分支里的 transformer 切到 N 个 rank 上。每个 rank 是一个 worker 进程,所以一次运行要 cfg_size * tp_size 张卡,按可见顺序依次占用。 和 inline 片段相比,改动不多。EngineConfig 多一个 parallel。请求张量建在 CPU 上,因为 GPU 归 worker,请求要跨进程传过去。引擎挪到 if __name__ == "__main__": 后面:worker 用 spawn 启动,会重新 import 主模块,没有这层保护,每个 worker 都会试着再建一个引擎。deployment 参数依旧可选,这里只是给 worker 多留一点加载权重的时间。
engine.step() 交回来的是 output rank 那张卡上张量的 CUDA-IPC view,postprocessor 会把它拷到 CPU,保存和单卡一样。Cosmos3 接受 cfg_size 为 1 或 2,tp_size 要同时整除 attention head 数和 KV head 数(Cosmos3-Nano 是 1、2、4 或 8),dense 与 attention 的 TP 保持一致。其他并行轴在 worker 启动前就会被拒绝。多副本和 torchrun 启动见 并行服务

完整代码