Skip to content

Commit 21230f9

Browse files
yy-code-nvclaude
andcommitted
Release: sync cosmos-framework tree from internal via release.sh pipeline
Ran packages/cosmos-framework-release/release.sh against current i4 source: - 451 files in mapping → 152 modified + 15 new in target - Includes COSMOS-RELEASE-* directive application, license/license-header rewrite, redactions, and import rewrites (cosmos.* → cosmos_framework.*). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 016c96d commit 21230f9

167 files changed

Lines changed: 7084 additions & 1558 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cosmos_framework/auxiliary/guardrail/common/presets.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ def create_video_guardrail_runner(offload_model_to_cpu: bool = False) -> Guardra
2727
"""Create the video guardrail runner."""
2828
return GuardrailRunner(
2929
safety_models=[
30-
# VideoContentSafetyFilter(offload_model_to_cpu=offload_model_to_cpu), # Too many false positives
31-
],
30+
#VideoContentSafetyFilter(offload_model_to_cpu=offload_model_to_cpu)
31+
# Too many false positives, add back when fixed
32+
],
3233
postprocessors=[RetinaFaceFilter(offload_model_to_cpu=offload_model_to_cpu)],
3334
)
3435

cosmos_framework/callbacks/compile_tokenizer.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"""Training callback that defers AOT compilation of the VAE tokenizer.
55
66
The actual compilation logic lives in
7-
:meth:`~projects.cosmos3.vfm.tokenizers.wan2pt2_vae_4x16x16.Wan2pt2VAEInterface.compile_encode`.
7+
:meth:`~cosmos_framework.model.vfm.tokenizers.wan2pt2_vae_4x16x16.Wan2pt2VAEInterface.compile_encode`.
88
This module provides a :class:`CompileTokenizer` callback that invokes it
99
at the right point during training (after ``compile_after_iterations``
1010
steps, to avoid NCCL timeouts during CUDA/cuDNN warm-up).
@@ -21,6 +21,7 @@
2121
"""
2222

2323
from collections.abc import Sequence
24+
from typing import Literal
2425

2526
import torch
2627

