Diffusers documentation
Cosmos 3
Cosmos 3
NVIDIA Cosmos 3 es un modelo de base unificado para el mundo (WFM) para la IA física: un único modelo omnimodal que combina la generación de mundos, el razonamiento físico y la generación de acciones. Reemplaza a los modelos separados Predict, Reason y Transfer de las versiones anteriores de Cosmos: ya sea que estés desarrollando para robótica, vehículos autónomos o espacios inteligentes, Cosmos 3 te ofrece una única base para simular y comprender el mundo físico.
Lo que se incluye en esta versión:
- Modelos en el Hugging Face Hub con tarjetas de modelo y licencias
- Integración de Cosmos 3 Diffusers para pipelines de generación (esta página)
- Scripts de post-entrenamiento para el ajuste fino de Cosmos 3 con tus propios datos
- Conjuntos de datos abiertos de generación de datos sintéticos (SDG) para IA física
Novedades en Cosmos 3
El mayor cambio respecto a las versiones anteriores de Cosmos es que Cosmos 3 es un omni-model, construido sobre una arquitectura Mixture-of-Transformers (MoT). Anteriormente, los desarrolladores trabajaban con modelos separados para la generación de mundos (Predict), la generación controlada (Transfer), la comprensión de escenas (Reason) y la generación de políticas de acción. Cosmos 3 unifica todos estos aspectos en un solo modelo que razona y genera a través de modalidades en una única pasada hacia adelante.
A partir de un modelo puedes:
- Genera mundos de video físicamente plausibles a partir de texto, imágenes o entradas de acción (generación de video a partir de imagen, generación de video a partir de texto, generación de video condicionado por acción).
- Razonar sobre propiedades físicas como el movimiento, la causalidad y las relaciones espaciales.
- Predice secuencias futuras de video y acciones a partir del estado actual.
- Transfiera escenas entre puntos de vista y condiciones con control estructural (próximamente).
Por debajo, una única instancia de Cosmos3OmniTransformer ejecuta un modelo de lenguaje estilo Qwen en paralelo con una ruta de generación por difusión: los tokens de texto fluyen a través de un flujo causal de “comprensión”, mientras que los latentes de video y sonido fluyen a través de un flujo de “generación” con atención bidireccional, unidos mediante un RoPE multimodal 3D. Consulte el artículo de la plataforma Cosmos World Foundation Model para conocer el contexto arquitectónico.
Puntos de control disponibles
Se publican dos puntos de control en el Hub: nvidia/Cosmos3-Nano (más pequeño, más rápido) y nvidia/Cosmos3-Super (más grande, de mayor calidad). La misma clase de pipeline admite texto a imagen, texto a video, imagen a video y (con un punto de control con capacidad de sonido) texto+imagen a video con sonido: elige un repositorio y usa la pestaña por modelo en cada flujo de trabajo a continuación.
Asegúrate de consultar la guía de Schedulers para aprender a explorar el equilibrio entre la velocidad y la calidad del scheduler, y consulta la sección reutilizar componentes entre pipelines para aprender a cargar eficientemente los mismos componentes en múltiples pipelines.
Denoising mixto FP8 W8A8/W8A16
Los puntos de control FP8 oficiales de ModelOpt se encuentran en la revisión fp8 del Hub (por ejemplo, nvidia/Cosmos3-Nano con revision="fp8").
Todos estos puntos de control se cuantizan de la misma manera. W8A8 utiliza pesos de 8 bits y activaciones de 8 bits (el GEMM de ModelOpt restaurado). W8A16 reutiliza esos mismos pesos de 8 bits pero omite la cuantización de activaciones: el peso FP8 se descuantiza y se ejecuta una lineal estándar sobre activaciones BF16/FP16/FP32.
Ejecutar W8A8 en cada paso puede provocar parpadeos visibles en la generación de video multipaso. Por lo tanto, los puntos de control FP8 de video Nano / Super / Super-I2V declaran un plan en transformer/config.json: W8A16 en los primeros 3 y últimos 3 pasos, W8A8 en el medio. Diffusers lee esas cantidades del punto de control en lugar de codificarlas de forma fija. La precisión se elige una vez por paso del programador para que las llamadas cond/uncond de guía libre de clasificador coincidan.
La generación de imágenes y los puntos de control destilados de pocos pasos no presentan ese parpadeo, por lo que Super-T2I y los repositorios destilados de 4 pasos en FP8 no declaran ningún programa y mantienen W8A8 en cada paso. El programa es exclusivo de ModelOpt FP8: otros backends de cuantización (por ejemplo, TorchAO) conservan sus forwards nativos.
Cargue la revisión fp8 con la misma ruta de restauración que la guía de ModelOpt (revision="fp8" ya incluye la configuración de cuantización). La precisión mixta sigue automáticamente al punto de control:
import torch
from diffusers import Cosmos3OmniPipeline
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Nano",
revision="fp8",
dtype=torch.bfloat16,
device_map="cuda",
)
result = pipe(prompt="...", num_inference_steps=35)Dos opciones en el momento de la generación:
- Por defecto (
mixed_precision_format=None): si el checkpoint declaradiffusion_step_policy, se ejecuta W8A16 en los primeros/últimos N pasos y W8A8 nativo en el medio. Esa es la receta prevista para video FP8 de varios pasos (menos parpadeo que todo W8A8). Los modelos FP8 destilados de 4 pasos y Super-T2I FP8 omiten la política, por lo que el valor por defecto ya es todo W8A8. mixed_precision_format="none": mantiene cada paso en W8A8 nativo. Es más rápido, ya que W8A16 es dequant +torch.nn.functional.linearen lugar del GEMM FP8 restaurado, pero el video de varios pasos puede parpadear. Usa esto para comparar el schedule o para igualar una línea base totalmente cuantizada.
En una estación de trabajo Blackwell, Cosmos3-Nano @fp8 a 720×1280 / 35 pasos fue aproximadamente un 27% más lento (T2I) y un 13% más lento (T2V de 49 fotogramas) con el programa mixto predeterminado que con "none". Esas cifras no son una garantía de rendimiento. Pasa "fp8" solo para forzar el programa de primeros/últimos N en un punto de control FP8 de ModelOpt que no tenga una política.
Ampliación de prompts
Cosmos 3 se entrenó con descripciones largas y muy detalladas. Para obtener la mejor calidad, los prompts de texto cortos deben ampliarse a una estructura JSON específica antes de pasarlos a la pipeline. El amplificador se encuentra en el paquete cosmos-framework.
Comience con un prompt breve en texto plano y guárdelo en assets/prompt.txt. Para el ejemplo de texto a video a continuación, el prompt original es “A robotic arm is cleaning a plate in a kitchen”:
mkdir -p assets
echo "A robotic arm is cleaning a plate in a kitchen" > assets/prompt.txtLuego, instala el framework y ejecuta el upsampler. El ejemplo siguiente realiza el upsampling para texto a video usando Opus-4.6:
git clone https://github.com/NVIDIA/cosmos-framework.git packages/cosmos-framework
pip install -e packages/cosmos-framework
export PROMPT_UPSAMPLER_ENDPOINT_URL="https://api.anthropic.com/v1/"
export PROMPT_UPSAMPLER_MODEL_NAME="claude-opus-4-6"
export PROMPT_UPSAMPLER_API_TOKEN="<your_token>"
python -m cosmos_framework.inference.prompt_upsampling \
--input assets/prompt.txt \
--output assets/example_t2v_prompt.json \
--mode text2video \
--endpoint-url "${PROMPT_UPSAMPLER_ENDPOINT_URL}" \
--model "${PROMPT_UPSAMPLER_MODEL_NAME}" \
--api-token "${PROMPT_UPSAMPLER_API_TOKEN}" \
--resolution 720 \
--aspect-ratio "16,9"Cambia --mode para que coincida con el flujo de trabajo que estás utilizando (text2image, text2video, image2video). El comando escribe los prompts ampliados en el archivo --output como un array JSON (un objeto por cada línea no vacía en --input); pasa una ruta .jsonl en su lugar para obtener un objeto JSON por línea. Para image2video, también debes proporcionar la imagen de condicionamiento mediante --image-url (una URL o ruta local) o --image-list (una imagen por prompt).
Se proporcionan un prompt positivo pre-ampliado (assets/example_t2v_prompt.json) y un prompt negativo (assets/negative_prompt.json) para mayor comodidad, y se utilizan en los ejemplos de generación a continuación. Los ejemplos cargan estos archivos JSON y los pasan a la pipeline como cadenas JSON mediante json.dumps(...).
Texto a video
Generación de múltiples fotogramas condicionada únicamente en texto. Elija num_frames en función de la duración objetivo: el valor predeterminado num_frames=189 produce ≈ 7,9 s a 24 FPS. El prompt y el prompt negativo se leen de los archivos ampliados con JSON descritos en Ampliación de prompts.
import json
import torch
from diffusers import Cosmos3OmniPipeline
from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
from diffusers.utils import export_to_video
# JSON-upsampled positive and negative prompts (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_t2v_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt.json"))
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Nano", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
pipe.scheduler = UniPCMultistepScheduler.from_config(
pipe.scheduler.config, flow_shift=10.0, use_karras_sigmas=False
)
result = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
num_frames=189,
height=720,
width=1280,
num_inference_steps=35,
guidance_scale=6.0,
fps=24.0,
)
# macro_block_size=1 allows arbitrary frame sizes (Cosmos3 outputs are not always divisible by 16).
export_to_video(result.video, "cosmos3_t2v.mp4", fps=24, macro_block_size=1)import json
import torch
from diffusers import Cosmos3OmniPipeline
from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
from diffusers.utils import export_to_video
# JSON-upsampled positive and negative prompts (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_t2v_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt.json"))
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Super", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
pipe.scheduler = UniPCMultistepScheduler.from_config(
pipe.scheduler.config, flow_shift=10.0, use_karras_sigmas=False
)
result = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
num_frames=189,
height=720,
width=1280,
num_inference_steps=35,
guidance_scale=6.0,
fps=24.0,
)
# macro_block_size=1 allows arbitrary frame sizes (Cosmos3 outputs are not always divisible by 16).
export_to_video(result.video, "cosmos3_t2v.mp4", fps=24, macro_block_size=1)Texto a imagen
Generación de un solo fotograma. El modelo se condiciona únicamente en el prompt de texto; pase num_frames=1. Use --mode text2image para generar el prompt JSON.
import json
import torch
from diffusers import Cosmos3OmniPipeline
# JSON-upsampled prompt (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_t2i_prompt.json"))
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Nano", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
result = pipe(prompt=json.dumps(json_prompt), num_frames=1, height=720, width=1280)
result.video[0].save("cosmos3_t2i.jpg", format="JPEG", quality=85)import json
import torch
from diffusers import Cosmos3OmniPipeline
# JSON-upsampled prompt (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_t2i_prompt.json"))
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Super", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
result = pipe(prompt=json.dumps(json_prompt), num_frames=1, height=720, width=1280)
result.video[0].save("cosmos3_t2i.jpg", format="JPEG", quality=85)Imagen a video
Pase una imagen de condicionamiento mediante image=. El pipeline ancla el fotograma 0 a la imagen proporcionada y desruidifica el resto. La imagen se redimensiona preservando su relación de aspecto, se recorta por el centro al tamaño de salida solicitado y se normaliza con redondeo equivalente a uint8. Use --mode image2video para generar el prompt en JSON.
import json
import torch
from diffusers import Cosmos3OmniPipeline
from diffusers.utils import export_to_video, load_image
# JSON-upsampled positive and negative prompts (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_i2v_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt_i2v.json"))
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Nano", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
image = load_image(
"https://github.com/nvidia-cosmos/cosmos-dependencies/releases/download/assets/robot_153.jpg"
)
result = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
image=image,
num_frames=189,
height=720,
width=1280,
fps=24.0,
)
# macro_block_size=1 allows arbitrary frame sizes (Cosmos3 outputs are not always divisible by 16).
export_to_video(result.video, "cosmos3_i2v.mp4", fps=24, macro_block_size=1)import json
import torch
from diffusers import Cosmos3OmniPipeline
from diffusers.utils import export_to_video, load_image
# JSON-upsampled positive and negative prompts (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_i2v_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt_i2v.json"))
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Super", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
image = load_image(
"https://github.com/nvidia-cosmos/cosmos-dependencies/releases/download/assets/robot_153.jpg"
)
result = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
image=image,
num_frames=189,
height=720,
width=1280,
fps=24.0,
)
# macro_block_size=1 allows arbitrary frame sizes (Cosmos3 outputs are not always divisible by 16).
export_to_video(result.video, "cosmos3_i2v.mp4", fps=24, macro_block_size=1)Video a video
Pase un clip de condicionamiento mediante video= (por ejemplo, desde load_video). El pipeline ancla los marcos latentes iniciales dados por condition_frame_indexes_vision (por defecto [0, 1]) al clip y desruidifica el resto. Use condition_video_keep ("first" o "last") para elegir desde qué extremo de un clip fuente más largo se toman los marcos de condicionamiento. Como en los otros modos, el prompt debe seguir la estructura JSON descriptiva descrita en Prompt upsampling.
import json
import torch
from diffusers import Cosmos3OmniPipeline
from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
from diffusers.utils import export_to_video, load_video
# JSON-upsampled positive and negative prompts (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_v2v_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt_i2v.json"))
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Nano", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
pipe.scheduler = UniPCMultistepScheduler.from_config(
pipe.scheduler.config, flow_shift=10.0, use_karras_sigmas=False
)
video = load_video(
"https://github.com/nvidia-cosmos/cosmos-dependencies/raw/refs/heads/assets/cosmos3/inputs/vision/robot_pouring.mp4"
)
result = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
video=video,
condition_frame_indexes_vision=[0, 1],
condition_video_keep="first",
num_frames=189,
height=720,
width=1280,
num_inference_steps=35,
guidance_scale=6.0,
fps=24.0,
)
# macro_block_size=1 allows arbitrary frame sizes (Cosmos3 outputs are not always divisible by 16).
export_to_video(result.video, "cosmos3_v2v.mp4", fps=24, macro_block_size=1)import json
import torch
from diffusers import Cosmos3OmniPipeline
from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
from diffusers.utils import export_to_video, load_video
# JSON-upsampled positive and negative prompts (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_v2v_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt_i2v.json"))
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Super", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
pipe.scheduler = UniPCMultistepScheduler.from_config(
pipe.scheduler.config, flow_shift=10.0, use_karras_sigmas=False
)
video = load_video(
"https://github.com/nvidia-cosmos/cosmos-dependencies/raw/refs/heads/assets/cosmos3/inputs/vision/robot_pouring.mp4"
)
result = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
video=video,
condition_frame_indexes_vision=[0, 1],
condition_video_keep="first",
num_frames=189,
height=720,
width=1280,
num_inference_steps=35,
guidance_scale=6.0,
fps=24.0,
)
# macro_block_size=1 allows arbitrary frame sizes (Cosmos3 outputs are not always divisible by 16).
export_to_video(result.video, "cosmos3_v2v.mp4", fps=24, macro_block_size=1)Video a video con sonido
Cuando el checkpoint incluye un sound_tokenizer, añade enable_sound=True a la llamada de video a video para generar simultáneamente una pista de audio sincronizada. La forma de onda se devuelve junto con el video y puede mezclarse en el MP4 con encode_video().
import json
import torch
from diffusers import Cosmos3OmniPipeline
from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
from diffusers.utils import encode_video, load_video
# JSON-upsampled positive and negative prompts (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_v2v_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt_i2v.json"))
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Nano", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
pipe.scheduler = UniPCMultistepScheduler.from_config(
pipe.scheduler.config, flow_shift=10.0, use_karras_sigmas=False
)
video = load_video(
"https://github.com/nvidia-cosmos/cosmos-dependencies/raw/refs/heads/assets/cosmos3/inputs/vision/robot_pouring.mp4"
)
result = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
video=video,
condition_frame_indexes_vision=[0, 1],
condition_video_keep="first",
num_frames=189,
height=720,
width=1280,
fps=24.0,
enable_sound=True,
)
encode_video(
result.video,
fps=24,
audio=result.sound,
audio_sample_rate=pipe.sound_tokenizer.config.sampling_rate,
output_path="cosmos3_v2v_with_sound.mp4",
)import json
import torch
from diffusers import Cosmos3OmniPipeline
from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
from diffusers.utils import encode_video, load_video
# JSON-upsampled positive and negative prompts (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_v2v_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt_i2v.json"))
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Super", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
pipe.scheduler = UniPCMultistepScheduler.from_config(
pipe.scheduler.config, flow_shift=10.0, use_karras_sigmas=False
)
video = load_video(
"https://github.com/nvidia-cosmos/cosmos-dependencies/raw/refs/heads/assets/cosmos3/inputs/vision/robot_pouring.mp4"
)
result = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
video=video,
condition_frame_indexes_vision=[0, 1],
condition_video_keep="first",
num_frames=189,
height=720,
width=1280,
fps=24.0,
enable_sound=True,
)
encode_video(
result.video,
fps=24,
audio=result.sound,
audio_sample_rate=pipe.sound_tokenizer.config.sampling_rate,
output_path="cosmos3_v2v_with_sound.mp4",
)Texto a video con sonido
Cuando el checkpoint incluye un sound_tokenizer, pase enable_sound=True para generar de forma conjunta una pista de audio sincronizada. La forma de onda se devuelve junto con el video y puede mezclarse en el MP4 con encode_video().
Esta es la misma llamada que el ejemplo de texto a video anterior, con enable_sound=True añadido:
import json
import torch
from diffusers import Cosmos3OmniPipeline
from diffusers.utils import encode_video
# JSON-upsampled positive and negative prompts (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_t2v_sound_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt.json"))
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Nano", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
result = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
num_frames=189,
height=720,
width=1280,
fps=24.0,
enable_sound=True,
)
encode_video(
result.video,
fps=24,
audio=result.sound,
audio_sample_rate=pipe.sound_tokenizer.config.sampling_rate,
output_path="cosmos3_with_sound.mp4",
)import json
import torch
from diffusers import Cosmos3OmniPipeline
from diffusers.utils import encode_video
# JSON-upsampled positive and negative prompts (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_t2v_sound_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt.json"))
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Super", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
result = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
num_frames=189,
height=720,
width=1280,
fps=24.0,
enable_sound=True,
)
encode_video(
result.video,
fps=24,
audio=result.sound,
audio_sample_rate=pipe.sound_tokenizer.config.sampling_rate,
output_path="cosmos3_with_sound.mp4",
)Generación condicionada por acción
Action runs agrupa cada entrada específica de la acción en un CosmosActionCondition que se pasa mediante el argumento action en lugar de los argumentos de nivel superior image / video / height / width. Establezca resolution_tier (256/480/704/720) cerca de la resolución nativa del video de entrada; este parámetro selecciona el lienzo de condicionamiento. Cosmos 3 admite tres modos de acción: policy, forward_dynamics y inverse_dynamics. policy y forward_dynamics solo se condicionan en el primer fotograma (por lo que tanto una image como un video funcionan), mientras que inverse_dynamics requiere un video. El video de condicionamiento para una ejecución de acción se establece en action.video (o action.image), no en el argumento de nivel superior video de la pipeline.
Pase una descripción de tarea simple como prompt y seleccione la cámara con action.view_point (por defecto "ego_view"; también "third_person_view", "wrist_view", "concat_view"). El pipeline convierte estos elementos en la descripción JSON estructurada con la que se entrenó el modelo, por lo que los prompts de acción no deben ser ampliados por un LLM.
Política de acción
La generación de políticas de acción predice los tokens de video y de acción futuros a partir del primer fotograma de observación, el prompt de texto y los metadatos del dominio de acción. El ejemplo siguiente utiliza el dominio del robot Bridge y escribe el trozo de acción predicho en JSON en el espacio de acción normalizado por el modelo.
import json
import torch
from diffusers import Cosmos3OmniPipeline, CosmosActionCondition
from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
from diffusers.utils import export_to_video, load_video
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Nano", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
pipe.scheduler = UniPCMultistepScheduler.from_config(
pipe.scheduler.config, flow_shift=10.0, use_karras_sigmas=False
)
prompt = "Put the pot to the left of the purple item."
video = load_video(
"https://github.com/nvidia-cosmos/cosmos-dependencies/raw/refs/heads/assets/cosmos3/inputs/action/bridge_20260501_0.mp4"
)
result = pipe(
prompt=prompt,
action=CosmosActionCondition(
mode="policy",
chunk_size=16,
domain_name="bridge_orig_lerobot",
resolution_tier=480,
video=video,
view_point="ego_view",
),
fps=5,
num_inference_steps=30,
guidance_scale=1.0,
use_system_prompt=False,
)
# macro_block_size=1 allows arbitrary frame sizes (Cosmos3 outputs are not always divisible by 16).
export_to_video(result.video, "sample.mp4", fps=5, macro_block_size=1)
if result.action is not None:
with open("sample_action.json", "w") as f:
json.dump(result.action[0].tolist(), f)import json
import torch
from diffusers import Cosmos3OmniPipeline, CosmosActionCondition
from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
from diffusers.utils import export_to_video, load_video
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Super", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
pipe.scheduler = UniPCMultistepScheduler.from_config(
pipe.scheduler.config, flow_shift=10.0, use_karras_sigmas=False
)
prompt = "Put the pot to the left of the purple item."
video = load_video(
"https://github.com/nvidia-cosmos/cosmos-dependencies/raw/refs/heads/assets/cosmos3/inputs/action/bridge_20260501_0.mp4"
)
result = pipe(
prompt=prompt,
action=CosmosActionCondition(
mode="policy",
chunk_size=16,
domain_name="bridge_orig_lerobot",
resolution_tier=480,
video=video,
view_point="ego_view",
),
fps=5,
num_inference_steps=30,
guidance_scale=1.0,
use_system_prompt=False,
)
# macro_block_size=1 allows arbitrary frame sizes (Cosmos3 outputs are not always divisible by 16).
export_to_video(result.video, "sample.mp4", fps=5, macro_block_size=1)
if result.action is not None:
with open("sample_action.json", "w") as f:
json.dump(result.action[0].tolist(), f)SeaCache
SeaCache está desactivado de forma predeterminada. Cosmos 3 permite activarlo explícitamente con SeaCacheConfig. SeaCache reutiliza los residuos del transformer cuando el indicador Spectral-Evolution-Aware cambia lentamente, reduciendo el número de ejecuciones completas del transformer. Calcula el indicador a partir de los latentes visuales crudos, incluyendo los fotogramas de condicionamiento limpios para la generación de imagen a video. Actívalo en el transformer con callbacks de metadatos del programador desde el pipeline:
import torch
from diffusers import Cosmos3OmniPipeline, SeaCacheConfig
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Nano", dtype=torch.bfloat16, device_map="cuda"
)
pipe.transformer.enable_cache(SeaCacheConfig(threshold=0.2, max_consecutive_cached=2))La misma API a nivel de modelo funciona con Cosmos3OmniPipeline, Cosmos3OmniModularPipeline y Cosmos3DistilledModularPipeline. SeaCache es aproximado y puede alterar las salidas generadas. Desactívalo con pipe.transformer.disable_cache() cuando necesites que cada paso de desruido ejecute el transformador completo. El estado de la caché se
reinicia después de cada llamada a la pipeline, y las ramas de guía condicional e incondicional mantienen historiales independientes.
Cosmos 3 mantiene la compuerta SeaCache fuera de sus capas de decodificador repetidas, por lo que es compatible con la compilación regional. Compila las capas después de habilitar la caché:
pipe.transformer.compile_repeated_blocks(fullgraph=True)SeaCache también es compatible con los helpers de paralelismo de contexto Ulysses de Cosmos 3 y de paralelismo de tensores basado en DTensor documentados a continuación. Las decisiones de caché se sincronizan entre rangos. No se afirma el soporte para la compilación del modelo completo ni para otras estrategias de particionamiento de modelos.
Paralelismo de contexto
Para videos largos o resoluciones altas, una sola pasada hacia adelante puede exceder el presupuesto de memoria y latencia de una sola GPU. Cosmos 3 admite paralelismo de contexto (CP) para dividir la dimensión de la secuencia entre varias GPUs, repartiendo el cálculo de atención de modo que cada dispositivo solo conserve una porción de los tokens.
Cosmos 3 admite el paralelismo de contexto Ulysses (intercambio de secuencia/cabeza all-to-all). No se admite el anillo de atención (ring attention).
A diferencia de la mayoría de los modelos de diffusers, Cosmos 3 no incorpora CP en el transformer ni en la ruta declarativa enable_parallelism(): su atención de consulta agrupada, sus flujos separados de comprensión/generación (el flujo de generación atiende a ambos) y sus longitudes irregulares por flujo no pueden expresarse como un _cp_plan. En su lugar, el modelo expone pequeñas costuras de shard/gather sin efecto, y la implementación reside en examples/cosmos3/cosmos_parallel.py, un módulo autónomo que puedes leer de principio a fin y adaptar. Ofrece dos ejes de sharding ortogonales y componibles:
| Función auxiliar | Fragmentos | Uso |
|---|---|---|
enable_cosmos3_context_parallel(transformer, cp_mesh) | secuencia (CP / Ulysses) | latencia en un modelo que cabe en una GPU (Nano) |
enable_cosmos3_tensor_parallel(transformer, tp_mesh) | pesos (TP) | ajustar un modelo que no cabe en una sola GPU (Super) |
Use cualquiera de ellos por separado o ambos juntos en una malla 2-D (tp, cp) (consulte Adaptar modelos grandes con paralelismo de tensor).
Dos requisitos son específicos de Cosmos 3:
- Use el backend de atención
native. Cosmos 3 utiliza grouped-query attention (GQA), y el backend SDPA nativo es el único que aceptaenable_gqa(cuDNN y flash lo rechazan). Los helpers expanden las cabeceras KV al número de cabeceras de consulta y llaman a SDPA conenable_gqa=Falsepara que siga despachando al kernel de flash (la alternativa matemática materializaría las puntuaciones completas de[S, S]y agotaría la memoria en secuencias largas). - El grado de CP (Ulysses) debe dividir el número de cabezas de consulta (32 para
Nano, 64 paraSuper); para TP, el grado debe dividir las cabezas KV (8). Los flujos de comprensión (texto) y generación (video/sonido) se fragmentan de forma independiente a lo largo de la secuencia, y las longitudes irregulares se rellenan con ceros internamente hasta un múltiplo del tamaño del mundo.
Ejecútalo
La CLI completa examples/cosmos3/inference_cosmos3.py utiliza Cosmos3OmniModularPipeline y reutiliza estos helpers, por lo que cualquier modalidad (texto a imagen/video, imagen a video, sonido, modos de acción) se ejecuta en multi-GPU mediante --tp-degree / --cp-degree. Inicie con torchrun; --tp-degree * --cp-degree debe ser igual a --nproc_per_node. Cada rank produce la misma salida; el rank 0 la escribe.
# CP only — Nano (fits one GPU); CP degree must divide 32 query heads.
torchrun --nproc_per_node=4 examples/cosmos3/inference_cosmos3.py --model nano --cp-degree 4 --prompt "..."
# TP only — Super; TP degree must divide 64 query heads and 8 KV heads.
torchrun --nproc_per_node=4 examples/cosmos3/inference_cosmos3.py --model super --tp-degree 4 --prompt "..."
# TP + CP — Super, with sound (TP=2 x CP=2 across 4 GPUs).
torchrun --nproc_per_node=4 examples/cosmos3/inference_cosmos3.py \
--model super --tp-degree 2 --cp-degree 2 --enable-sound --prompt "..."Los ~120 GB de pesos de Super no caben en una sola GPU de 96 GB, por lo que necesita TP; Nano cabe en una sola GPU, por lo que CP para este es una optimización pura de latencia. (Omita ambas banderas para ejecutar en una sola GPU.)
Ajuste de modelos grandes con paralelismo de tensor
CP fragmenta las activaciones, pero replica cada peso en cada rango, por lo que no reduce la huella de memoria de los pesos del modelo: un modelo que no cabe en una sola GPU tampoco cabrá con CP por sí solo. Para fragmentar los pesos, enable_cosmos3_tensor_parallel(transformer, tp_mesh) aplica paralelismo de tensores estilo Megatron en un segundo eje de malla ortogonal:
- Las proyecciones de atención y MLP se fragmentan por columnas/filas en el grupo de TP (
to_q/to_k/to_v+add_q/k/vygate/upde los MLP son paralelos por columnas;to_out/to_add_outydownde los MLP son paralelos por filas con un all-reduce). Cada rank termina poseyendoquery_heads / tpcabezas de consulta ykv_heads / tpcabezas KV. - TP se combina con CP en una malla de dispositivos 2D
(tp, cp): TP divide las cabeceras/pesos de forma persistente, y CP fragmenta la secuencia por encima. Las restricciones son quetpdebe dividir las cabeceras KV (8) y quetp * cpdebe dividir las cabeceras de consulta (32 paraNano, 64 paraSuper). - Los pesos se cargan en la CPU y se distribuyen en las GPUs capa por capa, de modo que el modelo completo nunca se materializa en un solo dispositivo.
TP emite un all-reduce en cada bloque de atención y MLP, por lo que consume mucho ancho de banda. En hosts sin NVLink, es el costo dominante; prefiera el grado de TP más pequeño que permita que los pesos quepan y coloque las GPU restantes en CP.
Úsalo en tu propio pipeline modular
Las banderas de la CLI son convenientes, pero puedes llamar a los helpers directamente con Cosmos3OmniModularPipeline. Carga la configuración del pipeline y los componentes en CPU, aplica TP antes de mover el pipeline a la GPU local del rank, cambia al backend native y luego habilita CP. No uses device_map para este flujo:
import os
import sys
import torch
import torch.distributed as dist
from diffusers import Cosmos3OmniModularPipeline
from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
from torch.distributed.device_mesh import init_device_mesh
# Make the helper module importable.
sys.path.insert(0, "examples/cosmos3")
from cosmos_parallel import (
enable_cosmos3_context_parallel,
enable_cosmos3_flash_attention,
enable_cosmos3_tensor_parallel,
)
# torchrun sets RANK / WORLD_SIZE / LOCAL_RANK. Pick tp_degree * cp_degree == world size.
local_rank = int(os.environ["LOCAL_RANK"])
torch.cuda.set_device(local_rank)
dist.init_process_group("nccl")
mesh = init_device_mesh("cuda", (tp_degree, cp_degree), mesh_dim_names=("tp", "cp"))
# Load components on CPU first; a TP-sharded model may not fit one GPU.
pipe = Cosmos3OmniModularPipeline.from_pretrained(model_id)
pipe.load_components(dtype=torch.bfloat16)
pipe.enable_safety_checker()
if tp_degree > 1:
enable_cosmos3_tensor_parallel(pipe.transformer, mesh["tp"]) # shard weights -> GPUs
pipe.to(f"cuda:{local_rank}") # move the replicated remainder
pipe.transformer.set_attention_backend("native")
if cp_degree > 1:
enable_cosmos3_context_parallel(pipe.transformer, mesh["cp"]) # shard the sequence
elif tp_degree > 1:
enable_cosmos3_flash_attention(pipe.transformer) # GQA-safe dense attention
# Modular pipelines replace components through update_components().
scheduler = UniPCMultistepScheduler.from_config(
pipe.scheduler.config, flow_shift=10.0, use_karras_sigmas=False
)
pipe.update_components(scheduler=scheduler)
# A single output name returns that value; a list returns a dictionary.
outputs = pipe(
prompt='{"scene":"A robot arm in a kitchen"}',
num_frames=189,
height=720,
width=1280,
output=["videos", "sound", "sampling_rate", "action"],
)
videos = outputs["videos"]
sound = outputs["sound"] # None unless sound generation was requested.
action = outputs["action"] # None unless an action workflow produced actions.Solo para CP (sin particionamiento de pesos), use una malla 1-D: init_device_mesh("cuda", (world_size,), mesh_dim_names=("cp",)) y simplemente enable_cosmos3_context_parallel.
enable_safety_checker() carga y habilita el comprobador predeterminado; disable_safety_checker() lo deshabilita explícitamente. Utilice esos métodos de pipeline en lugar del argumento de construcción enable_safety_checker= del pipeline de tareas o del argumento de llamada enable_safety_check=. Los pipelines modulares tampoco devuelven Cosmos3OmniPipelineOutput: use output="videos" para obtener solo los fotogramas, o una lista de salidas y su diccionario devuelto como se muestra arriba, en lugar de result.video, result.sound o result.action.
En algunas topologías multi-GPU, el primer all-to-all de NCCL puede colgarse. Si una ejecución de CP se detiene al inicio del primer paso de denoising, establezca
NCCL_P2P_DISABLE=1en el entorno antes de lanzartorchrun.
CP y TP se combinan con todos los flujos de trabajo anteriores (texto a video, imagen a video, texto a video con sonido y generación condicionada por acciones) y con los puntos de control Nano y Super: solo cambian las líneas de construcción del pipeline y de configuración de paralelismo.
Plantillas de metadatos
tokenize_prompt añade frases cortas de metadatos dentro del mensaje del usuario para que el LLM vea las condiciones con las que se entrenó el modelo. El prompt positivo recibe frases como «El vídeo dura 7,9 segundos y tiene 24 FPS.» y «Este vídeo tiene una resolución de 720x1280.»; el prompt negativo recibe la inversa («… no es …»).
Ambos están activados de forma predeterminada. Desactive cualquiera de los pares a través de __call__:
result = pipe(
prompt=prompt,
negative_prompt=negative_prompt,
num_frames=189,
height=720,
width=1280,
fps=24.0,
add_duration_template=False, # skip the duration sentence on both prompts
add_resolution_template=False, # skip the resolution sentence on both prompts
)add_duration_template no tiene efecto cuando num_frames == 1 (modo de imagen); en ese caso solo se añade la frase de resolución.
Verificador de seguridad
Cosmos3 integra el cosmos_guardrail CosmosSafetyChecker y lo ejecuta de forma predeterminada. El guardrail de texto rechaza los prompts inseguros antes de la generación (ValueError); el guardrail de video se ejecuta en los cuadros decodificados y, o bien pixela los rostros detectados, o bien rechaza la salida. La salida de audio no está sujeta a guardrails.
Instale la dependencia opcional para habilitar el comprobador predeterminado:
pip install cosmos_guardrailEl verificador es obligatorio según el Acuerdo de Licencia de Modelos Abiertos de NVIDIA. Las dos banderas siguientes existen para flujos de trabajo de pruebas y desarrollo en los que la barrera de seguridad sería redundante (p. ej., la entrada ya ha sido limpiada, o se está ejercitando intencionalmente el pipeline con entradas de borde).
Desactivar en la construcción (no se instancia ningún comprobador, por lo que no se descargan ni se cargan en memoria modelos de guardarrails):
import torch
from diffusers import Cosmos3OmniPipeline
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Nano",
dtype=torch.bfloat16,
device_map="cuda", # or "mps", "xpu", "cpu"
enable_safety_checker=False,
)Desactivar para una sola llamada (el comprobador permanece cargado: útil para un desvío puntual manteniendo el valor predeterminado activado para las llamadas posteriores):
result = pipe(
prompt=prompt,
num_frames=189,
height=720,
width=1280,
fps=24.0,
enable_safety_check=False,
)Para proporcionar un comprobador personalizado (p. ej., una subclase sin operación para pruebas rápidas), páselo como safety_checker=:
pipe = Cosmos3OmniPipeline.from_pretrained(
"nvidia/Cosmos3-Nano",
dtype=torch.bfloat16,
device_map="cuda", # or "mps", "xpu", "cpu"
safety_checker=MyCustomSafetyChecker(),
)Cosmos3OmniPipeline
clase diffusers.Cosmos3OmniPipeline
< source >( transformer: Cosmos3OmniTransformertext_tokenizer: AutoTokenizervae: AutoencoderKLWanscheduler: UniPCMultistepSchedulersound_tokenizer: diffusers.models.autoencoders.autoencoder_cosmos3_audio.Cosmos3AVAEAudioTokenizer | None = Nonesafety_checker: diffusers.pipelines.cosmos.pipeline_cosmos3_omni.CosmosSafetyChecker | None = Noneenable_safety_checker: bool = Truedefault_use_system_prompt: bool = Trueuse_native_flow_schedule: bool = False )
Decodifica un latente de sonido [C, T] a una forma de onda [audio_ch, N].
Añade/elimina la dimensión de lote esperada por el decodificador del tokenizador de sonido.
prepare_latents
< source >( image: typing.Union[PIL.Image.Image, numpy.ndarray, torch.Tensor, NoneType] = Nonevideo: typing.Union[list[PIL.Image.Image], torch.Tensor, numpy.ndarray, NoneType] = Nonecondition_frame_indexes_vision: Iterable = (0, 1)condition_video_keep: typing.Literal['first', 'last'] = 'first'num_frames: int | None = Noneheight: int | None = Nonewidth: int | None = Nonefps: float = 24.0latents: typing.Optional[torch.Tensor] = Nonesound_latents: typing.Optional[torch.Tensor] = Noneaction_latents: typing.Optional[torch.Tensor] = Nonegenerator: typing.Optional[torch.Generator] = Nonedevice: str = 'cuda'dtype: dtype = torch.bfloat16enable_sound: bool = Falseaction: CosmosActionCondition | None = None )
Construir la condición y el ruido inicial para una sola muestra.
tokenize_prompt
< source >( prompt: strnegative_prompt: str | None = Nonenum_frames: int = 189height: int = 720width: int = 1280fps: float = 24.0use_system_prompt: bool | None = Noneadd_resolution_template: bool = Trueadd_duration_template: bool = Trueaction_mode: str | None = Noneaction_view_point: str | None = None )
Aplica plantillas de aumento de prompt y tokeniza los prompts cond/uncond a través de la plantilla de chat configurada.
Este pipeline no ejecuta un codificador de texto separado: el transformador conjunto Cosmos3 consume los IDs de tokens crudos junto con los tokens de visión (y opcionalmente de sonido).
Cuando negative_prompt es None, se utiliza una cadena vacía; la página de documentación de Cosmos3 documenta los prompts negativos de control de calidad recomendados para pasarlos explícitamente en text2video / image2video. Las plantillas de duración y resolución se agregan al prompt, y las plantillas inversas se agregan al prompt negativo, cuando están habilitadas.
Cuando se establece action_mode, el prompt se convierte en su lugar en la descripción JSON estructurada de la acción en la que se entrenó el modelo (ver _build_action_json_prompt), utilizando action_view_point para el campo de encuadre; las plantillas de metadatos planos se omiten porque el JSON ya incluye duración/fps/resolución/aspect_ratio.
- todos
- call
Cosmos3OmniModularPipeline
Cosmos 3 también está disponible como un pipeline de Modular Diffusers. El pipeline basado en tareas Cosmos3OmniPipeline sigue disponible; el pipeline modular coexiste con él y cubre los mismos modos (text2image, text2video, image2video, video2video, generación condicionada por acciones y transfer (control estructural), con sonido opcional cuando el checkpoint lo admite).
import torch
from diffusers import Cosmos3OmniModularPipeline
pipe = Cosmos3OmniModularPipeline.from_pretrained(
"nvidia/Cosmos3-Nano", dtype=torch.bfloat16
)
pipe.load_components(dtype=torch.bfloat16)
pipe.enable_safety_checker()
videos = pipe(
prompt='{"scene":"A robot arm in a kitchen"}',
num_frames=1,
height=720,
width=1280,
output="videos",
)
# Modular pipelines expose declared outputs directly instead of using the task pipeline's
# `return_dict`/`Cosmos3OmniPipelineOutput` API.
image = videos[0]También puedes cargar a través de ModularPipeline y dejar que la configuración del repositorio seleccione la clase de bloques:
import torch
from diffusers import ModularPipeline
pipe = ModularPipeline.from_pretrained("nvidia/Cosmos3-Nano", dtype=torch.bfloat16)
pipe.load_components(dtype=torch.bfloat16)
pipe.enable_safety_checker()
videos = pipe(
prompt='{"scene":"A robot arm in a kitchen"}', num_frames=1, height=720, width=1280, output="videos"
)Para inspeccionar o personalizar un flujo de trabajo modular específico de Cosmos, use available_workflows + get_workflow():
available = pipe.blocks.available_workflows
image2video_blocks = pipe.blocks.get_workflow("image2video")Ejemplos modulares para todos los flujos de trabajo existentes
El pipeline modular admite las mismas firmas de llamada que el pipeline de tareas. Los fragmentos de código a continuación replican todos los ejemplos de generación mostrados anteriormente (text2video, text2image, image2video, video2video, video2video_sound, text2video_sound y action_policy). Transfer (control estructural) tiene sus propias entradas y se muestra por separado en Transfer modular a continuación.
import json
import torch
from diffusers import Cosmos3OmniModularPipeline, CosmosActionCondition
from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
from diffusers.utils import encode_video, export_to_video, load_image, load_video
pipe = Cosmos3OmniModularPipeline.from_pretrained("nvidia/Cosmos3-Nano", dtype=torch.bfloat16)
pipe.load_components(dtype=torch.bfloat16)
pipe.enable_safety_checker()
pipe.to("cuda") # or "mps", "xpu", "cpu"
pipe.scheduler = UniPCMultistepScheduler.from_config(
pipe.scheduler.config, flow_shift=10.0, use_karras_sigmas=False
)
# text2video
json_prompt = json.load(open("assets/example_t2v_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt.json"))
videos = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
num_frames=189,
height=720,
width=1280,
num_inference_steps=35,
guidance_scale=6.0,
fps=24.0,
output="videos",
)
export_to_video(videos, "cosmos3_modular_t2v.mp4", fps=24, macro_block_size=1)
# text2image
json_prompt = json.load(open("assets/example_t2i_prompt.json"))
videos = pipe(prompt=json.dumps(json_prompt), num_frames=1, height=720, width=1280, output="videos")
videos[0].save("cosmos3_modular_t2i.jpg", format="JPEG", quality=85)
# image2video
json_prompt = json.load(open("assets/example_i2v_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt_i2v.json"))
image = load_image("https://github.com/nvidia-cosmos/cosmos-dependencies/releases/download/assets/robot_153.jpg")
videos = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
image=image,
num_frames=189,
height=720,
width=1280,
fps=24.0,
output="videos",
)
export_to_video(videos, "cosmos3_modular_i2v.mp4", fps=24, macro_block_size=1)
# video2video
json_prompt = json.load(open("assets/example_v2v_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt_i2v.json"))
video = load_video(
"https://github.com/nvidia-cosmos/cosmos-dependencies/raw/refs/heads/assets/cosmos3/inputs/vision/robot_pouring.mp4"
)
videos = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
video=video,
condition_frame_indexes_vision=[0, 1],
condition_video_keep="first",
num_frames=189,
height=720,
width=1280,
num_inference_steps=35,
guidance_scale=6.0,
fps=24.0,
output="videos",
)
export_to_video(videos, "cosmos3_modular_v2v.mp4", fps=24, macro_block_size=1)
# video2video_sound
outputs = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
video=video,
condition_frame_indexes_vision=[0, 1],
condition_video_keep="first",
num_frames=189,
height=720,
width=1280,
fps=24.0,
enable_sound=True,
output=["videos", "sound", "sampling_rate"],
)
encode_video(
outputs["videos"],
fps=24,
audio=outputs["sound"],
audio_sample_rate=outputs["sampling_rate"],
output_path="cosmos3_modular_v2v_with_sound.mp4",
)
# text2video_sound
json_prompt = json.load(open("assets/example_t2v_sound_prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt.json"))
outputs = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
num_frames=189,
height=720,
width=1280,
fps=24.0,
enable_sound=True,
output=["videos", "sound", "sampling_rate"],
)
encode_video(
outputs["videos"],
fps=24,
audio=outputs["sound"],
audio_sample_rate=outputs["sampling_rate"],
output_path="cosmos3_modular_t2v_with_sound.mp4",
)
# action_policy
prompt = "Put the pot to the left of the purple item."
action_video = load_video(
"https://github.com/nvidia-cosmos/cosmos-dependencies/raw/refs/heads/assets/cosmos3/inputs/action/bridge_20260501_0.mp4"
)
outputs = pipe(
prompt=prompt,
action=CosmosActionCondition(
mode="policy",
chunk_size=16,
domain_name="bridge_orig_lerobot",
resolution_tier=480,
video=action_video,
view_point="ego_view",
),
fps=5,
num_inference_steps=30,
guidance_scale=1.0,
use_system_prompt=False,
output=["videos", "action"],
)
export_to_video(outputs["videos"], "cosmos3_modular_action_policy.mp4", fps=5, macro_block_size=1)
if outputs["action"] is not None:
with open("cosmos3_modular_action_policy.json", "w") as f:
json.dump(outputs["action"][0].tolist(), f)Transferencia modular (control estructural)
Transfer sigue un video de control precalculado (bordes, desenfoque, profundidad, segmentación o un mapa de escenario del mundo) que se pasa a través de control_videos= como un mapeo {hint: video}. Es solo para video (sin image / video / action / enable_sound), el prompt es una descripción JSON pre-ampliada (ver Ampliación de prompts) y los clips largos se generan de forma autoregresiva en bloques de num_video_frames_per_chunk y se unen automáticamente. guidance_scale es el CFG de texto habitual; control_guidance (!= 1.0) amplifica adicionalmente la señal de control. Valores de inicio recomendados por hint:
| Pista | guidance_scale | control_guidance | flow_shift | Geometría |
|---|---|---|---|---|
| Borde / Desenfoque / Profundidad | 3.0 | 1.5 | 10.0 | 121 fotogramas @ 30 FPS |
| Segmentación | 3.0 | 2.0 | 10.0 | 121 fotogramas @ 30 FPS |
| Escenario mundial (WSM) | 1.0 | 3.0 | 10.0 | 101 fotogramas @ 10 FPS |
Diffusers no incluye los activos de control. Los preelaborados (un video de control + un prompt.json correspondiente por pista, además de un negative_prompt.json compartido) se encuentran en el Cosmos cookbook. Para el ejemplo de borde a continuación, descárguelos en una carpeta local assets/:
base=https://github.com/NVIDIA/cosmos/raw/refs/heads/main/cookbooks/cosmos3/generator/transfer/assets
mkdir -p assets/edge
curl -sL "$base/edge/control_edge.mp4" -o assets/edge/control_edge.mp4
curl -sL "$base/edge/prompt.json" -o assets/edge/prompt.json
curl -sL "$base/negative_prompt.json" -o assets/negative_prompt.jsonimport json
import torch
from diffusers import Cosmos3OmniModularPipeline
from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
from diffusers.utils import export_to_video, load_video
pipe = Cosmos3OmniModularPipeline.from_pretrained("nvidia/Cosmos3-Nano", dtype=torch.bfloat16)
pipe.load_components(dtype=torch.bfloat16)
pipe.to("cuda") # or "mps", "xpu", "cpu"
pipe.scheduler = UniPCMultistepScheduler.from_config(
pipe.scheduler.config, flow_shift=10.0, use_karras_sigmas=False
)
# Downloaded into assets/ from the Cosmos cookbook (see the curl snippet above).
json_prompt = json.load(open("assets/edge/prompt.json"))
negative_prompt = json.load(open("assets/negative_prompt.json"))
control_edge = load_video("assets/edge/control_edge.mp4")
videos = pipe(
prompt=json.dumps(json_prompt),
negative_prompt=json.dumps(negative_prompt),
control_videos={"edge": control_edge},
num_frames=121,
height=720,
width=1280,
fps=30.0,
num_inference_steps=35,
guidance_scale=3.0,
control_guidance=1.5,
output="videos",
)
export_to_video(videos, "cosmos3_modular_transfer_edge.mp4", fps=30, macro_block_size=1)Texto a imagen e imagen a video destilados (de pocos pasos)
Los puntos de control destilados de pocos pasos se sirven mediante Cosmos3DistilledModularPipeline (bloques: Cosmos3DistilledBlocks); los Cosmos3OmniModularPipeline y Cosmos3OmniPipeline base no los admiten. num_inference_steps se fija a la longitud de la configuración de distilled_sigmas del pipeline (obtenida de modular_model_index.json del punto de control) y guidance_scale se fuerza a 1.0, ya que la guía está integrada en los pesos: pasar cualquier otro valor para cualquiera de los dos parámetros provoca un error, y negative_prompt se ignora con una advertencia.
Los puntos de control destilados en FP8 (revision="fp8") no declaran una política de precisión mixta, por lo que cada paso se mantiene en W8A8 nativo.
Los prompts siguen la misma estructura JSON descriptiva que los modelos no destilados, por lo que el texto corto debe interpolarse primero: use --mode text2image (T2I) o --mode image2video (I2V) como se describe en Interpolación de prompts y luego pase el JSON mediante json.dumps(...).
import json
import torch
from diffusers import Cosmos3DistilledModularPipeline
from diffusers.utils import export_to_video, load_image
# JSON-upsampled prompt (see "Prompt upsampling" above).
json_prompt = json.load(open("assets/example_t2i_prompt.json"))
repo = "nvidia/Cosmos3-Super-Text2Image-4Step"
pipe = Cosmos3DistilledModularPipeline.from_pretrained(repo, dtype=torch.bfloat16)
pipe.load_components(dtype=torch.bfloat16)
pipe.to("cuda") # or "mps", "xpu", "cpu"
# text-to-image (distilled)
videos = pipe(
prompt=json.dumps(json_prompt),
num_frames=1,
height=720,
width=1280,
output="videos",
)
videos[0].save("cosmos3_distilled_t2i.jpg", format="JPEG", quality=85)
# image-to-video (distilled) — load the I2V repo instead
# JSON-upsampled prompt (see "Prompt upsampling" above); upsampled from the source prompt
# "The right robotic hand picks up the red sphere on the shelf."
json_prompt_i2v = json.load(open("assets/example_i2v_prompt.json"))
repo_i2v = "nvidia/Cosmos3-Super-Image2Video-4Step"
pipe = Cosmos3DistilledModularPipeline.from_pretrained(repo_i2v, dtype=torch.bfloat16)
pipe.load_components(dtype=torch.bfloat16)
pipe.to("cuda")
image = load_image(
"https://github.com/nvidia-cosmos/cosmos-dependencies/raw/refs/heads/assets/cosmos3/inputs/vision/robot_153.jpg"
)
videos = pipe(
prompt=json.dumps(json_prompt_i2v),
image=image,
num_frames=189,
height=720,
width=1280,
output="videos",
)
export_to_video(videos, "cosmos3_distilled_i2v.mp4", fps=24, macro_block_size=1)clase diffusers.Cosmos3OmniModularPipeline
< source >( blocks: diffusers.modular_pipelines.modular_pipeline.ModularPipelineBlocks | None = Nonepretrained_model_name_or_path: str | os.PathLike | None = Nonecomponents_manager: diffusers.modular_pipelines.components_manager.ComponentsManager | None = Nonecollection: str | None = Noneworkflow: str | None = Nonemodular_config_dict: dict[str, typing.Any] | None = Noneconfig_dict: dict[str, typing.Any] | None = None**kwargs )
Un ModularPipeline para la generación omni de Cosmos 3.
- todos
- call
Cosmos3DistilledModularPipeline
clase diffusers.Cosmos3DistilledModularPipeline
< source >( blocks: diffusers.modular_pipelines.modular_pipeline.ModularPipelineBlocks | None = Nonepretrained_model_name_or_path: str | os.PathLike | None = Nonecomponents_manager: diffusers.modular_pipelines.components_manager.ComponentsManager | None = Nonecollection: str | None = Noneworkflow: str | None = Nonemodular_config_dict: dict[str, typing.Any] | None = Noneconfig_dict: dict[str, typing.Any] | None = None**kwargs )
Un ModularPipeline para la generación omni de Cosmos 3 destilada (de pocos pasos).
Los puntos de control destilados integran la guía sin clasificador en los pesos y muestrean según un plan fijo leído de la configuración distilled_sigmas del pipeline (completada desde modular_model_index.json), por lo que guidance_scale y num_inference_steps son fijos y negative_prompt no está soportado.
- todos
- call
CosmosActionCondition
clase diffusers.CosmosActionCondition
< source >( mode: typing.Literal['policy', 'forward_dynamics', 'inverse_dynamics']chunk_size: intdomain_name: strresolution_tier: int = 480raw_actions: typing.Optional[torch.Tensor] = Noneimage: typing.Union[PIL.Image.Image, numpy.ndarray, torch.Tensor, NoneType] = Nonevideo: typing.Union[list, numpy.ndarray, torch.Tensor, NoneType] = Noneview_point: str = 'ego_view' )
Parámetros
- mode (
str) — La tarea de acción. Uno de"forward_dynamics"(desarrollar el video futuro a partir de un primer fotograma y una secuencia dada deraw_actions),"inverse_dynamics"(inferir las acciones que conectan los fotogramas de condicionamiento) o"policy"(desarrollar conjuntamente el video futuro y las acciones a partir del primer fotograma). - chunk_size (
int) — Número de pasos de transición de acción en el chunk. El video de condicionamiento emparejado abarcachunk_size + 1fotogramas. - domain_name (
str) — Dominio de encarnación que selecciona los pesos de proyección de acciones conscientes del dominio. Debe ser uno de los dominios de encarnación de Cosmos 3 registrados. También fija el ancho de acción sin relleno utilizado para extraer las acciones predichas, resuelto internamente a partir de este nombre (ver_EMBODIMENT_TO_RAW_ACTION_DIM). - resolution_tier (
int, por defecto480) — Nivel de resolución tier para la condición de acción (uno de256,480,704,720). El nivel selecciona un lienzo predefinido cuya relación de aspecto es la más cercana a la de la entrada; la entrada se reduce (nunca se amplía) y se rellena con padding para condicionarlo. Esto no es el tamaño del cuadro de salida, que sigue el contenido de la entrada. Ajusta el nivel a la resolución nativa de la entrada: un nivel más bajo descarta detalle, mientras que un nivel más alto no añade resolución (no hay ampliación), desperdicia cómputo en el padding y es una discrepancia entre entrenamiento e inferencia que puede perjudicar la calidad. - raw_actions (
torch.Tensor, opcional) — Vectores de acción del dominio crudo de forma[T, raw_action_dim]que impulsan"forward_dynamics". Las secuencias más cortas quechunk_sizerepiten la última acción; las más largas se truncan. Los canales que superan elaction_dimdel modelo se rechazan, y las entradas más estrechas se rellenan con ceros hastaaction_dim. - image (
PIL.Image.Image,np.ndarrayotorch.Tensor, opcional) — Fotograma de condicionamiento para"policy"/"forward_dynamics". Mutuamente excluyente convideo. - video (
list,np.ndarrayotorch.Tensor, opcional) — Video de condicionamiento, obligatorio para"inverse_dynamics". Para"policy"/"forward_dynamics"solo se utiliza su primer frame. Es mutuamente excluyente conimage. - view_point (
str, por defecto"ego_view") — Etiqueta de perspectiva de cámara utilizada para completar el campocinematography.framingde la descripción de la acción. Uno de"ego_view","third_person_view","wrist_view"o"concat_view". El modelo de acción se entrenó con descripciones JSON estructuradas que incluyen esta oración de punto de vista; una etiqueta no reconocida elimina el campo framing (con una advertencia).
Agrupa todas las entradas necesarias para una tarea de generación condicionada por acciones en Cosmos 3.
Pásalo a Cosmos3OmniPipeline.__call__() mediante el argumento action en lugar de los argumentos de nivel superior image / height / width, que están reservados para ejecuciones de t2v e i2v.
Cosmos3OmniPipelineOutput
clase diffusers.pipelines.cosmos.pipeline_cosmos3_omni.Cosmos3OmniPipelineOutput
< source >( video: Anysound: typing.Optional[torch.Tensor] = Noneaction: list[torch.Tensor] | None = None )
Parámetros
- video — El video generado. El tipo exacto depende de
output_typepasado a la pipeline: una lista de fotogramas PIL para"pil"(predeterminado), unnp.ndarrayde forma[T, H, W, C]para"np", untorch.Tensorde forma[T, C, H, W]para"pt", o un tensor latente sin procesar cuandooutput_type="latent". - sound — Forma de onda de audio decodificada de forma
[C, N].Nonecuandoenable_sound=False. - action — Tokens de acción predichos.
Nonea menos que un modo de acción prediga acciones.
Dataclass de salida para Cosmos3OmniPipeline.