|
1 | 1 | import copy |
2 | | -import math |
3 | 2 |
|
4 | 3 | import torch |
5 | 4 |
|
6 | | -from ...configuration_utils import FrozenDict |
7 | 5 | from ...models.transformers.transformer_cosmos3 import Cosmos3OmniTransformer |
8 | 6 | from ...pipelines.cosmos.pipeline_cosmos3_omni import _EMBODIMENT_TO_DOMAIN_ID, CosmosActionCondition |
9 | 7 | from ...schedulers import UniPCMultistepScheduler |
10 | 8 | from ...utils.torch_utils import randn_tensor |
11 | | -from ...video_processor import VideoProcessor |
12 | 9 | from ..modular_pipeline import ModularPipelineBlocks, PipelineState |
13 | 10 | from ..modular_pipeline_utils import ComponentSpec, InputParam, OutputParam |
14 | 11 | from .modular_pipeline import Cosmos3OmniModularPipeline |
@@ -965,163 +962,6 @@ def __call__(self, components: Cosmos3OmniModularPipeline, state: PipelineState) |
965 | 962 | return components, state |
966 | 963 |
|
967 | 964 |
|
968 | | -class Cosmos3TransferSetupStep(ModularPipelineBlocks): |
969 | | - model_name = "cosmos3-omni" |
970 | | - |
971 | | - @property |
972 | | - def description(self) -> str: |
973 | | - return ( |
974 | | - "Preprocesses the transfer control videos and resolves the autoregressive chunk geometry " |
975 | | - "(total_frames / chunk_frames / num_chunks / stride). Chunk-invariant, so it runs once before the loop." |
976 | | - ) |
977 | | - |
978 | | - @property |
979 | | - def expected_components(self) -> list[ComponentSpec]: |
980 | | - return [ |
981 | | - ComponentSpec( |
982 | | - "video_processor", |
983 | | - VideoProcessor, |
984 | | - config=FrozenDict({"vae_scale_factor": 16, "resample": "bilinear"}), |
985 | | - default_creation_method="from_config", |
986 | | - ), |
987 | | - ] |
988 | | - |
989 | | - @property |
990 | | - def inputs(self) -> list[InputParam]: |
991 | | - return [ |
992 | | - InputParam( |
993 | | - name="control_videos", |
994 | | - type_hint=dict, |
995 | | - required=True, |
996 | | - description="Mapping of hint name (edge/blur/depth/seg/wsm) to the control video for that modality.", |
997 | | - ), |
998 | | - InputParam( |
999 | | - name="height", type_hint=int, default=None, description="Height of the generated video in pixels." |
1000 | | - ), |
1001 | | - InputParam( |
1002 | | - name="width", type_hint=int, default=None, description="Width of the generated video in pixels." |
1003 | | - ), |
1004 | | - InputParam( |
1005 | | - name="num_frames", |
1006 | | - type_hint=int, |
1007 | | - default=None, |
1008 | | - description="Optional cap on the number of output frames (defaults to the control video length).", |
1009 | | - ), |
1010 | | - InputParam( |
1011 | | - name="num_video_frames_per_chunk", |
1012 | | - type_hint=int, |
1013 | | - default=None, |
1014 | | - description="Number of pixel frames generated per autoregressive chunk.", |
1015 | | - ), |
1016 | | - InputParam( |
1017 | | - name="num_conditional_frames", |
1018 | | - type_hint=int, |
1019 | | - default=1, |
1020 | | - description="Number of frames each chunk reuses from the previous chunk's tail.", |
1021 | | - ), |
1022 | | - ] |
1023 | | - |
1024 | | - @property |
1025 | | - def intermediate_outputs(self) -> list[OutputParam]: |
1026 | | - return [ |
1027 | | - OutputParam("height", type_hint=int, description="Resolved output height in pixels."), |
1028 | | - OutputParam("width", type_hint=int, description="Resolved output width in pixels."), |
1029 | | - OutputParam( |
1030 | | - "control_frames", |
1031 | | - type_hint=dict, |
1032 | | - description="Preprocessed, time-padded control maps in canonical hint order.", |
1033 | | - ), |
1034 | | - OutputParam("total_frames", type_hint=int, description="Total number of output frames to generate."), |
1035 | | - OutputParam("chunk_frames", type_hint=int, description="Number of pixel frames per autoregressive chunk."), |
1036 | | - OutputParam("num_chunks", type_hint=int, description="Number of autoregressive chunks."), |
1037 | | - OutputParam("stride", type_hint=int, description="Frame stride between consecutive chunks."), |
1038 | | - ] |
1039 | | - |
1040 | | - @torch.no_grad() |
1041 | | - def __call__(self, components: Cosmos3OmniModularPipeline, state: PipelineState) -> PipelineState: |
1042 | | - block_state = self.get_block_state(state) |
1043 | | - device = components._execution_device |
1044 | | - dtype = components.transformer.dtype |
1045 | | - |
1046 | | - if block_state.height is None: |
1047 | | - block_state.height = 720 |
1048 | | - if block_state.width is None: |
1049 | | - block_state.width = 1280 |
1050 | | - |
1051 | | - # Canonical hint order used both to validate and to order the preprocessed control maps. |
1052 | | - hint_order = ["edge", "blur", "depth", "seg", "wsm"] |
1053 | | - control_videos = block_state.control_videos |
1054 | | - if not isinstance(control_videos, dict) or not control_videos: |
1055 | | - raise ValueError("`control_videos` must be a non-empty dict mapping hint name -> control video.") |
1056 | | - unknown = [k for k in control_videos if k not in hint_order] |
1057 | | - if unknown: |
1058 | | - raise ValueError(f"`control_videos` has unknown hint(s) {unknown}; expected keys from {hint_order}.") |
1059 | | - if any(v is None for v in control_videos.values()): |
1060 | | - raise ValueError("`control_videos` entries must be loaded videos, not None.") |
1061 | | - |
1062 | | - tcf = components.vae_scale_factor_temporal |
1063 | | - sf = components.vae_scale_factor_spatial |
1064 | | - if block_state.height % sf != 0 or block_state.width % sf != 0: |
1065 | | - raise ValueError( |
1066 | | - f"`height` and `width` must be multiples of {sf}, got ({block_state.height}, {block_state.width})." |
1067 | | - ) |
1068 | | - |
1069 | | - # Preprocess every control map to [1, 3, T, H, W] in [-1, 1] at target geometry, in canonical hint order. |
1070 | | - # The dict preserves this order, so downstream blocks just iterate control_frames (no separate hint_keys). |
1071 | | - hint_keys = [k for k in hint_order if k in control_videos] |
1072 | | - control_frames = { |
1073 | | - key: components.video_processor.preprocess_video( |
1074 | | - control_videos[key], height=block_state.height, width=block_state.width |
1075 | | - ).to(device=device, dtype=dtype) |
1076 | | - for key in hint_keys |
1077 | | - } |
1078 | | - |
1079 | | - # Output frame count / chunking come from the (first) control video, optionally capped by num_frames. |
1080 | | - total_frames = next(iter(control_frames.values())).shape[2] |
1081 | | - if block_state.num_frames is not None: |
1082 | | - total_frames = min(total_frames, block_state.num_frames) |
1083 | | - total_frames = max(1, total_frames) |
1084 | | - |
1085 | | - per_chunk = ( |
1086 | | - block_state.num_video_frames_per_chunk |
1087 | | - if block_state.num_video_frames_per_chunk is not None |
1088 | | - else total_frames |
1089 | | - ) |
1090 | | - chunk_frames = 1 if total_frames == 1 else per_chunk |
1091 | | - chunk_frames = math.ceil((chunk_frames - 1) / tcf) * tcf + 1 |
1092 | | - |
1093 | | - if total_frames <= chunk_frames: |
1094 | | - num_chunks, stride = 1, chunk_frames |
1095 | | - else: |
1096 | | - stride = chunk_frames - block_state.num_conditional_frames |
1097 | | - if stride <= 0: |
1098 | | - raise ValueError("`num_conditional_frames` must be smaller than `num_video_frames_per_chunk`.") |
1099 | | - remaining = total_frames - chunk_frames |
1100 | | - num_chunks = 1 + (remaining // stride + (1 if remaining % stride else 0)) |
1101 | | - |
1102 | | - # Reflect-pad each control map along time up to `padded` (repeat the last frame once the clip is too short to |
1103 | | - # keep reflecting). No truncation here; per-chunk slicing happens later. |
1104 | | - padded = max(total_frames, chunk_frames) |
1105 | | - control_frames_padded = {} |
1106 | | - for key, frames in control_frames.items(): |
1107 | | - while frames.shape[2] < padded: |
1108 | | - pad_len = min(frames.shape[2] - 1, padded - frames.shape[2]) |
1109 | | - if pad_len <= 0: |
1110 | | - pad_frame = frames[:, :, -1:].repeat(1, 1, padded - frames.shape[2], 1, 1) |
1111 | | - frames = torch.cat([frames, pad_frame], dim=2) |
1112 | | - break |
1113 | | - frames = torch.cat([frames, frames.flip(dims=[2])[:, :, :pad_len]], dim=2) |
1114 | | - control_frames_padded[key] = frames |
1115 | | - block_state.control_frames = control_frames_padded |
1116 | | - block_state.total_frames = total_frames |
1117 | | - block_state.chunk_frames = chunk_frames |
1118 | | - block_state.num_chunks = num_chunks |
1119 | | - block_state.stride = stride |
1120 | | - |
1121 | | - self.set_block_state(state, block_state) |
1122 | | - return components, state |
1123 | | - |
1124 | | - |
1125 | 965 | class Cosmos3TransferPrepareLatentsStep(ModularPipelineBlocks): |
1126 | 966 | model_name = "cosmos3-omni" |
1127 | 967 |
|
|
0 commit comments