@@ -43,6 +44,10 @@ def __init__(
4344
enabled: bool = False,
4445
compile_after_iterations: int = 3,
4546
warmup_resolutions: Sequence[str] | None = None,
47+
backend: Literal["cudagraphs", "inductor"] = "inductor",
48+
mode: Literal["reduce-overhead", "max-autotune"] | None = "reduce-overhead",
49+
fullgraph: bool = False,
50+
dynamic: bool = False,
4651
):
4752
"""
4853
Args:
@@ -60,6 +65,10 @@ def __init__(
6065
self.compile_after_iterations: int = compile_after_iterations
6166
self.skip_counter: int = 0
6267
self.warmup_resolutions: Sequence[str] | None = warmup_resolutions
68+
self.backend: Literal["cudagraphs", "inductor"] = backend
69+
self.mode: Literal["reduce-overhead", "max-autotune"] | None = mode
70+
self.fullgraph: bool = fullgraph
71+
self.dynamic: bool = dynamic
6372

6473
if self.enabled:
6574
if self.warmup_resolutions is None:
@@ -101,6 +110,10 @@ def on_training_step_start(
101110
tokenizer.compile_encode(
102111
self.warmup_resolutions,
103112
output_dir=self.config.job.path_local,
113+
backend=self.backend,
114+
mode=self.mode,
115+
fullgraph=self.fullgraph,
116+
dynamic=self.dynamic,
104117
)
105118

106119
self.skip_counter += 1

cosmos_framework/callbacks/data_stats.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ def on_training_step_end(
5151

5252
# Handle case where dataset_name gets batched into a list
5353
if isinstance(dataset_name, list):
54-
5554
assert len(dataset_name) == 1, "dataset_name should be a list of 1"
5655
dataset_name = dataset_name[0]
5756

cosmos_framework/callbacks/dataloader_state.py

Lines changed: 8 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,14 @@ class DataLoaderStateCallback(Callback):
2626
def __init__(
2727
self,
2828
distributor_type: str | None = None,
29-
name: str = "",
3029
) -> None:
3130
super().__init__()
3231
self.distributor_type = distributor_type
33-
self.name = name
3432
self.config: Any = None
3533
self.state: dict[int, NoReplaceShardlistState] = {}
3634
self.verbose = True
3735

3836
def _update_state_from_batch(self, data_batch: dict[str, torch.Tensor]) -> None:
39-
if "sample_worker_id" not in data_batch:
40-
return # batch has no position metadata (shuffle=False or iterable data_source)
4137
worker_ids = data_batch["sample_worker_id"].tolist() # [B]
4238
epochs = data_batch["sample_epoch"].tolist() # [B]
4339
indices = data_batch["sample_index"].tolist() # [B]
@@ -50,8 +46,6 @@ def _update_state_from_batch(self, data_batch: dict[str, torch.Tensor]) -> None:
5046
):
5147
self.state[worker_id] = NoReplaceShardlistState(epoch=epoch, index=index)
5248

53-
_ACTIVE_DISTRIBUTOR_TYPES = ("no_replace", "data_packer")
54-
5549
def on_training_step_batch_end(
5650
self,
5751
model: ImaginaireModel,
@@ -60,7 +54,7 @@ def on_training_step_batch_end(
6054
loss: torch.Tensor,
6155
iteration: int = 0,
6256
) -> None:
63-
if self.distributor_type in self._ACTIVE_DISTRIBUTOR_TYPES:
57+
if self.distributor_type == "no_replace":
6458
self._update_state_from_batch(data_batch)
6559

6660
def on_training_step_end(
@@ -71,7 +65,7 @@ def on_training_step_end(
7165
loss: torch.Tensor,
7266
iteration: int = 0,
7367
) -> None:
74-
if self.distributor_type in self._ACTIVE_DISTRIBUTOR_TYPES:
68+
if self.distributor_type == "no_replace":
7569
if self.verbose:
7670
if iteration % self.config.trainer.logging_iter == 0:
7771
msg = "\n"
@@ -80,10 +74,10 @@ def on_training_step_end(
8074
log.info(msg)
8175

8276
def has_checkpoint_state(self) -> bool:
83-
return self.distributor_type in self._ACTIVE_DISTRIBUTOR_TYPES
77+
return self.distributor_type == "no_replace"
8478

8579
def state_dict(self) -> dict[int, dict[str, int]]:
86-
if self.distributor_type not in self._ACTIVE_DISTRIBUTOR_TYPES:
80+
if self.distributor_type != "no_replace":
8781
return {}
8882

8983
state_dict: dict[int, dict[str, int]] = {}
@@ -96,122 +90,18 @@ def state_dict(self) -> dict[int, dict[str, int]]:
9690
return state_dict
9791

9892
def load_state_dict(self, state_dict: dict[int, dict[str, int]]) -> None:
99-
if self.distributor_type not in self._ACTIVE_DISTRIBUTOR_TYPES:
93+
if self.distributor_type != "no_replace":
10094
return
10195

10296
if not state_dict:
10397
log.info("No dataloader state found in checkpoint")
10498
return
10599

106100
self.state = {}
107-
# Build env var prefix. For data_packer, namespacing avoids conflicts
108-
# when multiple DataPackerDataLoader instances share the same process
109-
# (e.g. inside JointDataPackerDataLoader). name="" → original format.
110-
_dp_pfx = f"DP_STATE_{self.name}_" if self.name else "DP_STATE_"
111101
for worker_id, per_worker_state in state_dict.items():
112102
epoch = per_worker_state["epoch"]
113103
index = per_worker_state["index"]
114104
self.state[worker_id] = NoReplaceShardlistState(epoch=epoch, index=index)
115-
if self.distributor_type == "data_packer":
116-
os.environ[f"{_dp_pfx}WORKER_{worker_id}_EPOCH"] = str(epoch)
117-
os.environ[f"{_dp_pfx}WORKER_{worker_id}_INDEX"] = str(index)
118-
log.info(f"Loaded data_packer dataloader state for worker {worker_id}: epoch={epoch}, index={index}")
119-
else:
120-
os.environ[f"NSL_STATE_WORKER_{worker_id}_EPOCH"] = str(epoch)
121-
os.environ[f"NSL_STATE_WORKER_{worker_id}_INDEX"] = str(index)
122-
log.info(f"Loaded no_replace dataloader state for worker {worker_id}: epoch={epoch}, index={index}")
123-
124-
125-
class JointDataLoaderStateCallback(Callback):
126-
"""Checkpoint/resume state for ``JointDataPackerDataLoader``.
127-
128-
Manages two levels of state in a single DCP checkpoint entry
129-
(``checkpoint_component = "dataloader"``):
130-
131-
1. **Outer** ``global_id`` — the number of batches the outer loader has
132-
yielded. Restored via ``outer_loader.set_start_iteration(global_id)``
133-
so the deterministic dataset-selection sequence resumes from the correct
134-
step.
135-
136-
2. **Inner** per-dataset, per-worker ``(epoch, index)`` — one
137-
``DataLoaderStateCallback`` per inner loader, keyed by the dataset name.
138-
Each inner callback sets namespaced env vars on ``load_state_dict`` so
139-
workers fast-forward to the saved sample position.
140-
141-
Usage in experiment configs::
142-
143-
joint_loader = JointDataPackerDataLoader(dataloaders={...}, seed=42)
144-
exp["dataloader_train"] = joint_loader
145-
exp["trainer"]["callbacks"]["dataloader_state"] = JointDataLoaderStateCallback(
146-
outer_loader=joint_loader,
147-
distributor_type="data_packer",
148-
)
149-
150-
The ``checkpoint_component = "dataloader"`` class attribute ensures the DCP
151-
checkpointer's ``_DataloaderWrapper`` discovers exactly this callback (it
152-
picks the first matching callback). Do **not** also register standalone
153-
``DataLoaderStateCallback`` instances for the inner loaders — this class
154-
already handles them all.
155-
"""
156-
157-
checkpoint_component: str = "dataloader"
158-
159-
def __init__(
160-
self,
161-
outer_loader: Any,
162-
distributor_type: str = "data_packer",
163-
) -> None:
164-
super().__init__()
165-
self._outer = outer_loader
166-
self._inner: dict[str, DataLoaderStateCallback] = {
167-
name: DataLoaderStateCallback(distributor_type=distributor_type, name=name)
168-
for name in outer_loader._names
169-
}
170-
self.config: Any = None
171-
172-
def _update_state_from_batch(self, batch: dict) -> None:
173-
name = batch.get("dataset_name")
174-
if name in self._inner:
175-
self._inner[name]._update_state_from_batch(batch)
176-
177-
def on_training_step_batch_end(
178-
self,
179-
model: Any,
180-
data_batch: dict,
181-
output_batch: dict,
182-
loss: Any,
183-
iteration: int = 0,
184-
) -> None:
185-
self._update_state_from_batch(data_batch)
186-
187-
def on_training_step_end(
188-
self,
189-
model: Any,
190-
data_batch: dict,
191-
output_batch: dict,
192-
loss: Any,
193-
iteration: int = 0,
194-
) -> None:
195-
if self.config and iteration % self.config.trainer.logging_iter == 0:
196-
msg = f"\nJointDataPackerDataLoader global_id={self._outer._global_id}\n"
197-
for name, cb in self._inner.items():
198-
for wid, state in cb.state.items():
199-
msg += f" [{name}] worker {wid}: epoch={state.epoch}, index={state.index}\n"
200-
log.info(msg)
201-
202-
def has_checkpoint_state(self) -> bool:
203-
return True
204-
205-
def state_dict(self) -> dict:
206-
return {
207-
"global_id": self._outer._global_id,
208-
**{name: cb.state_dict() for name, cb in self._inner.items()},
209-
}
210-
211-
def load_state_dict(self, state: dict) -> None:
212-
global_id = state.get("global_id", 0)
213-
self._outer.set_start_iteration(global_id)
214-
log.info(f"JointDataLoaderStateCallback: resumed outer global_id={global_id}")
215-
for name, cb in self._inner.items():
216-
if name in state:
217-
cb.load_state_dict(state[name])
105+
os.environ[f"NSL_STATE_WORKER_{worker_id}_EPOCH"] = str(epoch)
106+
os.environ[f"NSL_STATE_WORKER_{worker_id}_INDEX"] = str(index)
107+
log.info(f"Loaded no replace dataloader state for worker {worker_id}: epoch={epoch}, index={index}")

cosmos_framework/callbacks/every_n_draw_sample.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,6 @@ def x0_pred(self, trainer, model, data_batch, output_batch, loss, iteration):
154154
tag = "ema" if self.is_ema else "reg"
155155

156156
log.debug("starting data and condition model", rank0_only=False)
157-
158-
159157
data_clean = model.get_data_and_condition(data_batch)
160158
raw_data = data_clean.raw_state_vision
161159
x0 = data_clean.x0_tokens_vision
@@ -185,7 +183,6 @@ def x0_pred(self, trainer, model, data_batch, output_batch, loss, iteration):
185183
log.debug(f"done denoising {sigma}", rank0_only=False)
186184
mse_loss = distributed.dist_reduce_tensor(F.mse_loss(sample, x0))
187185
mse_loss_list.append(mse_loss)
188-
189186
if hasattr(model, "decode"):
190187
sample = model.decode(sample)
191188
to_show.append(sample.float().cpu())
@@ -316,7 +313,6 @@ def sample(self, trainer, model, data_batch, output_batch, loss, iteration):
316313
for sample_idx in range(data_clean.batch_size):
317314
n_vis = num_items[sample_idx]
318315
# First item(s) are condition, last item is generation target
319-
320316
# but we need to support multiple conditions per sample in the future. Current code
321317
# can handle this without throwing an error.
322318
condition_images.append(raw_data[vis_offset]) # source image (1, C, 1, H, W)

cosmos_framework/callbacks/grad_clip.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def _clip_grad(
132132
# `torch.distributed._tensor.ops.math_ops._NormPartial`.
133133
# We can simply reduce the DTensor to get the total norm in this
134134
# tensor's process group and then convert it to a local tensor.
135-
135+
# NOTE: It has two purposes:
136136
# 1. to make sure the total norm is computed correctly when PP is used (see below)
137137
# 2. to return a reduced mesh_norm tensor whose .item() would return the correct value
138138
if isinstance(mesh_norm, DTensor):

cosmos_framework/callbacks/hf_export.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,11 @@ def on_save_checkpoint(self, model: Any, state_dict: dict[str, Any]) -> None:
137137
if not isinstance(model, VLMModel):
138138
# The legacy vlm/train.py path passes model_parts: list[nn.Module] (raw HF
139139
# models without the VLMModel attribute structure). HF export requires the
140-
# VLMModel wrapper, which is only available via the unified cosmos_framework/scripts/train.py path.
140+
# VLMModel wrapper, which is only available via the unified scripts/train.py path.
141141
if isinstance(model, list):
142142
log.warning(
143143
"[HFExportCallback] Received model_parts (list) instead of VLMModel. "
144-
"HF export requires the unified training path (cosmos_framework/scripts/train.py). Skipping."
144+
"HF export requires the unified training path (scripts/train.py). Skipping."
145145
)
146146
else:
147147
log.warning(

cosmos_framework/callbacks/mfu.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ def _ensure_initialised(self, model: ImaginaireModel) -> None:
138138
ac_cfg = getattr(model_cfg, "activation_checkpointing", None)
139139
ac_mode = getattr(ac_cfg, "mode", "none")
140140

141-
142141
# Some activations don't need to be recomputed under selective AC, so
143142
# we need to remove them from the FLOP computation.
144143
self._use_activation_checkpointing = ac_mode != "none"

cosmos_framework/callbacks/wandb_log_eval.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ def on_validation_step_end(
8888

8989
# Handle case where dataset_name gets batched into a list
9090
if isinstance(dataset_name, list):
91-
9291
assert len(dataset_name) == 1, "dataset_name should be a list of 1"
9392
dataset_name = dataset_name[0]
9493

cosmos_framework/checkpoint/dcp.py

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
set_model_state_dict,
6464
)
6565
from torch.distributed.checkpoint.stateful import Stateful
66+
from torch.nn.modules.module import _IncompatibleKeys
6667

6768
from cosmos_framework.checkpoint.base import AbstractCheckpointer
6869
from cosmos_framework.checkpoint.s3_filesystem import S3StorageReader, S3StorageWriter
@@ -85,11 +86,11 @@ def __init__(self, model: nn.Module) -> None:
8586
def state_dict(self) -> dict[str, Any]:
8687
return get_model_state_dict(self.model)
8788

88-
def load_state_dict(self, state_dict: dict[str, Any]) -> None:
89-
set_model_state_dict(
89+
def load_state_dict(self, state_dict: dict[str, Any]) -> _IncompatibleKeys:
90+
return set_model_state_dict(
9091
self.model,
9192
model_state_dict=state_dict,
92-
options=StateDictOptions(strict=True),
93+
options=StateDictOptions(strict=False),
9394
)
9495

9596

@@ -539,28 +540,13 @@ def load(
539540
"Ensure the model has net_ema submodule."
540541
)
541542
_state_dict[sd_key] = _state_dict[key_ema]
542-
elif warm_start and any(str(s).startswith("net_ema") for s in self.keys_to_skip_loading):
543-
# Only when net_ema.* is explicitly skipped on load (e.g. an HF->DCP
544-
# init from convert_model_to_dcp that has only net.*): the skipped
545-
# net_ema.* keep build_net() construction values (random init when
546-
# vlm_config.pretrained_weights.enabled=False), which would seed EMA
547-
# from random weights -> copy net.* -> net_ema.* so EMA starts from the
548-
# freshly-loaded init. When net_ema.* IS loaded (e.g. a training DCP
549-
# that carries a trained EMA), do NOT clobber it.
550-
log.info("Warm start: net_ema. skipped on load -> resetting net_ema = net.")
551-
for sd_key in list(_state_dict.keys()):
552-
if sd_key.startswith("net."):
553-
key_ema = "net_ema." + sd_key.removeprefix("net.")
554-
if key_ema in _state_dict:
555-
_state_dict[key_ema] = _state_dict[sd_key]
556543
results = _model_wrapper.load_state_dict(_state_dict)
557-
if results is not None:
558-
if len(results.missing_keys) > 0:
559-
raise ValueError(f"Missing keys (not found in checkpoint): {results.missing_keys}")
560-
if len(results.unexpected_keys) > 0:
561-
raise ValueError(
562-
f"Unexpected keys (found in checkpoint but not in model): {results.unexpected_keys}"
563-
)
544+
if len(results.missing_keys) > 0:
545+
raise ValueError(f"Missing keys (not found in checkpoint): {results.missing_keys}")
546+
if len(results.unexpected_keys) > 0:
547+
raise ValueError(
548+
f"Unexpected keys (found in checkpoint but not in model): {results.unexpected_keys}"
549+
)
564550

565551
elif key == "optim":
566552
log.info("- Loading the optimizer...")

0 commit comments

Comments
 (0)