Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions mstar/model/cosmos3/components/packing.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,10 +497,18 @@ def build_static_inputs(
pos_dtype = torch.float32 if any(p.is_floating_point() for p in parts) else torch.long
position_ids = torch.cat([p.to(pos_dtype) for p in parts], dim=1)
static["position_ids"] = position_ids
static["gen_position_ids"] = _gen_band(position_ids, text["und_len"])
static["sequence_length"] = sequence_length
return static


def _gen_band(position_ids: torch.Tensor, und_len: int) -> torch.Tensor:
"""The generation band's position ids as their own tensor. A slice of
``position_ids`` has the prompt length in its stride, which the compiled
denoise step guards on, so every new prompt length would recompile it."""
return position_ids[:, und_len:].contiguous()


def build_t2i_static_inputs(
input_ids: list[int],
latent_shape: tuple[int, int, int, int, int],
Expand Down Expand Up @@ -585,5 +593,6 @@ def build_action_static_inputs(
"num_noisy_action_tokens": len(action_noisy),
"action_mode": mode,
"position_ids": position_ids,
"gen_position_ids": _gen_band(position_ids, text["und_len"]),
"sequence_length": curr + action_chunk_size,
}
26 changes: 12 additions & 14 deletions mstar/model/cosmos3/submodules.py
Original file line number Diff line number Diff line change
Expand Up @@ -1758,16 +1758,16 @@ def _forward_video_sound_gen(self, attn, st, latents, sound_latents, time_index,

if not cfg_active:
velocity, sound_v = self.transformer.denoise_step(
latents, vts, st["cond"]["position_ids"][:, st["cond"]["und_len"]:],
latents, vts, st["cond"]["gen_position_ids"],
st["cond"]["vision_token_shapes"], st["cond"]["vision_noisy_frame_indexes"],
st["cond"]["mse_gen_indexes"], COND_LABEL, attn,
**self._sound_kwargs(st["cond"], sound_latents, sts),
)
elif self.batched_cfg:
(cond_v, s_c), (uncond_v, s_u) = self.transformer.denoise_step_batched_cfg(
latents, vts,
st["cond"]["position_ids"][:, st["cond"]["und_len"]:],
st["uncond"]["position_ids"][:, st["uncond"]["und_len"]:],
st["cond"]["gen_position_ids"],
st["uncond"]["gen_position_ids"],
st["cond"]["vision_token_shapes"],
st["cond"]["vision_noisy_frame_indexes"],
st["cond"]["mse_gen_indexes"], CFG_BATCHED_LABEL, attn,
Expand All @@ -1777,13 +1777,13 @@ def _forward_video_sound_gen(self, attn, st, latents, sound_latents, time_index,
sound_v = s_u + st["gs"] * (s_c - s_u)
else:
cond_v, s_c = self.transformer.denoise_step(
latents, vts, st["cond"]["position_ids"][:, st["cond"]["und_len"]:],
latents, vts, st["cond"]["gen_position_ids"],
st["cond"]["vision_token_shapes"], st["cond"]["vision_noisy_frame_indexes"],
st["cond"]["mse_gen_indexes"], COND_LABEL, attn,
**self._sound_kwargs(st["cond"], sound_latents, sts),
)
uncond_v, s_u = self.transformer.denoise_step(
latents, vts, st["uncond"]["position_ids"][:, st["uncond"]["und_len"]:],
latents, vts, st["uncond"]["gen_position_ids"],
st["uncond"]["vision_token_shapes"], st["uncond"]["vision_noisy_frame_indexes"],
st["uncond"]["mse_gen_indexes"], UNCOND_LABEL, attn,
**self._sound_kwargs(st["uncond"], sound_latents, sts),
Expand All @@ -1806,11 +1806,10 @@ def _forward_video_sound_gen(self, attn, st, latents, sound_latents, time_index,
}

def _denoise_action(self, attn, static, latents, action_latents, vts, ats, domain, label):
und_len = static["und_len"]
return self.transformer.denoise_step(
latents,
vts,
static["position_ids"][:, und_len:],
static["gen_position_ids"],
static["vision_token_shapes"],
static["vision_noisy_frame_indexes"],
static["mse_gen_indexes"],
Expand Down Expand Up @@ -1873,8 +1872,8 @@ def _forward_action_gen(self, attn, st, latents, action_latents, time_index, **k
(video_v, action_v), (v_u, a_u) = self.transformer.denoise_step_batched_cfg(
latents,
vts,
st["cond"]["position_ids"][:, st["cond"]["und_len"]:],
st["uncond"]["position_ids"][:, st["uncond"]["und_len"]:],
st["cond"]["gen_position_ids"],
st["uncond"]["gen_position_ids"],
st["cond"]["vision_token_shapes"],
st["cond"]["vision_noisy_frame_indexes"],
st["cond"]["mse_gen_indexes"],
Expand Down Expand Up @@ -2055,8 +2054,8 @@ def _forward_batched_sound(self, engine_inputs, latents, sound_latents, time_ind
reqs.append({
"latents": lat,
"vision_timesteps": torch.full((st["cond"]["num_noisy_vision_tokens"],), t.item(), device=lat.device),
"position_ids_cond": cond["position_ids"][:, cond["und_len"]:],
"position_ids_uncond": unc["position_ids"][:, unc["und_len"]:],
"position_ids_cond": cond["gen_position_ids"],
"position_ids_uncond": unc["gen_position_ids"],
"vision_token_shapes": cond["vision_token_shapes"],
"vision_noisy_frame_indexes": cond["vision_noisy_frame_indexes"],
"vision_mse_loss_indexes": cond["mse_gen_indexes"],
Expand Down Expand Up @@ -2108,13 +2107,12 @@ def _forward_batched_action(self, engine_inputs, latents, action_latents, time_i
# step below.
t = st["scheduler"].timesteps[min(step_index, n_steps - 1)]
cond = st["cond"]
und = cond["und_len"]
req = {
"latents": lat,
"action_latents": act,
"vision_timesteps": torch.full((st["cond"]["num_noisy_vision_tokens"],), t.item(), device=lat.device),
"action_timesteps": torch.full((st["cond"]["num_noisy_action_tokens"],), t.item(), device=lat.device),
"position_ids_cond": cond["position_ids"][:, und:],
"position_ids_cond": cond["gen_position_ids"],
"vision_token_shapes": cond["vision_token_shapes"],
"vision_noisy_frame_indexes": cond["vision_noisy_frame_indexes"],
"vision_mse_loss_indexes": cond["mse_gen_indexes"],
Expand All @@ -2125,7 +2123,7 @@ def _forward_batched_action(self, engine_inputs, latents, action_latents, time_i
}
if with_cfg:
unc = st["uncond"]
req["position_ids_uncond"] = unc["position_ids"][:, unc["und_len"]:]
req["position_ids_uncond"] = unc["gen_position_ids"]
reqs.append(req)
meta.append((rid, st, lat, act, ti, t))

Expand Down
27 changes: 27 additions & 0 deletions mstar/model/cosmos3/tests/test_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from mstar.model.cosmos3.components.packing import (
action_condition_frame_indexes,
build_action_static_inputs,
build_static_inputs,
get_3d_mrope_ids_action_tokens,
vision_condition_frame_indexes,
)
Expand Down Expand Up @@ -118,6 +119,32 @@ def test_action_static_layout() -> None:
assert s["action_mse_loss_indexes"].numel() == exp_act_noisy


def test_gen_position_ids_do_not_depend_on_prompt_length() -> None:
"""The denoise step is compiled with dynamic=False, which guards on sizes
and strides, so the generation band's position ids must have the same
layout for every prompt length."""
cfg = _cfg()
latent_shape = (1, cfg.latent_channel, 3, 4, 4)
builds = {
"action": lambda ids: build_action_static_inputs(
ids, latent_shape, 8, "policy", cfg, cfg.vae.scale_factor_temporal,
fps=10.0, action_fps=10.0, action_start_offset=1, device="cpu",
),
"sound": lambda ids: build_static_inputs(
ids, latent_shape, cfg, cfg.vae.scale_factor_temporal, fps=10.0, device="cpu",
sound_latent_frames=4,
),
}
for build in builds.values():
layouts = set()
for n in (4, 9, 23):
s = build(list(range(1, n + 1)))
gen = s["gen_position_ids"]
assert torch.equal(gen, s["position_ids"][:, s["und_len"]:])
layouts.add((tuple(gen.shape), gen.stride(), gen.storage_offset()))
assert len(layouts) == 1


def _run_mode(model, cfg, mode, latent_shape, action_chunk, ids):
s = build_action_static_inputs(
ids, latent_shape, action_chunk, mode, cfg, cfg.vae.scale_factor_temporal,
Expand Down
Loading