44"""Omni-specific argument parsing for python -m dynamo.vllm.omni."""
55
66import argparse
7+ import dataclasses
78import logging
89from typing import Optional
910
2425logger = logging .getLogger (__name__ )
2526
2627
27- class OmniArgGroup (ArgGroup ):
28- """Diffusion pipeline kwargs passed through to AsyncOmni() constructor.
28+ @dataclasses .dataclass
29+ class OmniDiffusionKwargs :
30+ """AsyncOmni constructor kwargs for diffusion engine configuration.
31+
32+ Every field here is passed directly to AsyncOmni(**kwargs) and consumed by
33+ _create_default_diffusion_stage_cfg() in vllm-omni. Adding a new vllm-omni
34+ diffusion flag only requires adding it here and to OmniArgGroup — the
35+ passthrough in base_handler is automatic.
36+ """
37+
38+ enable_layerwise_offload : bool = False
39+ layerwise_num_gpu_layers : int = 1
40+ vae_use_slicing : bool = False
41+ vae_use_tiling : bool = False
42+ boundary_ratio : float = 0.875
43+ flow_shift : Optional [float ] = None
44+ cache_backend : Optional [str ] = None
45+ cache_config : Optional [str ] = None
46+ enable_cache_dit_summary : bool = False
47+ enable_cpu_offload : bool = False
48+ enforce_eager : bool = False
49+
2950
30- These are NOT part of OmniEngineArgs (which handles vLLM engine-level
31- args like model, tp, max_model_len). Instead they are direct constructor
32- kwargs for AsyncOmni and need Dynamo-side env-var (DYN_OMNI_*) support,
33- so we define them here rather than relying on the upstream arg parser.
51+ @dataclasses .dataclass
52+ class OmniParallelKwargs :
53+ """Diffusion parallelism configuration passed to DiffusionParallelConfig.
54+
55+ Every field here maps 1:1 to a DiffusionParallelConfig field (excluding
56+ tensor_parallel_size which comes from engine_args, and fixed/derived fields).
57+ Adding a new parallelism field only requires adding it here and to OmniArgGroup.
3458 """
3559
60+ ulysses_degree : int = 1
61+ ring_degree : int = 1
62+ cfg_parallel_size : int = 1
63+ vae_patch_parallel_size : int = 1
64+ use_hsdp : bool = False
65+ hsdp_shard_size : int = - 1
66+ hsdp_replicate_size : int = 1
67+
68+
69+ class OmniArgGroup (ArgGroup ):
70+ """CLI argument definitions for Dynamo vLLM-Omni."""
71+
3672 name = "dynamo-omni"
3773
3874 def add_arguments (self , parser ) -> None :
@@ -49,7 +85,6 @@ def add_arguments(self, parser) -> None:
4985 help = "Path to vLLM-Omni stage configuration YAML file (optional)." ,
5086 )
5187
52- # Video encoding
5388 add_argument (
5489 g ,
5590 flag_name = "--default-video-fps" ,
@@ -59,7 +94,7 @@ def add_arguments(self, parser) -> None:
5994 help = "Default frames per second for generated videos." ,
6095 )
6196
62- # Layerwise offloading
97+ # OmniDiffusionKwargs fields
6398 add_negatable_bool_argument (
6499 g ,
65100 flag_name = "--enable-layerwise-offload" ,
@@ -75,8 +110,6 @@ def add_arguments(self, parser) -> None:
75110 arg_type = int ,
76111 help = "Number of ready layers (blocks) to keep on GPU during generation." ,
77112 )
78-
79- # VAE optimization
80113 add_negatable_bool_argument (
81114 g ,
82115 flag_name = "--vae-use-slicing" ,
@@ -91,8 +124,6 @@ def add_arguments(self, parser) -> None:
91124 default = False ,
92125 help = "Enable VAE tiling for memory optimization in diffusion models." ,
93126 )
94-
95- # Diffusion scheduling
96127 add_argument (
97128 g ,
98129 flag_name = "--boundary-ratio" ,
@@ -113,8 +144,6 @@ def add_arguments(self, parser) -> None:
113144 arg_type = float ,
114145 help = "Scheduler flow_shift parameter (5.0 for 720p, 12.0 for 480p)." ,
115146 )
116-
117- # Cache acceleration
118147 add_argument (
119148 g ,
120149 flag_name = "--cache-backend" ,
@@ -141,8 +170,6 @@ def add_arguments(self, parser) -> None:
141170 default = False ,
142171 help = "Enable cache-dit summary logging after diffusion forward passes." ,
143172 )
144-
145- # Execution mode
146173 add_negatable_bool_argument (
147174 g ,
148175 flag_name = "--enable-cpu-offload" ,
@@ -204,7 +231,7 @@ def add_arguments(self, parser) -> None:
204231 help = "Maximum size in bytes for reference audio files (default: 50MB)." ,
205232 )
206233
207- # Diffusion parallel configuration
234+ # OmniParallelKwargs fields
208235 add_argument (
209236 g ,
210237 flag_name = "--ulysses-degree" ,
@@ -227,9 +254,43 @@ def add_arguments(self, parser) -> None:
227254 env_var = "DYN_OMNI_CFG_PARALLEL_SIZE" ,
228255 default = 1 ,
229256 arg_type = int ,
230- choices = [1 , 2 ],
257+ choices = [1 , 2 , 3 ],
231258 help = "Number of GPUs used for classifier free guidance parallelism." ,
232259 )
260+ add_argument (
261+ g ,
262+ flag_name = "--vae-patch-parallel-size" ,
263+ env_var = "DYN_OMNI_VAE_PATCH_PARALLEL_SIZE" ,
264+ default = 1 ,
265+ arg_type = int ,
266+ help = "Number of ranks used for VAE patch/tile parallelism during decode/encode." ,
267+ )
268+ add_negatable_bool_argument (
269+ g ,
270+ flag_name = "--use-hsdp" ,
271+ env_var = "DYN_OMNI_USE_HSDP" ,
272+ default = False ,
273+ help = (
274+ "Enable Hybrid Sharded Data Parallel (HSDP) for diffusion models. "
275+ "Shards model weights across GPUs to reduce per-GPU memory usage."
276+ ),
277+ )
278+ add_argument (
279+ g ,
280+ flag_name = "--hsdp-shard-size" ,
281+ env_var = "DYN_OMNI_HSDP_SHARD_SIZE" ,
282+ default = - 1 ,
283+ arg_type = int ,
284+ help = "Number of GPUs to shard model weights across when using HSDP (-1 = auto)." ,
285+ )
286+ add_argument (
287+ g ,
288+ flag_name = "--hsdp-replicate-size" ,
289+ env_var = "DYN_OMNI_HSDP_REPLICATE_SIZE" ,
290+ default = 1 ,
291+ arg_type = int ,
292+ help = "Number of HSDP replica groups (default: 1)." ,
293+ )
233294
234295 # Disaggregated stage worker flags
235296 add_argument (
@@ -244,7 +305,6 @@ def add_arguments(self, parser) -> None:
244305 "Requires --stage-configs-path."
245306 ),
246307 )
247-
248308 add_negatable_bool_argument (
249309 g ,
250310 flag_name = "--omni-router" ,
@@ -263,30 +323,18 @@ class OmniConfig(DynamoRuntimeConfig):
263323 component : str = "backend"
264324 endpoint : Optional [str ] = None
265325
266- # mirror vLLM
267326 model : str
268327 served_model_name : Optional [str ] = None
269-
270- # vLLM-Omni engine args
271328 engine_args : OmniEngineArgs
272329
273- # OmniArgGroup fields (populated by from_cli_args)
274330 stage_configs_path : Optional [str ] = None
275331 default_video_fps : int = 16
276- enable_layerwise_offload : bool = False
277- layerwise_num_gpu_layers : int = 1
278- vae_use_slicing : bool = False
279- vae_use_tiling : bool = False
280- boundary_ratio : float = 0.875
281- flow_shift : Optional [float ] = None
282- cache_backend : Optional [str ] = None
283- cache_config : Optional [str ] = None
284- enable_cache_dit_summary : bool = False
285- enable_cpu_offload : bool = False
286- enforce_eager : bool = False
287- ulysses_degree : int = 1
288- ring_degree : int = 1
289- cfg_parallel_size : int = 1
332+
333+ # Nested structs — each group of fields has a clear destination
334+ diffusion : OmniDiffusionKwargs = dataclasses .field (
335+ default_factory = OmniDiffusionKwargs
336+ )
337+ parallel : OmniParallelKwargs = dataclasses .field (default_factory = OmniParallelKwargs )
290338
291339 # TTS parameters
292340 tts_max_instructions_length : int = 500
@@ -299,15 +347,36 @@ class OmniConfig(DynamoRuntimeConfig):
299347 stage_id : Optional [int ] = None
300348 omni_router : bool = False
301349
350+ @classmethod
351+ def from_cli_args (cls , args : argparse .Namespace ) -> "OmniConfig" :
352+ config = super ().from_cli_args (args )
353+ config .diffusion = dataclasses .replace (
354+ OmniDiffusionKwargs (),
355+ ** {
356+ f .name : getattr (args , f .name )
357+ for f in dataclasses .fields (OmniDiffusionKwargs )
358+ if hasattr (args , f .name )
359+ },
360+ )
361+ config .parallel = dataclasses .replace (
362+ OmniParallelKwargs (),
363+ ** {
364+ f .name : getattr (args , f .name )
365+ for f in dataclasses .fields (OmniParallelKwargs )
366+ if hasattr (args , f .name )
367+ },
368+ )
369+ return config
370+
302371 def validate (self ) -> None :
303372 DynamoRuntimeConfig .validate (self )
304373 if self .default_video_fps <= 0 :
305374 raise ValueError ("--default-video-fps must be > 0" )
306- if self .ulysses_degree <= 0 :
375+ if self .parallel . ulysses_degree <= 0 :
307376 raise ValueError ("--ulysses-degree must be > 0" )
308- if self .ring_degree <= 0 :
377+ if self .parallel . ring_degree <= 0 :
309378 raise ValueError ("--ring-degree must be > 0" )
310- if not (0 < self .boundary_ratio <= 1 ):
379+ if not (0 < self .diffusion . boundary_ratio <= 1 ):
311380 raise ValueError ("--boundary-ratio must be in (0, 1]" )
312381 if self .stage_configs_path is None :
313382 if self .stage_id is not None :
@@ -334,7 +403,6 @@ def parse_omni_args() -> OmniConfig:
334403 dynamo_runtime_argspec .add_arguments (parser )
335404 omni_argspec .add_arguments (parser )
336405
337- # Add vLLM-Omni engine args
338406 vg = parser .add_argument_group (
339407 "vLLM-Omni Engine Options. Please refer to vLLM-Omni documentation for more details."
340408 )
@@ -349,7 +417,6 @@ def parse_omni_args() -> OmniConfig:
349417 args , unknown = parser .parse_known_args ()
350418 config = OmniConfig .from_cli_args (args )
351419
352- # Default endpoint to "generate" if not explicitly provided by user
353420 if config .endpoint is None :
354421 config .endpoint = "generate"
355422
0 commit comments