Cosmos3 Generator Transfer Examples¶
Cosmos3 video transfer examples — Nano (single GPU) and Super (multi-GPU, 32B) — on
the native PyTorch (Cosmos Framework) path, the Diffusers modular pipeline, and the
OpenAI-compatible TensorRT-LLM and vLLM-Omni server paths.
Sample assets under assets/ cover spatial control signals paired with
prompt.json files:
- Edge (Canny) — edge map control plus caption.
- Blur — blurred-reference control plus caption.
- Depth — depth map control plus caption.
- Segmentation — segmentation map control plus caption.
- World scenario (WSM) — world-scenario map control plus caption.
- Multi-control — two or more hints; Cosmos Framework also supports per-hint weights.
Cosmos Framework, TensorRT-LLM, and vLLM-Omni support multi-control transfer. Per-hint weighting is supported only by Cosmos Framework; the serving backends accept multiple unweighted controls. Diffusers also accepts multiple precomputed controls without per-hint weights.
Environment setup is centralized in the shared Cosmos3 cookbooks environment setup guide.
Transfer Definition¶
Video transfer generates a target clip from a prompt.json caption and one or more
spatial control signals. The Framework path uses model_mode video2video in a local JSON spec.
TensorRT-LLM uses POST /v1/videos/sync. A raw source used to derive edge or
blur is multipart video_reference; precomputed controls are carried directly
under their extra_params hint and do not need a top-level reference.
The vLLM-Omni path uses POST /v1/videos/sync and passes one or more hint keys (edge, blur,
depth, seg, or wsm) inside extra_params. Cosmos Framework accepts pre-computed
control videos (control_path) or derives active controls from a raw source video
(vision_path). With vLLM-Omni, pass pre-computed controls through control_path; edge
and blur controls can also be derived from an uploaded input_reference. Output frame
count and geometry come from the control video; see the spec field reference for how
fps and aspect_ratio are resolved. All examples share assets/negative_prompt.json
for the negative caption.
| Control | Asset folder | Inference input | Generation duration |
|---|---|---|---|
| Edge (Canny) | assets/edge/ |
control_edge.mp4 + prompt.json |
121 frames @ 30 FPS |
| Blur | assets/blur/ |
control_blur.mp4 + prompt.json |
121 frames @ 30 FPS |
| Depth | assets/depth/ |
control_depth.mp4 + prompt.json |
121 frames @ 30 FPS |
| Segmentation | assets/seg/ |
control_seg.mp4 + prompt.json |
121 frames @ 30 FPS |
| World scenario (WSM) | assets/wsm/ |
control_wsm.mp4 + prompt.json |
100 frames @ 10 FPS |
| Multi-control | assets/multi_control/ |
vision_path + multiple hints (Framework example) |
121 frames @ 30 FPS |
Transfer inference is selected automatically when any hint key is present in the
Framework spec or in vLLM-Omni extra_params.
The same spec files are used for both Nano and Super — model selection is controlled
entirely by --checkpoint-path.
Run with Cosmos Framework¶
Quickstart — Single-control transfer¶
Set up the environment: Cosmos Framework setup.
Run the commands below inside the cosmos container (e.g. pytorch:25.09-py3) — the same
environment used to install the venv and run the notebook. The commands mirror the notebook
exactly: cd into the framework repo first, then invoke the venv's Python or torchrun
(the system Python does not have cosmos_framework).
# Set once — the cosmos-framework repo root (contains .venv/ and pyproject.toml).
# In this cosmos checkout: packages/cosmos3 (or packages/cosmos-framework).
export COSMOS_FRAMEWORK=/path/to/cosmos-framework # e.g. <cosmos_root>/packages/cosmos3
export TRANSFER_ROOT=$(pwd)/cookbooks/cosmos3/generator/transfer
# NGC containers bundle libtorch in LD_LIBRARY_PATH which conflicts with Triton/CUDA.
unset LD_LIBRARY_PATH
Cosmos3-Nano (single GPU)¶
cd "$COSMOS_FRAMEWORK"
# edge — replace edge.json with blur.json / depth.json / seg.json / wsm.json for other controls
CUDA_VISIBLE_DEVICES=0 \
.venv/bin/python -m cosmos_framework.scripts.inference \
--parallelism-preset=latency \
-i "$TRANSFER_ROOT/specs/edge.json" \
-o "$TRANSFER_ROOT/outputs/Cosmos3-Nano/" \
--checkpoint-path Cosmos3-Nano \
--seed 2026
Cosmos3-Super (multi-GPU)¶
cd "$COSMOS_FRAMEWORK"
# edge — replace edge.json with other control specs as needed
CUDA_VISIBLE_DEVICES=0,1,2,3 \
.venv/bin/torchrun --nproc-per-node=4 \
--master-addr=127.0.0.1 --master-port=29500 \
-m cosmos_framework.scripts.inference \
--parallelism-preset=latency \
-i "$TRANSFER_ROOT/specs/edge.json" \
-o "$TRANSFER_ROOT/outputs/Cosmos3-Super/" \
--checkpoint-path Cosmos3-Super \
--seed 2026
| Cosmos3-Nano | Cosmos3-Super | |
|---|---|---|
--checkpoint-path |
Cosmos3-Nano |
Cosmos3-Super |
| Launcher | .venv/bin/python (from framework root) |
.venv/bin/torchrun --nproc-per-node=<N> (from framework root) |
--parallelism-preset |
latency |
latency |
| GPUs | 1 | 4+ |
The input spec sets prompt_path and a hint block with control_path pointing at the
checked-in assets under assets/ via paths relative to specs/.
Outputs are written under the directory passed to -o, with one subdirectory per sample
name, e.g. outputs/Cosmos3-Nano/transfer_edge/vision.mp4.
Notebook (self-contained)¶
run_video_transfer_with_cosmos_framework.ipynb
is a self-contained tutorial: it installs all dependencies (system packages, framework
clone, Python venv via uv), authenticates with Hugging Face, and runs all six controls
with previews.
- Open the notebook and edit §2 (Configure) — paste your
HF_TOKENand optionally set cache/output paths. - Run §9–§13 for Cosmos3-Nano single-control (single GPU), §14–§18 for Cosmos3-Super single-control (multi-GPU), or §19 for multi-control (Nano). No model flag needed — each section uses its matching checkpoint explicitly.
To execute headlessly:
cd .agents/skills/cookbooks/cosmos3/generator/transfer
jupyter execute run_video_transfer_with_cosmos_framework.ipynb
Outputs land under outputs/notebooks/<model>/transfer_<control>/vision.mp4.
Run with Diffusers¶
Quickstart¶
Set up the environment: Diffusers setup. Transfer is
reachable only through the modular pipeline, which takes precomputed control videos as
control_videos={hint: frames}:
import json
from pathlib import Path
import torch
from diffusers import Cosmos3OmniModularPipeline
from diffusers.utils import export_to_video, load_video
transfer_root = Path(".agents/skills/cookbooks/cosmos3/generator/transfer")
prompt = json.dumps(json.load(open(transfer_root / "assets/depth/prompt.json")))
negative = json.dumps(json.load(open(transfer_root / "assets/negative_prompt.json")))
pipe = Cosmos3OmniModularPipeline.from_pretrained("nvidia/Cosmos3-Nano", torch_dtype=torch.bfloat16)
pipe.load_components(torch_dtype=torch.bfloat16)
pipe.enable_safety_checker()
pipe.to("cuda")
videos = pipe(
prompt=prompt,
negative_prompt=negative,
control_videos={"depth": load_video(str(transfer_root / "assets/depth/control_depth.mp4"))},
control_guidance=1.5,
num_frames=121,
num_video_frames_per_chunk=121,
num_conditional_frames=1,
height=720,
width=1280,
fps=30.0,
num_inference_steps=50,
guidance_scale=3.0,
generator=torch.Generator(device="cuda").manual_seed(2026),
output="videos",
)
export_to_video(videos, "/tmp/cosmos3_transfer_depth.mp4", fps=30, macro_block_size=1)
To run Cosmos3-Super instead, load the larger checkpoint:
Cosmos3OmniModularPipeline.from_pretrained("nvidia/Cosmos3-Super", ...).
Diffusers notebook walkthrough¶
run_video_transfer_with_diffusers.ipynb is
the full tutorial for the Diffusers backend: it provisions a dedicated venv, then runs
edge, blur, depth, segmentation, and world-scenario-map transfer on Cosmos3-Nano followed
by the same five controls on Cosmos3-Super. It reads the same specs/ files and
reuses the previews from preview_helpers.py, writing outputs to
outputs/notebooks/diffusers/<model>/transfer_<control>/vision.mp4.
Run with TensorRT-LLM¶
Quickstart¶
Set up and launch Nano or Super as described in the shared
TensorRT-LLM setup, including the
server-side NLTK data setup.
Keep NLTK_DATA exported in the server's shell. TensorRT-LLM
accepts a raw source video as multipart video_reference when edge or blur will
be computed on the server. The checked-in assets are already precomputed
controls, so this example base64-encodes the control inside its hint and does
not send a top-level reference. The server decodes inline media at the HTTP
boundary before validating and dispatching the request.
import base64
import json
from pathlib import Path
import requests
transfer_root = Path(".agents/skills/cookbooks/cosmos3/generator/transfer")
control_path = transfer_root / "assets/depth/control_depth.mp4"
prompt = json.dumps(json.load(open(transfer_root / "assets/depth/prompt.json")))
negative = json.dumps(json.load(open(transfer_root / "assets/negative_prompt.json")))
extra_params = {
"use_resolution_template": False,
"use_duration_template": False,
"use_system_prompt": False,
"use_guardrails": True,
"flow_shift": 10.0,
"depth": {
"control": base64.b64encode(control_path.read_bytes()).decode("ascii")
},
"control_guidance": 1.5,
"num_video_frames_per_chunk": 121,
"num_conditional_frames": 1,
"num_first_chunk_conditional_frames": 0,
"share_vision_temporal_positions": True,
"emphasize_control_in_prompt": False,
"max_frames": 121,
}
response = requests.post(
"http://localhost:8000/v1/videos/sync",
json={
"prompt": prompt,
"negative_prompt": negative,
"size": "1280x720",
"num_frames": 121,
"fps": 30,
"num_inference_steps": 50,
"guidance_scale": 3.0,
"max_sequence_length": 4096,
"seed": 2026,
"format": "mp4",
"response_format": "file",
"extra_params": extra_params,
},
headers={"Accept": "video/mp4"},
)
response.raise_for_status()
if (
"video/mp4" not in response.headers.get("content-type", "")
or response.content[4:8] != b"ftyp"
):
raise RuntimeError("TensorRT-LLM did not return browser-compatible MP4")
Path("/tmp/cosmos3_transfer_depth_trtllm.mp4").write_bytes(response.content)
Only edge and blur can be generated from a raw uploaded source ("edge": true
or "blur": true); depth, segmentation, and WSM always require precomputed
control media. Precomputed edge and blur are also accepted. Use
use_guardrails, not vLLM-Omni's guardrails, and send encoded control bytes
rather than a server-local control_path. When neither output dimension is
specified, TensorRT-LLM chooses the nearest supported bucket from the source or
first precomputed control's aspect ratio. The checked-in blur example explicitly
requests its native 4:3 bucket, 1104×832; the other examples request
1280×720. All preserve their native frame count/fps, and WSM uses 100 frames
at 10 fps. /v1/videos/generations remains only as a deprecated alias of the
canonical blocking /v1/videos/sync route.
TensorRT-LLM notebook walkthrough¶
run_video_transfer_with_trt_llm.ipynb
runs edge, blur, depth, segmentation, and WSM against an already-running Nano
or Super server. It reuses the checked-in media and captions, shows the complete
mode matrix, validates the JSON/base64 control request contract, and previews the
synchronous encoded-video responses.
Run with vLLM-Omni¶
Quickstart¶
vLLM-Omni accepts multiple control hints in one request, but does not support
the per-hint weight field available in Cosmos Framework.
Set up the environment and start the server:
vLLM-Omni setup. Transfer controls are available from
vLLM-Omni main and the released vllm/vllm-omni:cosmos3 container. Check the current
Cosmos3-Nano recipe
before selecting an image. For Docker, run the command from the cookbook root (.agents/skills) so
it is mounted at /workspace and the server runs from that directory inside the
container:
export COSMOS3_WORKDIR="$(pwd)"
export COSMOS3_HOST_PORT=8000
The transfer examples send repo-local control_path strings to the server. For
Docker, those paths must be visible from the server working directory. With the
shared Docker setup, the checked-in depth control video is:
cookbooks/cosmos3/generator/transfer/assets/depth/control_depth.mp4
If your server does not run from the cookbook root, start it from there or
adjust control_path to a path the server process can read.
Transfer requests should also pass the spec resolution inside extra_params.
Cosmos3 transfer bucket selection reads extra_params.resolution and the
control/input aspect ratio; set the video API size field to the matching
<width>x<height> value for a consistent request.
Send a depth-transfer request:
import json
from pathlib import Path
import requests
transfer_root = Path(".agents/skills/cookbooks/cosmos3/generator/transfer")
prompt = json.dumps(json.load(open(transfer_root / "assets/depth/prompt.json")))
negative = json.dumps(json.load(open(transfer_root / "assets/negative_prompt.json")))
control_path = transfer_root / "assets/depth/control_depth.mp4"
response = requests.post(
"http://localhost:8000/v1/videos/sync",
data={
"prompt": prompt,
"negative_prompt": negative,
"size": "1280x720",
"num_frames": "121",
"fps": "30",
"num_inference_steps": "50",
"guidance_scale": "3.0",
"flow_shift": "10.0",
"seed": "2026",
"extra_params": json.dumps(
{
"use_resolution_template": False,
"use_duration_template": False,
"guardrails": True,
"depth": {"control_path": control_path.as_posix()},
"resolution": "720",
"control_guidance": 1.5,
"num_video_frames_per_chunk": 121,
"max_frames": 121,
}
),
},
headers={"Accept": "video/mp4"},
)
response.raise_for_status()
Path("/tmp/cosmos3_transfer_depth.mp4").write_bytes(response.content)
Spec field reference¶
A representative spec (specs/edge.json):
{
"name": "transfer_edge",
"model_mode": "video2video",
"resolution": "720",
"aspect_ratio": "16,9",
"num_frames": 121,
"fps": 30,
"num_video_frames_per_chunk": 121,
"num_conditional_frames": 1,
"num_first_chunk_conditional_frames": 0,
"share_vision_temporal_positions": true,
"guidance": 3.0,
"control_guidance": 1.5,
"negative_prompt_file": "../assets/negative_prompt.json",
"prompt_path": "../assets/edge/prompt.json",
"edge": {
"control_path": "../assets/edge/control_edge.mp4",
"preset_edge_threshold": "medium"
}
}
Key fields:
-
resolution— target resolution (e.g.720for 720p). -
aspect_ratio— aspect ratio of the control video; together withresolutiondetermines the spatial dimensions (e.g.720+16,9→ 1280 × 720). -
fps— model conditioning signal and playback rate of the saved output video. Should match the native fps of the control video. -
num_frames— number of video frames.
Cookbook entrypoints¶
run_video_transfer_with_cosmos_framework.ipynb— self-contained notebook: §9–§13 Nano single-control, §14–§18 Super single-control, §19 multi-control (Nano). Edit §2, run top-to-bottom.run_video_transfer_with_diffusers.ipynb— full tutorial for the Diffusers modular pipeline: five single-control transfers on Nano, then the same five on Super, driven by the same specs.run_video_transfer_with_trt_llm.ipynb— five single-control transfers through TensorRT-LLM's synchronous VisualGen API, using base64-encoded precomputed controls in JSONextra_params.run_video_transfer_with_vllm_omni.ipynb— full tutorial against an already-running vLLM-Omni server: endpoint checks, repo-local control paths, five single-control transfer requests, and compact previews. The API also accepts unweighted multi-control requests by including multiple hint blocks inextra_params.specs/— checked-in Framework input JSON per control (paths relative tospecs/). Shared by both Nano and Super.
Troubleshooting¶
If inference fails inside attention with a NATTEN/libnatten error, verify that the active Python
environment uses a matching Torch and NATTEN build. Avoid mixing a container-provided Torch/NATTEN
stack with packages from ~/.local or another venv. In containerized environments,
PYTHONNOUSERSITE=1 can help prevent user-site packages from shadowing the container stack.