tao-finetune-cosmos-embed — Claude Code skill: how to install
Configures Docker runs for Cosmos-Embed1 inside NVIDIA TAO, enabling text-to-video retrieval, model fine-tuning, evaluation, and artifact exports.
npx skills add NVIDIA/skills --skill tao-finetune-cosmos-embed -a claude-codeWhat tao-finetune-cosmos-embed does
This skill provides Docker run configurations and execution commands for the cosmos-embed1 CLI inside the nvcr.io/nvidia/tao/tao-toolkit:7.3.0-cosmos-embed container. It handles four core workflows: training, evaluation, inference queries, and exporting checkpoints to ONNX or HuggingFace formats. Workspace execution relies on predefined YAML specs alongside data, specs, and results directories.
AutoML is not supported here. Because model schemas are absent, all training flows must use direct CLI actions rather than automated orchestration pipelines. Pulling the pretrained weights requires an HF_TOKEN environment variable. You must install protobuf below version 7 before running tasks, because wandb 0.21.0 breaks on newer protobuf releases in this image.
The container working directory must be set to a writable results directory. Cold Triton caches cause GCC to misinterpret a local specs directory as a compiler configuration file, which crashes execution immediately. An isolated bind mount handles the BERT Q-Former cache to avoid permission issues across site-packages.
What it helps with
- fine-tune Cosmos-Embed1 on custom video datasets
- run text-to-video retrieval queries via CLI inference
- export trained checkpoints to ONNX or HuggingFace formats
- resolve protobuf and wandb package conflicts in TAO containers
Example prompts for the agent
- Help me fine-tune Cosmos-Embed1 using the specs/train.yaml configuration
- Run cosmos-embed1 inference to search videos for "a man is singing on stage"
- Export checkpoint iter_000000001.pt to ONNX format
How to install tao-finetune-cosmos-embed
1Skills CLI (Vercel)
npx skills add NVIDIA/skills --skill tao-finetune-cosmos-embed -a claude-code2Manually: put the files in place
~/.claude/skills/tao-finetune-cosmos-embed/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/tao-finetune-cosmos-embed/
1Skills CLI (Vercel)
npx skills add NVIDIA/skills --skill tao-finetune-cosmos-embed -a codex2Manually: put the files in place
.agents/skills/tao-finetune-cosmos-embed/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add NVIDIA/skills --skill tao-finetune-cosmos-embed -a cursor2Manually: put the files in place
.cursor/skills/tao-finetune-cosmos-embed/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install NVIDIA/skills tao-finetune-cosmos-embed2Manually: put the files in place
.github/skills/tao-finetune-cosmos-embed/SKILL.md1Skills CLI (Vercel)
npx skills add NVIDIA/skills --skill tao-finetune-cosmos-embed -a gemini-cli2Platform CLI
gemini skills install https://github.com/NVIDIA/skills --path skills/tao-finetune-cosmos-embedManually: put the files in place
.devin/skills/tao-finetune-cosmos-embed/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add NVIDIA/skills --skill tao-finetune-cosmos-embed -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about tao-finetune-cosmos-embed
How to install tao-finetune-cosmos-embed in Claude Code?
Run npx skills add NVIDIA/skills --skill tao-finetune-cosmos-embed -a claude-code. For manual setup, place the definition file at ~/.claude/skills/tao-finetune-cosmos-embed/SKILL.md.
What does tao-finetune-cosmos-embed do?
It sets up containerized workflows for Cosmos-Embed1 under NVIDIA TAO Toolkit. The skill specifies exact Docker mounts, environment variables, and CLI commands for training, inference, and exports.
What prerequisites are needed before running this skill?
You need Docker with nvidia-container-toolkit installed, access to the pinned TAO container image, and an HF_TOKEN variable to download pretrained model weights.
Source text
SKILL.md · Apache-2.0
---
name: tao-finetune-cosmos-embed
description: >-
Cosmos-Embed1 video-text embedding for text-to-video retrieval, video-to-video search, semantic deduplication, and
fine-tuning. Use when the user asks to "fine-tune Cosmos-Embed1", "run cosmos-embed inference", "export Cosmos-Embed1",
"embed videos", or "search videos with text".
license: Apache-2.0
compatibility: Requires docker + nvidia-container-toolkit, the published Cosmos-Embed TAO container (pinned in this skill), and a HuggingFace token when downloading pretrained `nvidia/Cosmos-Embed1-*` weights.
metadata:
author: NVIDIA Corporation
version: "0.1.0"
allowed-tools: Read Bash
tags:
- video
- vision-language
- vlm
- multimodal
- retrieval
- embedding
- cosmos
- fine-tuning
---
# Cosmos-Embed
> **Standalone install?** If this session was not initialized by the TAO skill bank plugin, run the `tao-setup` skill first (host preflight, credentials, cross-skill discovery).
Cosmos-Embed1 is a joint video-text embedder for text-to-video retrieval, video-to-video search, zero-shot/kNN classification, and semantic deduplication. The packaged CLI is `cosmos-embed1` and supports `train`, `evaluate`, `inference`, and `export`.
Container image and per-action commands are in `references/skill_info.yaml`. Compact starting specs are in `references/spec_template_*.yaml`.
## Train Action Policy
AutoML is not packaged for this model skill because there are no Cosmos-Embed schemas under `schemas/`. Always use the direct model skill actions for `train`, `evaluate`, `inference`, and `export`, even when a higher-level request includes `automl_policy: on`. Do not route Cosmos-Embed through workflow or AutoML skills until model-specific train schemas and templates are added.
Non-train actions such as `evaluate`, `inference`, `export`, and deploy flows stay in this model skill. The per-run `automl_policy` override does not change model metadata.
## Quick Start
Use the published Cosmos-Embed container pinned below (also declared in
`references/skill_info.yaml`). Do not build from the private
Cosmos-Embed1 source tree for normal skill use; build from source only when
developing the container itself.
```bash
COSMOS_EMBED_IMAGE_DEFAULT=nvcr.io/nvidia/tao/tao-toolkit:7.3.0-cosmos-embed # versions-key: images.tao_toolkit.cosmos_embed
COSMOS_EMBED_IMAGE="${COSMOS_EMBED_IMAGE:-$COSMOS_EMBED_IMAGE_DEFAULT}"
docker pull "$COSMOS_EMBED_IMAGE"
```
Expected local workspace layout:
```text
workspace/
├── data/
│ ├── msrvtt_test_1k.json
│ └── video/
│ ├── video7020.mp4
│ └── ...
├── model/
│ └── Cosmos-Embed1-224p/ # optional if using HF repo id
├── specs/
│ ├── train.yaml
│ ├── evaluate.yaml
│ ├── inference.yaml
│ ├── export_onnx.yaml
│ └── export_hf.yaml
└── results/
```
Use these Docker options for all actions unless the local Docker/platform skill gives a stricter environment-specific command:
```bash
set -a; source /path/to/.env; set +a # omit if already exported
COSMOS_EMBED_IMAGE_DEFAULT=nvcr.io/nvidia/tao/tao-toolkit:7.3.0-cosmos-embed # versions-key: images.tao_toolkit.cosmos_embed
COSMOS_EMBED_IMAGE="${COSMOS_EMBED_IMAGE:-$COSMOS_EMBED_IMAGE_DEFAULT}"
RUN_ROOT="${RUN_ROOT:-$PWD}"
COSMOS_EMBED_PRETRAINED_CACHE="${COSMOS_EMBED_PRETRAINED_CACHE:-$RUN_ROOT/pretrained_checkpoints}"
mkdir -p "$COSMOS_EMBED_PRETRAINED_CACHE"
DOCKER_COMMON=(
--rm --gpus all --shm-size=8g --network=host
--shm-size=64g
--ulimit memlock=-1
--ulimit stack=67108864
-w /results
-e HF_TOKEN
-e WANDB_DISABLED=true
-e WANDB_MODE=disabled
-e HUGGINGFACE_HUB_CACHE=/hf_cache
-v "$RUN_ROOT/data:/data:ro"
-v "$RUN_ROOT/model:/model"
-v "$RUN_ROOT/specs:/specs:ro"
-v "$RUN_ROOT/results:/results"
-v "$RUN_ROOT/hf_cache:/hf_cache"
--mount "type=bind,source=$COSMOS_EMBED_PRETRAINED_CACHE,target=/usr/local/lib/python3.12/dist-packages/pretrained_checkpoints"
)
```
The pinned 7.1.0 image downloads the BERT Q-Former component under
`/usr/local/lib/python3.12/dist-packages/pretrained_checkpoints`, even when
Hugging Face cache variables point elsewhere. The dedicated bind mount above
must be writable by the container UID selected by the platform skill; create
it as the launching user before submission. Keep this mount when applying the
platform's non-root UID/GID and writable HOME settings. It permits normal
runtime downloads without modifying the image or making all of site-packages
writable. For another image version, verify its cache location before reusing
this image-specific destination.
Use a writable per-run results directory as the container working directory.
With a cold Triton cache in this image, launching from a directory containing
`specs/` can make GCC read `./specs` as a compiler spec file and fail with
`cannot read spec file './specs': Is a directory`. Keep the inference spec's
absolute `results_dir` unchanged; changing the working directory is sufficient.
For Cosmos-Embed images that ship `protobuf==7.x`, run a small startup
preamble before every action:
```bash
python -m pip install "protobuf<7"
```
The image contains `wandb==0.21.0` with `protobuf==7.x`; importing W&B fails before training/evaluation unless protobuf is pinned below 7. Use `WANDB_DISABLED=true` and `WANDB_MODE=disabled` for smoke or offline runs. Cosmos-Embed may still download the public `google-bert/bert-base-uncased` Q-Former component even when the model checkpoint is disabled, so pass `HF_TOKEN` as an environment variable or mount a persistent HuggingFace cache. Do not write the token into specs, logs, or reports.
Train:
```bash
docker run "${DOCKER_COMMON[@]}" "$COSMOS_EMBED_IMAGE" \
bash -lc "python -m pip install 'protobuf<7' && cosmos-embed1 train -e /specs/train.yaml results_dir=/results"
```
Evaluate:
```bash
docker run "${DOCKER_COMMON[@]}" "$COSMOS_EMBED_IMAGE" \
bash -lc "python -m pip install 'protobuf<7' && cosmos-embed1 evaluate -e /specs/evaluate.yaml results_dir=/results"
```
Inference:
```bash
docker run "${DOCKER_COMMON[@]}" "$COSMOS_EMBED_IMAGE" \
bash -lc "python -m pip install 'protobuf<7' && cosmos-embed1 inference -e /specs/inference.yaml \
'inference.query.input_texts=[\"a man is singing on stage\"]' \
inference.k=5 \
results_dir=/results"
```
Export ONNX:
```bash
docker run "${DOCKER_COMMON[@]}" "$COSMOS_EMBED_IMAGE" \
bash -lc "python -m pip install 'protobuf<7' && cosmos-embed1 export -e /specs/export_onnx.yaml \
export.checkpoint=/results/train/checkpoints/iter_000000001.pt \
export.onnx_file=/results/export/cosmos_embed1_combined.onnx \
results_dir=/results"
```
Export HuggingFace format:
```bash
docker run "${DOCKER_COMMON[@]}" "$COSMOS_EMBED_IMAGE" \
bash -lc "python -m pip install 'protobuf<7' && cosmos-embed1 export -e /specs/export_hf.yaml \
export.checkpoint=/results/train/checkpoints/iter_000000001.pt \
export.hf_output_dir=/results/export_hf/cosmos_embed1_hf \
results_dir=/results"
```
## Smoke Overrides
For a small functional check, keep the same specs and override the expensive knobs:
```bash
train.max_iter=1
train.validation_iter=2
train.checkpoint_iter=1
train.optim.optim=adamw
train.optim.warmup_steps=0
train.optim.lr_decay_iters=1
dataset.train_dataset.batch_size=1
dataset.val_dataset.batch_size=1
dataset.train_dataset.workers=0
dataset.val_dataset.workers=0
```
When shortening the cosine scheduler for smoke runs, keep
`train.optim.lr_decay_iters` greater than `train.optim.warmup_steps`, or set
`train.optim.warmup_steps=0` as shown above. The scheduler divides by
`lr_decay_iters - warmup_steps`, so equal values fail before the checkpoint is
written.
If no local Cosmos-Embed1 pretrained checkpoint is available, set `model.pretrained_model_path=null` for a plumbing-only smoke train. The model quality is meaningless in that mode, but the train/evaluate/inference/export action paths can still be exercised. In the current container, the Q-Former path can still fetch `google-bert/bert-base-uncased`; provide `HF_TOKEN` or a mounted HuggingFace cache for fresh ephemeral containers.
For evaluation and inference smoke tests on a tiny subset:
```bash
evaluate.callbacks.embedding_visualization=false
evaluate.callbacks.max_eval_samples=8
dataset.test_dataset.batch_size=1
dataset.test_dataset.workers=0
inference.k=2
dataset.inference_dataset.batch_size=1
dataset.inference_dataset.workers=0
```
## Data Format
The MSR-VTT path expects a local video glob and a JSON metadata file:
```yaml
dataset:
train_dataset:
dataset_type: msrvtt
mp4_urls: /data/video/*.mp4
metadata: /data/msrvtt_test_1k.json
```
List-format metadata rows must include at least `video` and `caption`:
```json
{"video_id": "video7020", "video": "video7020.mp4", "caption": "a woman creating a fondant baby and flower"}
```
The dataset loader derives the video id from the local `.mp4` filename and filters to videos present in the metadata. If a run finds zero videos, check that `mp4_urls` points to a container-local glob and that metadata `video` names match the filenames.
## Model Weights
- Local HF directory: mount it under `/model` and set `model.pretrained_model_path=/model/Cosmos-Embed1-224p`.
- HuggingFace repo: set `model.pretrained_model_path=nvidia/Cosmos-Embed1-224p` and pass `HF_TOKEN` if access is gated.
- Fine-tuned checkpoint: set downstream actions to the resolver-selected `/results/train/checkpoints/iter_#########.pt` file.
Training writes full checkpoints under `results/train/checkpoints/iter_#########.pt`, updates `results/train/checkpoints/latest_checkpoint.txt`, and creates a `cosmos_embed1_model_latest.pth` symlink. For `evaluate.checkpoint`, `inference.checkpoint`, `export.checkpoint`, and `train.resume_training_checkpoint_path`, resolve and pass the exact `iter_#########.pt` file for the intended iteration. The action spec templates intentionally leave these checkpoint fields null so the model-skill runner or the user must provide the resolver-selected checkpoint. Use the latest symlink only when the user explicitly asks for latest.
For single-GPU resume/retrain from a consolidated checkpoint, set `model.fsdp_shard_size: 1`. The container default is 8, which sends resumed training through an FSDP apply path that Cosmos-Embed1 does not implement for this model class.
Variants:
| Variant | Resolution | Frames | Embedding dim |
|---|---:|---:|---:|
| `Cosmos-Embed1-224p` | 224 x 224 | 8 | 256 |
| `Cosmos-Embed1-336p` | 336 x 336 | 8 | 768 |
| `Cosmos-Embed1-448p` | 448 x 448 | 8 | 768 |
Keep `model.network.embed_dim`, `model.input_hw`, and `model.network.spatial_resolution` aligned with the selected variant.
## Important Parameters
| Parameter | Notes |
|---|---|
| `train.num_gpus` | `1` for single GPU, `>1` auto-launches `torchrun`, `-1` auto-detects visible GPUs. |
| `train.max_iter` | Main training length. Use `1` only for smoke testing. |
| `train.optim.optim` | `fused_adamw` is faster when available; `adamw` is safer for smoke and portability. |
| `model.lora.enabled` | Enables LoRA. Set `model.network.visual_encoder.transformer_engine=false` when LoRA is on. |
| `model.lora.lora_rank` | LoRA rank. Start with `8`; try `4`, `8`, or `16` for manual or AutoML-style sweeps. |
| `model.lora.lora_alpha` | LoRA scaling factor. Start with `16`; keep near `2 * lora_rank` unless experiments show otherwise. |
| `model.lora.lora_dropout` | LoRA dropout. Start with `0.1`; sweep `0.0`, `0.05`, and `0.1` for small datasets. |
| `model.lora.bias` | Bias policy: `none`, `all`, or `lora_only`. Keep `none` unless intentionally training biases. |
| `model.lora.use_rslora` / `use_dora` | Optional LoRA variants. Enable one at a time and record the setting with the checkpoint. |
| `model.lora.target_modules` | Optional module-name patterns for LoRA injection. Leave empty for the default ViT + Q-Former attention/MLP targets. |
| `model.lora.modules_to_save` | Optional modules to keep fully trainable alongside LoRA. Leave empty unless preserving a task-specific head. |
| `evaluate.load_dataset_pkl` / `save_dataset_pkl` | Cache evaluation embeddings. |
| `inference.load_dataset_pkl` / `save_dataset_pkl` | Cache the search database for repeated retrieval. |
| `export.mode` | `video`, `text`, `combined`, or `huggingface`. |
| `export.on_cpu` | Recommended for export to avoid device mismatch issues. |
### LoRA and AutoML Notes
For parameter-efficient fine-tuning, set `model.lora.enabled=true` and keep
`model.network.visual_encoder.transformer_engine=false`; TAO Core's
Cosmos-Embed1 config notes that PEFT cannot inject adapters into Transformer
Engine layers. Treat the LoRA fields above as the first candidate parameters
for manual tuning or AutoML-style search before unfreezing larger model blocks.
Avoid changing `target_modules` or `modules_to_save` unless the user explicitly
needs custom adapter placement.
## S3 Staging
The Cosmos-Embed1 CLI consumes local paths and Python globs, not raw `s3://.../*.mp4` URIs. For S3-backed runs, first stage a subset or full dataset to the execution host/container filesystem, then use local paths such as `/data/video/*.mp4` in the spec.
Recommended S3 layout for staged MSR-VTT data:
```text
s3://bucket/path/cosmos-embed/msrvtt-subset/
├── msrvtt_test_1k.json
└── video/
├── video7020.mp4
└── ...
```
After downloading/syncing that prefix into the mounted `data/` directory, use the same Docker commands above.
## Outputs
```text
results/
├── train/
│ ├── cosmos_embed1_model_latest.pth
│ ├── cosmos_embed1_model_<iter>.pth
│ └── experiment.yaml
├── evaluate/
│ ├── metrics.json
│ └── experiment.yaml
├── inference/
│ ├── results.json
│ └── experiment.yaml
├── export/
│ ├── cosmos_embed1_combined.onnx
│ └── export_config.yaml
└── export_hf/
└── cosmos_embed1_hf/
```
## Known Pitfalls
| Symptom | Cause | Fix |
|---|---|---|
| `MSRVTTDataset: 0 videos found` | `mp4_urls` is not a local glob or metadata filenames do not match videos. | Mount data into the container and set `mp4_urls=/data/video/*.mp4`. |
| HF download/auth failure | Missing or invalid `HF_TOKEN`, or model agreement not accepted. | Accept the model terms and pass `-e HF_TOKEN`. |
| `cannot import name 'Imports' from 'wandb.proto.wandb_telemetry_pb2'` | `wandb==0.21.0` in the container is incompatible with `protobuf==7.x`. | Run `python -m pip install "protobuf<7"` in the container before invoking `cosmos-embed1`. |
| Resume fails with `Model does not implement 'apply_fsdp'` | Single-GPU resume loaded a consolidated checkpoint while `model.fsdp_shard_size` stayed at the default 8. | Set `model.fsdp_shard_size=1` for local single-GPU resume/retrain. |
| LoRA injection failure | Transformer Engine visual encoder is enabled. | Set `model.network.visual_encoder.transformer_engine=false`. |
| ONNX/HF export complains about missing components | Export checkpoint is partial or adapter-only. | Use a full checkpoint or configure pretrained visual/text sources before export. |
| CUDA OOM | Batch/resolution too high for the GPU. | Reduce batch size, use 224p, enable LoRA, or use more GPUs. |
© NVIDIA Corporation · Apache-2.0 · NVIDIA/skills