---
title: matrixgame2_ode_causal_pipeline
---

<div class="python-reference">
<a id="fastvideo.training.matrixgame2_ode_causal_pipeline-classes"></a>
<a id="fastvideo.training.matrixgame2_ode_causal_pipeline-functions"></a>
<a id="fastvideo.training.matrixgame2_ode_causal_pipeline"></a>

<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SamplingParam"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SamplingParam</code></h2>
<pre class="doc-signature"><code>SamplingParam(data_type: str = &#x27;video&#x27;, image_path: str | None = None, pil_image: Any | None = None, last_image: Any | None = None, references: list&#91;Any&#93; | None = None, video_path: str | None = None, pose_video_path: str | None = None, face_video_path: str | None = None, background_video_path: str | None = None, mask_video_path: str | None = None, animate_mode: str | None = None, audio_path: str | None = None, latents: Any | None = None, audio_latents: Any | None = None, mouse_cond: Any | None = None, keyboard_cond: Any | None = None, grid_sizes: Any | None = None, pose: str | None = None, prompt_attention_mask: list = list(), negative_attention_mask: list = list(), c2ws_plucker_emb: Any | None = None, action_path: str | None = None, t_thresh: float = 0.5, num_cond_frames: int = 0, prompt: str | list&#91;str&#93; | None = None, negative_prompt: str = &#x27;Bright tones, overexposed, static, blurred details, subtitles, style, works, paintings, images, static, overall gray, worst quality, low quality, JPEG compression residue, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn faces, deformed, disfigured, misshapen limbs, fused fingers, still picture, messy background, three legs, many people in the background, walking backwards&#x27;, max_sequence_length: int | None = None, prompt_path: str | None = None, output_path: str = &#x27;outputs/&#x27;, output_video_name: str | None = None, num_videos_per_prompt: int = 1, seed: int = 1024, num_frames: int = 125, height: int = 720, width: int = 1280, height_sr: int = 1072, width_sr: int = 1920, fps: int = 24, num_inference_steps: int = 50, num_inference_steps_sr: int = 50, guidance_scale: float = 1.0, batch_cfg: bool = False, guidance_scale_2: float | None = None, use_embedded_guidance: bool = False, true_cfg_scale: float = 1.0, guidance_rescale: float = 0.0, boundary_ratio: float | None = None, sigmas: list&#91;float&#93; | None = None, pyramid_num_inference_steps_list: list&#91;int&#93; | None = None, history_sizes: list&#91;int&#93; | None = None, num_latent_frames_per_chunk: int = 9, keep_first_frame: bool = True, is_skip_first_chunk: bool = False, use_zero_init: bool = True, zero_steps: int = 1, is_amplify_first_chunk: bool = False, enable_teacache: bool = False, trajectory_type: str | None = None, movement_distance: float | None = None, camera_rotation: str | None = None, ltx2_cfg_scale_video: float = 1.0, ltx2_cfg_scale_audio: float = 1.0, ltx2_modality_scale_video: float = 1.0, ltx2_modality_scale_audio: float = 1.0, ltx2_rescale_scale: float = 0.0, ltx2_stg_scale_video: float = 0.0, ltx2_stg_scale_audio: float = 0.0, ltx2_stg_blocks_video: list&#91;int&#93; = (lambda: &#91;29&#93;)(), ltx2_stg_blocks_audio: list&#91;int&#93; = (lambda: &#91;29&#93;)(), ltx2_use_ancestral_sampler: bool = False, ltx2_images: list&#91;tuple&#91;str, int, float&#93;&#93; | None = None, ltx2_image_crf: float = 33.0, ltx2_conditioning_latent_stage1: Any | None = None, ltx2_conditioning_latent_stage2: Any | None = None, ltx2_video_conditions: list&#91;tuple&#91;list&#91;str&#93;, int, float&#93;&#93; | None = None, audio_start_in_s: float | None = None, audio_end_in_s: float | None = None, init_audio: Any = None, init_audio_strength: float | None = None, init_noise_level: float | None = None, inpaint_audio: Any = None, inpaint_mask: Any = None, continuation_state: ContinuationState | None = None, return_continuation_state: bool = False, save_video: bool = True, return_frames: bool = True, return_trajectory_latents: bool = False, return_trajectory_decoded: bool = False, *, return_samples: bool = False)</code></pre>
<p>Sampling parameters for video generation.</p>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SamplingParam.check_sampling_param"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SamplingParam.check_sampling_param</code></h3>
<pre class="doc-signature"><code>check_sampling_param() -&gt; None</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SamplingParam.update"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SamplingParam.update</code></h3>
<pre class="doc-signature"><code>update(source_dict: dict&#91;str, Any&#93;) -&gt; None</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SamplingParam.from_pretrained"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SamplingParam.from_pretrained</code></h3>
<pre class="doc-signature"><code>from_pretrained(model_path: str) -&gt; SamplingParam</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SamplingParam.add_cli_args"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SamplingParam.add_cli_args</code></h3>
<pre class="doc-signature"><code>add_cli_args(parser: Any) -&gt; Any</code></pre>
<p>Add CLI arguments for SamplingParam fields</p>
<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.get_local_torch_device"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.get_local_torch_device</code></h2>
<pre class="doc-signature"><code>get_local_torch_device() -&gt; torch.device</code></pre>
<p>Return the torch device for the current rank.</p>
<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs</code></h2>
<pre class="doc-signature"><code>FastVideoArgs(model_path: str, mode: ExecutionMode = ExecutionMode.INFERENCE, workload_type: WorkloadType = WorkloadType.T2V, distributed_executor_backend: str = &#x27;mp&#x27;, enable_streaming_ipc_queues: bool = False, ray_placement_group: PlacementGroup | None = None, ray_runtime_env: RuntimeEnv | None = None, inference_mode: bool = True, trust_remote_code: bool = False, revision: str | None = None, num_gpus: int = 1, tp_size: int = -1, sp_size: int = -1, hsdp_replicate_dim: int = 1, hsdp_shard_dim: int = -1, dist_timeout: int | None = None, pipeline_config: PipelineConfig = PipelineConfig(), preprocess_config: PreprocessConfig | None = None, lora_path: str | None = None, lora_nickname: str = &#x27;default&#x27;, lora_strength: float = 1.0, lora_target_modules: list&#91;str&#93; | None = None, output_type: str = &#x27;pil&#x27;, attention_backend: str | None = None, dit_cpu_offload: bool = True, use_fsdp_inference: bool = False, dit_layerwise_offload: bool = True, text_encoder_cpu_offload: bool = True, image_encoder_cpu_offload: bool = True, vae_cpu_offload: bool = True, pin_cpu_memory: bool = True, h3_sequential_load: bool | None = None, h3_encoder_split: bool | None = None, h3_encoder_nodes: int = -1, h3_encoder_workers: int = 0, video_decode_backend: str = &#x27;h3-vae&#x27;, taeh3_checkpoint: str | None = None, taeh3_chunk_size: int = 5, h3_vae_nvfp4_decoder: str | None = None, lazy_module_load: bool | None = None, vae_parallel_decode: bool = False, vae_parallel_encode: bool = False, vae_parallel_decode_strategy: str | None = None, enable_torch_compile: bool = False, regional_compile: bool = False, enable_torch_compile_text_encoder: bool = False, enable_torch_compile_vae: bool = False, enable_torch_compile_audio_vae: bool = False, torch_compile_kwargs: dict&#91;str, Any&#93; = dict(), torch_compile_kwargs_dit: dict&#91;str, Any&#93; = dict(), torch_compile_kwargs_text_encoder: dict&#91;str, Any&#93; = dict(), torch_compile_kwargs_vae: dict&#91;str, Any&#93; = dict(), torch_compile_kwargs_audio_vae: dict&#91;str, Any&#93; = dict(), inference_torch_compile: bool = False, h3_vsa_fp4: dict&#91;str, Any&#93; = dict(), disable_autocast: bool = False, VSA_sparsity: float | None = None, VSA_tile_size: int | None = None, moba_config_path: str | None = None, moba_config: dict&#91;str, Any&#93; = dict(), master_port: int | None = None, enable_stage_verification: bool = True, prompt_txt: str | None = None, ltx2_vae_tiling: bool | None = None, ltx2_vae_spatial_tile_size_in_pixels: int | None = None, ltx2_vae_spatial_tile_overlap_in_pixels: int | None = None, ltx2_vae_temporal_tile_size_in_frames: int | None = None, ltx2_vae_temporal_tile_overlap_in_frames: int | None = None, ltx2_initial_latent_path: str | None = None, ltx2_audio_latent_path: str | None = None, refine_enabled: bool | None = None, refine_upsampler_path: str | None = None, refine_transformer_path: str | None = None, refine_lora_path: str | None = None, refine_num_inference_steps: int | None = None, refine_guidance_scale: float | None = None, refine_add_noise: bool | None = None, refine_noise_path: str | None = None, refine_audio_noise_path: str | None = None, ltx2_refine_enabled: bool = False, ltx2_refine_upsampler_path: str | None = None, ltx2_refine_transformer_path: str | None = None, ltx2_refine_lora_path: str | None = None, ltx2_refine_num_inference_steps: int = 3, ltx2_refine_guidance_scale: float = 1.0, ltx2_refine_add_noise: bool = True, ltx2_refine_noise_path: str | None = None, ltx2_refine_audio_noise_path: str | None = None, ltx2_legacy_native_noise_order: bool = False, ltx2_use_distilled_sigmas: bool = True, model_paths: dict&#91;str, str&#93; = dict(), model_loaded: dict&#91;str, bool&#93; = (lambda: &#123;&#x27;transformer&#x27;: True, &#x27;vae&#x27;: True, &#x27;upsampler&#x27;: True&#125;)(), override_text_encoder_safetensors: str | None = None, override_text_encoder_quant: QuantizationMethods = None, transformer_quant: Any | None = None, override_transformer_cls_name: str | None = None, init_weights_from_safetensors: str = &#x27;&#x27;, init_weights_from_safetensors_2: str = &#x27;&#x27;, override_pipeline_cls_name: str | None = None, boundary_ratio: float | None = 0.875)</code></pre>


<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.is_output_rank"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.is_output_rank</code></h3>
<pre class="doc-signature"><code>is_output_rank: bool</code></pre>
<p>Whether this process may materialize user-facing outputs.</p>
<p>This is runtime state assigned by an SPMD executor, not a public
configuration field, so dataclass serialization and typed config
parsing deliberately ignore it.</p>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.add_cli_args"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.add_cli_args</code></h3>
<pre class="doc-signature"><code>add_cli_args(parser: FlexibleArgumentParser) -&gt; FlexibleArgumentParser</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.from_cli_args"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.from_cli_args</code></h3>
<pre class="doc-signature"><code>from_cli_args(args: argparse.Namespace) -&gt; FastVideoArgs</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.from_kwargs"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.from_kwargs</code></h3>
<pre class="doc-signature"><code>from_kwargs(**kwargs: Any) -&gt; FastVideoArgs</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.check_fastvideo_args"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.check_fastvideo_args</code></h3>
<pre class="doc-signature"><code>check_fastvideo_args() -&gt; None</code></pre>
<p>Validate inference arguments for consistency</p>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.finalize_device_offload_policy"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.finalize_device_offload_policy</code></h3>
<pre class="doc-signature"><code>finalize_device_offload_policy(device_id: int = 0) -&gt; bool</code></pre>
<p>Apply device-local memory policy, then resolve incompatible modes.</p>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.disable_offload_on_unified_memory"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.FastVideoArgs.disable_offload_on_unified_memory</code></h3>
<pre class="doc-signature"><code>disable_offload_on_unified_memory(device_id: int = 0, *, offload_flag: str | None = None) -&gt; bool</code></pre>
<p>Disable host offload after a worker has selected its device.</p>
<p>CUDA's unified-memory probe reads runtime device properties and may
initialize a CUDA context. Callers must therefore use this only inside
a device-owning process, after selecting and binding <code>device_id</code>.
Returning the classification lets direct component-loader callers
apply the same policy to explicit per-call overrides. When
<code>offload_flag</code> is given, the return value says whether this policy
covers that component role.</p>
<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingArgs"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingArgs</code></h2>
<pre class="doc-signature"><code>TrainingArgs(model_path: str, mode: ExecutionMode = ExecutionMode.INFERENCE, workload_type: WorkloadType = WorkloadType.T2V, distributed_executor_backend: str = &#x27;mp&#x27;, enable_streaming_ipc_queues: bool = False, ray_placement_group: PlacementGroup | None = None, ray_runtime_env: RuntimeEnv | None = None, inference_mode: bool = True, trust_remote_code: bool = False, revision: str | None = None, num_gpus: int = 1, tp_size: int = -1, sp_size: int = -1, hsdp_replicate_dim: int = 1, hsdp_shard_dim: int = -1, dist_timeout: int | None = None, pipeline_config: PipelineConfig = PipelineConfig(), preprocess_config: PreprocessConfig | None = None, lora_path: str | None = None, lora_nickname: str = &#x27;default&#x27;, lora_strength: float = 1.0, lora_target_modules: list&#91;str&#93; | None = None, output_type: str = &#x27;pil&#x27;, attention_backend: str | None = None, dit_cpu_offload: bool = True, use_fsdp_inference: bool = False, dit_layerwise_offload: bool = True, text_encoder_cpu_offload: bool = True, image_encoder_cpu_offload: bool = True, vae_cpu_offload: bool = True, pin_cpu_memory: bool = True, h3_sequential_load: bool | None = None, h3_encoder_split: bool | None = None, h3_encoder_nodes: int = -1, h3_encoder_workers: int = 0, video_decode_backend: str = &#x27;h3-vae&#x27;, taeh3_checkpoint: str | None = None, taeh3_chunk_size: int = 5, h3_vae_nvfp4_decoder: str | None = None, lazy_module_load: bool | None = None, vae_parallel_decode: bool = False, vae_parallel_encode: bool = False, vae_parallel_decode_strategy: str | None = None, enable_torch_compile: bool = False, regional_compile: bool = False, enable_torch_compile_text_encoder: bool = False, enable_torch_compile_vae: bool = False, enable_torch_compile_audio_vae: bool = False, torch_compile_kwargs: dict&#91;str, Any&#93; = dict(), torch_compile_kwargs_dit: dict&#91;str, Any&#93; = dict(), torch_compile_kwargs_text_encoder: dict&#91;str, Any&#93; = dict(), torch_compile_kwargs_vae: dict&#91;str, Any&#93; = dict(), torch_compile_kwargs_audio_vae: dict&#91;str, Any&#93; = dict(), inference_torch_compile: bool = False, h3_vsa_fp4: dict&#91;str, Any&#93; = dict(), disable_autocast: bool = False, VSA_sparsity: float | None = None, VSA_tile_size: int | None = None, moba_config_path: str | None = None, moba_config: dict&#91;str, Any&#93; = dict(), master_port: int | None = None, enable_stage_verification: bool = True, prompt_txt: str | None = None, ltx2_vae_tiling: bool | None = None, ltx2_vae_spatial_tile_size_in_pixels: int | None = None, ltx2_vae_spatial_tile_overlap_in_pixels: int | None = None, ltx2_vae_temporal_tile_size_in_frames: int | None = None, ltx2_vae_temporal_tile_overlap_in_frames: int | None = None, ltx2_initial_latent_path: str | None = None, ltx2_audio_latent_path: str | None = None, refine_enabled: bool | None = None, refine_upsampler_path: str | None = None, refine_transformer_path: str | None = None, refine_lora_path: str | None = None, refine_num_inference_steps: int | None = None, refine_guidance_scale: float | None = None, refine_add_noise: bool | None = None, refine_noise_path: str | None = None, refine_audio_noise_path: str | None = None, ltx2_refine_enabled: bool = False, ltx2_refine_upsampler_path: str | None = None, ltx2_refine_transformer_path: str | None = None, ltx2_refine_lora_path: str | None = None, ltx2_refine_num_inference_steps: int = 3, ltx2_refine_guidance_scale: float = 1.0, ltx2_refine_add_noise: bool = True, ltx2_refine_noise_path: str | None = None, ltx2_refine_audio_noise_path: str | None = None, ltx2_legacy_native_noise_order: bool = False, ltx2_use_distilled_sigmas: bool = True, model_paths: dict&#91;str, str&#93; = dict(), model_loaded: dict&#91;str, bool&#93; = (lambda: &#123;&#x27;transformer&#x27;: True, &#x27;vae&#x27;: True, &#x27;upsampler&#x27;: True&#125;)(), override_text_encoder_safetensors: str | None = None, override_text_encoder_quant: QuantizationMethods = None, transformer_quant: Any | None = None, override_transformer_cls_name: str | None = None, init_weights_from_safetensors: str = &#x27;&#x27;, init_weights_from_safetensors_2: str = &#x27;&#x27;, override_pipeline_cls_name: str | None = None, boundary_ratio: float | None = 0.875, pipeline_class: str = &#x27;&#x27;, pipeline_module: str = &#x27;&#x27;, data_path: str = &#x27;&#x27;, dataloader_num_workers: int = 0, num_height: int = 0, num_width: int = 0, num_frames: int = 0, train_batch_size: int = 0, num_latent_t: int = 0, group_frame: bool = False, group_resolution: bool = False, pretrained_model_name_or_path: str = &#x27;&#x27;, real_score_model_path: str = &#x27;&#x27;, fake_score_model_path: str = &#x27;&#x27;, ema_decay: float = 0.0, ema_start_step: int = 0, training_cfg_rate: float = 0.0, precondition_outputs: bool = False, validation_dataset_file: str = &#x27;&#x27;, validation_preprocessed_path: str = &#x27;&#x27;, validation_sampling_steps: str = &#x27;&#x27;, validation_guidance_scale: str = &#x27;&#x27;, validation_steps: float = 0.0, log_validation: bool = False, trackers: list&#91;str&#93; = list(), tracker_project_name: str = &#x27;&#x27;, wandb_run_name: str = &#x27;&#x27;, seed: int | None = None, output_dir: str = &#x27;&#x27;, checkpoints_total_limit: int = 0, resume_from_checkpoint: str = &#x27;&#x27;, num_train_epochs: int = 0, max_train_steps: int = 0, gradient_accumulation_steps: int = 0, learning_rate: float = 0.0, scale_lr: bool = False, lr_scheduler: str = &#x27;constant&#x27;, lr_warmup_steps: int = 0, max_grad_norm: float = 0.0, enable_gradient_checkpointing_type: str | None = None, selective_checkpointing: float = 0.0, mixed_precision: str = &#x27;&#x27;, train_sp_batch_size: int = 0, fsdp_sharding_startegy: str = &#x27;&#x27;, weighting_scheme: str = &#x27;&#x27;, logit_mean: float = 0.0, logit_std: float = 1.0, mode_scale: float = 0.0, num_euler_timesteps: int = 0, lr_num_cycles: int = 0, lr_power: float = 0.0, min_lr_ratio: float = 0.5, not_apply_cfg_solver: bool = False, distill_cfg: float = 0.0, scheduler_type: str = &#x27;&#x27;, linear_quadratic_threshold: float = 0.0, linear_range: float = 0.0, weight_decay: float = 0.0, betas: str = &#x27;0.9,0.999&#x27;, use_ema: bool = False, multi_phased_distill_schedule: str = &#x27;&#x27;, pred_decay_weight: float = 0.0, pred_decay_type: str = &#x27;&#x27;, hunyuan_teacher_disable_cfg: bool = False, master_weight_type: str = &#x27;&#x27;, VSA_decay_rate: float = 0.01, VSA_decay_interval_steps: int = 1, VSA_cache_tile_buf: bool = False, lora_rank: int | None = None, lora_alpha: int | None = None, lora_training: bool = False, ltx2_first_frame_conditioning_p: float = 0.1, generator_update_interval: int = 5, dfake_gen_update_ratio: int = 5, min_timestep_ratio: float = 0.2, max_timestep_ratio: float = 0.98, real_score_guidance_scale: float = 3.5, fake_score_learning_rate: float = 0.0, fake_score_lr_scheduler: str = &#x27;constant&#x27;, fake_score_betas: str = &#x27;0.9,0.999&#x27;, training_state_checkpointing_steps: int = 0, weight_only_checkpointing_steps: int = 0, log_visualization: bool = False, visualization_steps: int = 0, simulate_generator_forward: bool = False, warp_denoising_step: bool = False, num_frame_per_block: int = 3, independent_first_frame: bool = False, enable_gradient_masking: bool = True, gradient_mask_last_n_frames: int = 21, same_step_across_blocks: bool = False, last_step_only: bool = False, context_noise: int = 0)</code></pre>
<p>Training arguments. Inherits from FastVideoArgs and adds training-specific
arguments. If there are any conflicts, the training arguments will take
precedence.</p>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingArgs.from_cli_args"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingArgs.from_cli_args</code></h3>
<pre class="doc-signature"><code>from_cli_args(args: argparse.Namespace) -&gt; TrainingArgs</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingArgs.add_cli_args"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingArgs.add_cli_args</code></h3>
<pre class="doc-signature"><code>add_cli_args(parser: FlexibleArgumentParser) -&gt; FlexibleArgumentParser</code></pre>

<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.set_forward_context"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.set_forward_context</code></h2>
<pre class="doc-signature"><code>set_forward_context(current_timestep, attn_metadata, forward_batch: Optional&#91;ForwardBatch&#93; = None)</code></pre>
<p>A context manager that stores the current forward context,
can be attention metadata, etc.
Here we can inject common logic for every model forward pass.</p>
<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.init_logger"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.init_logger</code></h2>
<pre class="doc-signature"><code>init_logger(name: str) -&gt; _FastvideoLogger</code></pre>
<p>The main purpose of this function is to ensure that loggers are
retrieved in such a way that we can be sure the root fastvideo logger has
already been configured.</p>
<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler</code></h2>
<pre class="doc-signature"><code>SelfForcingFlowMatchScheduler(num_inference_steps = 100, num_train_timesteps = 1000, shift = 3.0, sigma_max = 1.0, sigma_min = 0.003 / 1.002, inverse_timesteps = False, extra_one_step = False, reverse_sigmas = False, training = False)</code></pre>


<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.set_timesteps"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.set_timesteps</code></h3>
<pre class="doc-signature"><code>set_timesteps(num_inference_steps = 100, denoising_strength = 1.0, training = False, return_dict = False, **kwargs)</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.step"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.step</code></h3>
<pre class="doc-signature"><code>step(model_output: torch.FloatTensor, timestep: torch.FloatTensor, sample: torch.FloatTensor, to_final = False, return_dict = False, **kwargs)</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.calculate_alpha_beta_high"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.calculate_alpha_beta_high</code></h3>
<pre class="doc-signature"><code>calculate_alpha_beta_high(sigma, sigma_bound)</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.add_noise"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.add_noise</code></h3>
<pre class="doc-signature"><code>add_noise(original_samples, noise, timestep)</code></pre>
<p>Diffusion forward corruption process.
Input:
    - clean_latent: the clean latent with shape [B<em>T, C, H, W]
    - noise: the noise with shape [B</em>T, C, H, W]
    - timestep: the timestep with shape [B<em>T]
Output: the corrupted latent with shape [B</em>T, C, H, W]</p>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.add_noise_high"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.add_noise_high</code></h3>
<pre class="doc-signature"><code>add_noise_high(original_samples, noise, timestep, boundary_timestep)</code></pre>
<p>Diffusion forward corruption process.
Input:
    - clean_latent: the clean latent with shape [B<em>T, C, H, W]
    - noise: the noise with shape [B</em>T, C, H, W]
    - timestep: the timestep with shape [B<em>T]
Output: the corrupted latent with shape [B</em>T, C, H, W]</p>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.training_target"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.training_target</code></h3>
<pre class="doc-signature"><code>training_target(sample, noise, timestep)</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.training_weight"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.training_weight</code></h3>
<pre class="doc-signature"><code>training_weight(timestep)</code></pre>
<h4>Input</h4>
<ul>
<li>timestep: the timestep with shape [B*T]</li>
</ul>
<p>Output: the corresponding weighting [B*T]</p>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.scale_model_input"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.scale_model_input</code></h3>
<pre class="doc-signature"><code>scale_model_input(sample: torch.Tensor, timestep: int | None = None) -&gt; torch.Tensor</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.set_shift"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.SelfForcingFlowMatchScheduler.set_shift</code></h3>
<pre class="doc-signature"><code>set_shift(shift: float) -&gt; None</code></pre>

<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2CausalDMDPipeline"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2CausalDMDPipeline</code></h2>
<pre class="doc-signature"><code>MatrixGame2CausalDMDPipeline(*args, **kwargs)</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2CausalDMDPipeline.create_pipeline_stages"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2CausalDMDPipeline.create_pipeline_stages</code></h3>
<pre class="doc-signature"><code>create_pipeline_stages(fastvideo_args: FastVideoArgs) -&gt; None</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2CausalDMDPipeline.streaming_reset"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2CausalDMDPipeline.streaming_reset</code></h3>
<pre class="doc-signature"><code>streaming_reset(batch: ForwardBatch, fastvideo_args: FastVideoArgs)</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2CausalDMDPipeline.streaming_step"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2CausalDMDPipeline.streaming_step</code></h3>
<pre class="doc-signature"><code>streaming_step(keyboard_action, mouse_action) -&gt; ForwardBatch</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2CausalDMDPipeline.streaming_clear"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2CausalDMDPipeline.streaming_clear</code></h3>
<pre class="doc-signature"><code>streaming_clear() -&gt; None</code></pre>

<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.DecodingStage"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.DecodingStage</code></h2>
<pre class="doc-signature"><code>DecodingStage(vae, pipeline = None)</code></pre>
<p>Stage for decoding latent representations into pixel space.</p>
<p>This stage handles the decoding of latent representations into the final
output format (e.g., pixel values).</p>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.DecodingStage.verify_input"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.DecodingStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify decoding stage inputs.</p>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.DecodingStage.verify_output"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.DecodingStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify decoding stage outputs.</p>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.DecodingStage.decode"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.DecodingStage.decode</code></h3>
<pre class="doc-signature"><code>decode(latents: torch.Tensor, fastvideo_args: FastVideoArgs) -&gt; torch.Tensor</code></pre>
<p>Decode latent representations into pixel space using VAE.</p>
<h4>Parameters</h4>
<dl>
<dt><code>latents: torch.Tensor</code></dt><dd><p>Input latent tensor with shape (batch, channels, frames, height_latents, width_latents)</p></dd>
<dt><code>fastvideo_args: FastVideoArgs</code></dt><dd><p>Configuration containing:
- disable_autocast: Whether to disable automatic mixed precision (default: False)
- pipeline_config.vae_precision: VAE computation precision ("fp32", "fp16", "bf16")
- pipeline_config.vae_tiling: Whether to enable VAE tiling for memory efficiency</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>torch.Tensor</code></dt><dd><p>Decoded video tensor with shape (batch, channels, frames, height, width), </p></dd>
<dt><code>torch.Tensor</code></dt><dd><p>normalized to [0, 1] range and moved to CPU as float32</p></dd>
</dl>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.DecodingStage.streaming_decode"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.DecodingStage.streaming_decode</code></h3>
<pre class="doc-signature"><code>streaming_decode(latents: torch.Tensor, fastvideo_args: FastVideoArgs, cache: list&#91;torch.Tensor | None&#93; | None = None, is_first_chunk: bool = False) -&gt; tuple&#91;torch.Tensor, list&#91;torch.Tensor | None&#93;&#93;</code></pre>
<p>Decode latent representations into pixel space using VAE with streaming cache.</p>
<h4>Parameters</h4>
<dl>
<dt><code>latents: torch.Tensor</code></dt><dd><p>Input latent tensor with shape (batch, channels, frames, height_latents, width_latents)</p></dd>
<dt><code>fastvideo_args: FastVideoArgs</code></dt><dd><p>Configuration object.</p></dd>
<dt><code>cache: list[torch.Tensor | None] | None</code></dt><dd><p>VAE cache from previous call, or None to initialize a new cache.</p></dd>
<dt><code>is_first_chunk: bool</code></dt><dd><p>Whether this is the first chunk.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>tuple[torch.Tensor, list[torch.Tensor | None]]</code></dt><dd><p>A tuple of (decoded_frames, updated_cache).</p></dd>
</dl>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.DecodingStage.forward"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.DecodingStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>
<p>Decode latent representations into pixel space.</p>
<p>This method processes the batch through the VAE decoder, converting latent
representations to pixel-space video/images. It also optionally decodes
trajectory latents for visualization purposes.</p>
<h4>Parameters</h4>
<dl>
<dt><code>batch: ForwardBatch</code></dt><dd><p>The current batch containing:
- latents: Tensor to decode (batch, channels, frames, height_latents, width_latents)
- return_trajectory_decoded (optional): Flag to decode trajectory latents
- trajectory_latents (optional): Latents at different timesteps
- trajectory_timesteps (optional): Corresponding timesteps</p></dd>
<dt><code>fastvideo_args: FastVideoArgs</code></dt><dd><p>Configuration containing:
- output_type: "latent" to skip decoding, otherwise decode to pixels
- vae_cpu_offload: Whether to offload VAE to CPU after decoding
- model_loaded: Track VAE loading state
- model_paths: Path to VAE model if loading needed</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>ForwardBatch</code></dt><dd><p>Modified batch with:
- output: Decoded frames (batch, channels, frames, height, width) as CPU float32
- trajectory_decoded (if requested): List of decoded frames per timestep</p></dd>
</dl>
<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.ForwardBatch"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.ForwardBatch</code></h2>
<pre class="doc-signature"><code>ForwardBatch(data_type: str, generator: torch.Generator | list&#91;torch.Generator&#93; | None = None, image_path: str | None = None, image_embeds: list&#91;torch.Tensor&#93; = list(), pil_image: torch.Tensor | PIL.Image.Image | None = None, last_image: torch.Tensor | PIL.Image.Image | None = None, references: list&#91;Any&#93; | None = None, preprocessed_image: torch.Tensor | None = None, prompt: str | list&#91;str&#93; | None = None, negative_prompt: str | list&#91;str&#93; | None = None, prompt_path: str | None = None, output_path: str = &#x27;outputs/&#x27;, output_video_name: str | None = None, video_path: str | None = None, video_latent: torch.Tensor | None = None, pose_video_path: str | None = None, face_video_path: str | None = None, background_video_path: str | None = None, mask_video_path: str | None = None, animate_mode: str | None = None, pose_latents: torch.Tensor | None = None, face_pixel_values: torch.Tensor | None = None, audio_path: str | None = None, audio_embeds: torch.Tensor | None = None, t_thresh: float = 0.5, num_cond_frames: int = 0, prompt_embeds: list&#91;torch.Tensor&#93; = list(), negative_prompt_embeds: list&#91;torch.Tensor&#93; | None = None, prompt_attention_mask: list&#91;torch.Tensor&#93; | None = None, negative_attention_mask: list&#91;torch.Tensor&#93; | None = None, clip_embedding_pos: list&#91;torch.Tensor&#93; | None = None, clip_embedding_neg: list&#91;torch.Tensor&#93; | None = None, max_sequence_length: int | None = None, prompt_template: dict&#91;str, Any&#93; | None = None, do_classifier_free_guidance: bool = False, use_embedded_guidance: bool = False, true_cfg_scale: float = 1.0, batch_size: int | None = None, num_videos_per_prompt: int = 1, seed: int | None = None, seeds: list&#91;int&#93; | None = None, is_prompt_processed: bool = False, latents: torch.Tensor | None = None, audio_latents: torch.Tensor | None = None, lq_latents: torch.Tensor | None = None, raw_latent_shape: tuple&#91;int, ...&#93; | None = None, noise_pred: torch.Tensor | None = None, image_latent: torch.Tensor | None = None, first_frame_latent: torch.Tensor | None = None, helios_latent_chunks: list&#91;torch.Tensor&#93; | None = None, mouse_cond: torch.Tensor | None = None, keyboard_cond: torch.Tensor | None = None, grid_sizes: torch.Tensor | None = None, num_iterations: int | None = None, use_base_model: bool = False, pose: str | None = None, c2ws_plucker_emb: torch.Tensor | None = None, action_path: str | None = None, trajectory_type: str | None = None, movement_distance: float | None = None, camera_rotation: str | None = None, height_latents: list&#91;int&#93; | int | None = None, width_latents: list&#91;int&#93; | int | None = None, num_frames: list&#91;int&#93; | int = 1, height: list&#91;int&#93; | int | None = None, width: list&#91;int&#93; | int | None = None, height_sr: list&#91;int&#93; | int | None = None, width_sr: list&#91;int&#93; | int | None = None, fps: list&#91;int&#93; | int | None = None, timesteps: torch.Tensor | None = None, timestep: torch.Tensor | float | int | None = None, step_index: int | None = None, boundary_ratio: float | None = None, num_inference_steps: int = 50, num_inference_steps_sr: int = 50, guidance_scale: float = 1.0, batch_cfg: bool = False, guidance_scale_2: float | None = None, guidance_rescale: float = 0.0, eta: float = 0.0, sigmas: list&#91;float&#93; | None = None, pyramid_num_inference_steps_list: list&#91;int&#93; | None = None, history_sizes: list&#91;int&#93; | None = None, num_latent_frames_per_chunk: int = 9, keep_first_frame: bool = True, is_skip_first_chunk: bool = False, use_zero_init: bool = True, zero_steps: int = 1, is_amplify_first_chunk: bool = False, enable_teacache: bool = False, ltx2_cfg_scale_video: float = 1.0, ltx2_cfg_scale_audio: float = 1.0, ltx2_modality_scale_video: float = 1.0, ltx2_modality_scale_audio: float = 1.0, ltx2_rescale_scale: float = 0.0, ltx2_stg_scale_video: float = 0.0, ltx2_stg_scale_audio: float = 0.0, ltx2_stg_blocks_video: list&#91;int&#93; = list(), ltx2_stg_blocks_audio: list&#91;int&#93; = list(), ltx2_use_ancestral_sampler: bool = False, ltx2_images: list&#91;tuple&#91;str, int, float&#93;&#93; | None = None, ltx2_image_crf: float = 33.0, ltx2_conditioning_latent_stage1: torch.Tensor | None = None, ltx2_conditioning_latent_stage2: torch.Tensor | None = None, ltx2_video_conditions: list&#91;tuple&#91;list&#91;str&#93;, int, float&#93;&#93; | None = None, audio_start_in_s: float | None = None, audio_end_in_s: float | None = None, init_audio: Any = None, init_audio_strength: float | None = None, init_noise_level: float | None = None, inpaint_audio: Any = None, inpaint_mask: Any = None, n_tokens: int | None = None, extra_step_kwargs: dict&#91;str, Any&#93; = dict(), modules: dict&#91;str, Any&#93; = dict(), output: torch.Tensor | None = None, return_trajectory_latents: bool = False, return_trajectory_decoded: bool = False, trajectory_timesteps: list&#91;torch.Tensor&#93; | None = None, trajectory_latents: torch.Tensor | None = None, trajectory_decoded: list&#91;torch.Tensor&#93; | None = None, continuation_state: ContinuationState | None = None, return_continuation_state: bool = False, extra: dict&#91;str, Any&#93; = dict(), save_video: bool = True, return_frames: bool = False, is_cfg_negative: bool = False, VSA_sparsity: float = 0.0, logging_info: PipelineLoggingInfo = PipelineLoggingInfo(), *, return_samples: bool = False)</code></pre>
<p>Complete state passed through the pipeline execution.</p>
<p>This dataclass contains all information needed during the diffusion pipeline
execution, allowing methods to update specific components without needing
to manage numerous individual parameters.</p>

<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingBatch"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingBatch</code></h2>
<pre class="doc-signature"><code>TrainingBatch(current_timestep: int = 0, current_vsa_sparsity: float = 0.0, latents: torch.Tensor | None = None, raw_latent_shape: tuple&#91;int, ...&#93; | None = None, noise_latents: torch.Tensor | None = None, encoder_hidden_states: torch.Tensor | None = None, encoder_attention_mask: torch.Tensor | None = None, audio_latents: torch.Tensor | None = None, audio_noisy_model_input: torch.Tensor | None = None, audio_timesteps: torch.Tensor | None = None, audio_sigmas: torch.Tensor | None = None, audio_noise: torch.Tensor | None = None, audio_encoder_hidden_states: torch.Tensor | None = None, audio_encoder_attention_mask: torch.Tensor | None = None, conditioning_mask: torch.Tensor | None = None, preprocessed_image: torch.Tensor | None = None, image_embeds: torch.Tensor | None = None, image_latents: torch.Tensor | None = None, infos: list&#91;dict&#91;str, Any&#93;&#93; | None = None, mask_lat_size: torch.Tensor | None = None, trajectory_latents: torch.Tensor | None = None, trajectory_timesteps: torch.Tensor | None = None, noisy_model_input: torch.Tensor | None = None, timesteps: torch.Tensor | None = None, sigmas: torch.Tensor | None = None, noise: torch.Tensor | None = None, training_target: torch.Tensor | None = None, minimax_h3_layout: Any | None = None, attn_metadata_vsa: AttentionMetadata | None = None, attn_metadata: AttentionMetadata | None = None, input_kwargs: dict&#91;str, Any&#93; | None = None, loss: torch.Tensor | None = None, total_loss: float | None = None, grad_norm: float | None = None, encoder_hidden_states_neg: torch.Tensor | None = None, encoder_attention_mask_neg: torch.Tensor | None = None, conditional_dict: dict&#91;str, Any&#93; | None = None, unconditional_dict: dict&#91;str, Any&#93; | None = None, generator_loss: float = 0.0, fake_score_loss: float = 0.0, dmd_latent_vis_dict: dict&#91;str, Any&#93; = dict(), latent_vis_dict: dict&#91;str, Any&#93; = dict(), fake_score_latent_vis_dict: dict&#91;str, Any&#93; = dict(), minimax_h3_condition_video_rows: torch.Tensor | None = None, minimax_h3_condition_audio_rows: torch.Tensor | None = None, minimax_h3_dmd_layout: Any | None = None, minimax_h3_document_video_latents: tuple&#91;torch.Tensor, ...&#93; | None = None, minimax_h3_document_audio_latents: tuple&#91;torch.Tensor, ...&#93; | None = None, minimax_h3_text_attn_metadata: AttentionMetadata | None = None, sequence_packing_num_documents: int = 1, sequence_packing_num_tokens: int = 0, sequence_padded_num_tokens: int = 0, sequence_padding_ratio: float | None = None, sequence_packing_loss_scale: float = 1.0, sequence_packing_data_forced_ratio: float | None = None)</code></pre>


<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline</code></h2>
<pre class="doc-signature"><code>TrainingPipeline(model_path: str, fastvideo_args: TrainingArgs, required_config_modules: list&#91;str&#93; | None = None, loaded_modules: dict&#91;str, torch.nn.Module&#93; | None = None)</code></pre>
<p>A pipeline for training a model. All training pipelines should inherit from this class.
All reusable components and code should be implemented in this class.</p>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.create_pipeline_stages"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.create_pipeline_stages</code></h3>
<pre class="doc-signature"><code>create_pipeline_stages(fastvideo_args: FastVideoArgs)</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.set_schemas"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.set_schemas</code></h3>
<pre class="doc-signature"><code>set_schemas() -&gt; None</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.initialize_training_pipeline"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.initialize_training_pipeline</code></h3>
<pre class="doc-signature"><code>initialize_training_pipeline(training_args: TrainingArgs)</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.initialize_validation_pipeline"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.initialize_validation_pipeline</code></h3>
<pre class="doc-signature"><code>initialize_validation_pipeline(training_args: TrainingArgs)</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.train_one_step"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.train_one_step</code></h3>
<pre class="doc-signature"><code>train_one_step(training_batch: TrainingBatch) -&gt; TrainingBatch</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.train"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.train</code></h3>
<pre class="doc-signature"><code>train() -&gt; None</code></pre>

<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.visualize_intermediate_latents"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.TrainingPipeline.visualize_intermediate_latents</code></h3>
<pre class="doc-signature"><code>visualize_intermediate_latents(training_batch: TrainingBatch, training_args: TrainingArgs, step: int)</code></pre>
<p>Add visualization data to tracker logging and save frames to disk.</p>
<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.clip_grad_norm_while_handling_failing_dtensor_cases"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.clip_grad_norm_while_handling_failing_dtensor_cases</code></h2>
<pre class="doc-signature"><code>clip_grad_norm_while_handling_failing_dtensor_cases(parameters: torch.Tensor | list&#91;torch.Tensor&#93;, max_norm: float, norm_type: float = 2.0, error_if_nonfinite: bool = False, foreach: bool | None = None, pp_mesh: torch.distributed.device_mesh.DeviceMesh | None = None) -&gt; torch.Tensor | None</code></pre>

<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.shallow_asdict"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.shallow_asdict</code></h2>
<pre class="doc-signature"><code>shallow_asdict(obj) -&gt; dict&#91;str, Any&#93;</code></pre>

<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline</code></h2>
<pre class="doc-signature"><code>MatrixGame2ODEInitTrainingPipeline(model_path: str, fastvideo_args: TrainingArgs, required_config_modules: list&#91;str&#93; | None = None, loaded_modules: dict&#91;str, torch.nn.Module&#93; | None = None)</code></pre>
<p>Training pipeline for ODE-init using precomputed denoising trajectories.</p>
<p>Supervision: predict the next latent in the stored trajectory by
- feeding current latent at timestep t into the transformer to predict noise
- stepping the scheduler with the predicted noise
- minimizing MSE to the stored next latent at timestep t_next</p>
<details><summary>Source</summary><pre><code>class MatrixGame2ODEInitTrainingPipeline(TrainingPipeline):
    &quot;&quot;&quot;
    Training pipeline for ODE-init using precomputed denoising trajectories.

    Supervision: predict the next latent in the stored trajectory by
    - feeding current latent at timestep t into the transformer to predict noise
    - stepping the scheduler with the predicted noise
    - minimizing MSE to the stored next latent at timestep t_next
    &quot;&quot;&quot;

    _required_config_modules = &#91;&quot;scheduler&quot;, &quot;transformer&quot;, &quot;vae&quot;&#93;

    def initialize_pipeline(self, fastvideo_args: FastVideoArgs):
        # Match the preprocess/generation scheduler for consistent stepping
        self.modules&#91;&quot;scheduler&quot;&#93; = SelfForcingFlowMatchScheduler(shift=fastvideo_args.pipeline_config.flow_shift,
                                                                  sigma_min=0.0,
                                                                  extra_one_step=True)
        self.modules&#91;&quot;scheduler&quot;&#93;.set_timesteps(num_inference_steps=1000, training=True)

    def set_schemas(self):
        self.train_dataset_schema = pyarrow_schema_matrixgame2_ode_trajectory

    def initialize_training_pipeline(self, training_args: TrainingArgs):
        super().initialize_training_pipeline(training_args)

        self.noise_scheduler = self.get_module(&quot;scheduler&quot;)
        self.vae = self.get_module(&quot;vae&quot;)
        self.vae.requires_grad_(False)

        self.timestep_shift = self.training_args.pipeline_config.flow_shift
        self.noise_scheduler = SelfForcingFlowMatchScheduler(shift=self.timestep_shift,
                                                             sigma_min=0.0,
                                                             extra_one_step=True)
        self.noise_scheduler.set_timesteps(num_inference_steps=1000, training=True)

        self.add_stage(stage_name=&quot;decoding_stage&quot;, stage=DecodingStage(vae=self.get_module(&quot;vae&quot;)))

        logger.info(&quot;dmd_denoising_steps: %s&quot;, self.training_args.pipeline_config.dmd_denoising_steps)
        self.dmd_denoising_steps = torch.tensor(&#91;1000, 750, 500, 250, 0&#93;,
                                                dtype=torch.long,
                                                device=get_local_torch_device())
        if training_args.warp_denoising_step:  # Warp the denoising step according to the scheduler time shift
            timesteps = torch.cat((self.noise_scheduler.timesteps.cpu(), torch.tensor(&#91;0&#93;, dtype=torch.float32))).cuda()
            logger.info(&quot;timesteps: %s&quot;, timesteps)
            self.dmd_denoising_steps = timesteps&#91;1000 - self.dmd_denoising_steps&#93;
            logger.info(&quot;warped self.dmd_denoising_steps: %s&quot;, self.dmd_denoising_steps)
        else:
            raise ValueError(&quot;warp_denoising_step must be true&quot;)

        self.dmd_denoising_steps = self.dmd_denoising_steps.to(get_local_torch_device())

        logger.info(&quot;denoising_step_list: %s&quot;, self.dmd_denoising_steps)

        logger.info(&quot;Initialized ODE-init training pipeline with %s denoising steps&quot;, len(self.dmd_denoising_steps))
        # Cache for nearest trajectory index per DMD step (computed lazily on first batch)
        self._cached_closest_idx_per_dmd = None
        self.num_train_timestep = self.noise_scheduler.num_train_timesteps
        self.manual_idx = 0

    def initialize_validation_pipeline(self, training_args: TrainingArgs):
        logger.info(&quot;Initializing validation pipeline...&quot;)
        args_copy = deepcopy(training_args)
        args_copy.inference_mode = True
        # Use the same flow-matching scheduler as training for consistent validation.
        validation_scheduler = SelfForcingFlowMatchScheduler(shift=args_copy.pipeline_config.flow_shift,
                                                             sigma_min=0.0,
                                                             extra_one_step=True)
        validation_scheduler.set_timesteps(num_inference_steps=1000, training=True)
        # Warm start validation with current transformer
        self.validation_pipeline = MatrixGame2CausalDMDPipeline.from_pretrained(
            training_args.model_path,
            args=args_copy,  # type: ignore
            inference_mode=True,
            loaded_modules=&#123;
                &quot;transformer&quot;: self.get_module(&quot;transformer&quot;),
                &quot;vae&quot;: self.get_module(&quot;vae&quot;),
                &quot;scheduler&quot;: validation_scheduler,
            &#125;,
            tp_size=training_args.tp_size,
            sp_size=training_args.sp_size,
            num_gpus=training_args.num_gpus,
            pin_cpu_memory=training_args.pin_cpu_memory,
            dit_cpu_offload=True)

    def _get_next_batch(self, training_batch) -&gt; tuple&#91;TrainingBatch, torch.Tensor, torch.Tensor&#93;:
        batch = next(self.train_loader_iter, None)  # type: ignore
        if batch is None:
            self.current_epoch += 1
            logger.info(&quot;Starting epoch %s&quot;, self.current_epoch)
            self.train_loader_iter = iter(self.train_dataloader)
            batch = next(self.train_loader_iter)

        # Required fields from parquet (ODE trajectory schema)
        clip_feature = batch&#91;&#x27;clip_feature&#x27;&#93;
        first_frame_latent = batch&#91;&#x27;first_frame_latent&#x27;&#93;
        keyboard_cond = batch.get(&#x27;keyboard_cond&#x27;, None)
        mouse_cond = batch.get(&#x27;mouse_cond&#x27;, None)
        infos = batch&#91;&#x27;info_list&#x27;&#93;

        # Trajectory tensors may include a leading singleton batch dim per row
        trajectory_latents = batch&#91;&#x27;trajectory_latents&#x27;&#93;
        if trajectory_latents.dim() == 7:
            # &#91;B, 1, S, C, T, H, W&#93; -&gt; &#91;B, S, C, T, H, W&#93;
            trajectory_latents = trajectory_latents&#91;:, 0&#93;
        elif trajectory_latents.dim() == 6:
            # already &#91;B, S, C, T, H, W&#93;
            pass
        else:
            raise ValueError(f&quot;Unexpected trajectory_latents dim: &#123;trajectory_latents.dim()&#125;&quot;)

        trajectory_timesteps = batch&#91;&#x27;trajectory_timesteps&#x27;&#93;
        if trajectory_timesteps.dim() == 3:
            # &#91;B, 1, S&#93; -&gt; &#91;B, S&#93;
            trajectory_timesteps = trajectory_timesteps&#91;:, 0&#93;
        elif trajectory_timesteps.dim() == 2:
            # &#91;B, S&#93;
            pass
        else:
            raise ValueError(f&quot;Unexpected trajectory_timesteps dim: &#123;trajectory_timesteps.dim()&#125;&quot;)
        # &#91;B, S, C, T, H, W&#93; -&gt; &#91;B, S, T, C, H, W&#93; to match self-forcing
        trajectory_latents = trajectory_latents.permute(0, 1, 3, 2, 4, 5)

        # Move to device
        device = get_local_torch_device()
        training_batch.image_embeds = clip_feature.to(device, dtype=torch.bfloat16)
        training_batch.image_latents = first_frame_latent.to(device, dtype=torch.bfloat16)
        if keyboard_cond is not None and keyboard_cond.numel() &gt; 0:
            training_batch.keyboard_cond = keyboard_cond.to(device, dtype=torch.bfloat16)
        else:
            training_batch.keyboard_cond = None
        if mouse_cond is not None and mouse_cond.numel() &gt; 0:
            training_batch.mouse_cond = mouse_cond.to(device, dtype=torch.bfloat16)
        else:
            training_batch.mouse_cond = None
        training_batch.infos = infos

        return training_batch, trajectory_latents&#91;:, :, :self.training_args.num_latent_t&#93;.to(
            device, dtype=torch.bfloat16), trajectory_timesteps.to(device)

    def _get_timestep(self,
                      min_timestep: int,
                      max_timestep: int,
                      batch_size: int,
                      num_frame: int,
                      num_frame_per_block: int,
                      uniform_timestep: bool = False) -&gt; torch.Tensor:
        if uniform_timestep:
            timestep = torch.randint(min_timestep, max_timestep, &#91;batch_size, 1&#93;, device=self.device,
                                     dtype=torch.long).repeat(1, num_frame)
            return timestep
        else:
            timestep = torch.randint(min_timestep,
                                     max_timestep, &#91;batch_size, num_frame&#93;,
                                     device=self.device,
                                     dtype=torch.long)
            # logger.info(f&quot;individual timestep: &#123;timestep&#125;&quot;)
            # make the noise level the same within every block
            timestep = timestep.reshape(timestep.shape&#91;0&#93;, -1, num_frame_per_block)
            timestep&#91;:, :, 1:&#93; = timestep&#91;:, :, 0:1&#93;
            timestep = timestep.reshape(timestep.shape&#91;0&#93;, -1)
            return timestep

    def _step_predict_next_latent(
            self, traj_latents: torch.Tensor, traj_timesteps: torch.Tensor, image_embeds: torch.Tensor,
            image_latents: torch.Tensor, keyboard_cond: torch.Tensor | None, mouse_cond: torch.Tensor | None
    ) -&gt; tuple&#91;torch.Tensor, torch.Tensor, torch.Tensor, dict&#91;str, torch.Tensor&#93;&#93;:
        latent_vis_dict: dict&#91;str, torch.Tensor&#93; = &#123;&#125;
        device = get_local_torch_device()
        target_latent = traj_latents&#91;:, -1&#93;

        # Shapes: traj_latents &#91;B, S, C, T, H, W&#93;, traj_timesteps &#91;B, S&#93;
        B, S, num_frames, num_channels, height, width = traj_latents.shape
        expected_action_frames = 1 + 4 * (num_frames - 1)
        if keyboard_cond is None or mouse_cond is None:
            raise ValueError(&quot;keyboard_cond/mouse_cond must both be provided for action-follow training. &quot;
                             f&quot;keyboard_cond=&#123;None if keyboard_cond is None else tuple(keyboard_cond.shape)&#125;, &quot;
                             f&quot;mouse_cond=&#123;None if mouse_cond is None else tuple(mouse_cond.shape)&#125;&quot;)
        if keyboard_cond.shape&#91;1&#93; &lt; expected_action_frames:
            raise ValueError(&quot;keyboard_cond length is shorter than required for latent frames. &quot;
                             f&quot;got=&#123;keyboard_cond.shape&#91;1&#93;&#125;, required&gt;=&#123;expected_action_frames&#125;, &quot;
                             f&quot;num_latent_frames=&#123;num_frames&#125;&quot;)
        if mouse_cond.shape&#91;1&#93; &lt; expected_action_frames:
            raise ValueError(&quot;mouse_cond length is shorter than required for latent frames. &quot;
                             f&quot;got=&#123;mouse_cond.shape&#91;1&#93;&#125;, required&gt;=&#123;expected_action_frames&#125;, &quot;
                             f&quot;num_latent_frames=&#123;num_frames&#125;&quot;)

        # Lazily cache nearest trajectory index per DMD step based on the (fixed) S timesteps
        if self._cached_closest_idx_per_dmd is None:
            traj_ts = traj_timesteps&#91;0&#93;.float().cpu()
            dmd_steps = self.dmd_denoising_steps.float().cpu()
            closest_idx = torch.argmin(torch.abs(traj_ts.unsqueeze(0) - dmd_steps.unsqueeze(1)), dim=1)
            self._cached_closest_idx_per_dmd = closest_idx.to(torch.long).cpu()
            logger.info(&quot;self._cached_closest_idx_per_dmd: %s&quot;, self._cached_closest_idx_per_dmd)
            logger.info(&quot;corresponding timesteps: %s&quot;, traj_ts&#91;self._cached_closest_idx_per_dmd&#93;)

        # Select the K indexes from traj_latents using self._cached_closest_idx_per_dmd
        # traj_latents: &#91;B, S, C, T, H, W&#93;, self._cached_closest_idx_per_dmd: &#91;K&#93;
        # Output: &#91;B, K, C, T, H, W&#93;
        assert self._cached_closest_idx_per_dmd is not None
        relevant_traj_latents = torch.index_select(traj_latents,
                                                   dim=1,
                                                   index=self._cached_closest_idx_per_dmd.to(traj_latents.device))

        indexes = self._get_timestep(  # &#91;B, num_frames&#93;
            0, len(self.dmd_denoising_steps), B, num_frames, 3, uniform_timestep=False)
        noisy_input = torch.gather(relevant_traj_latents,
                                   dim=1,
                                   index=indexes.reshape(B, 1, num_frames, 1, 1,
                                                         1).expand(-1, -1, -1, num_channels, height,
                                                                   width).to(self.device)).squeeze(1)
        latent_model_input = noisy_input.permute(0, 2, 1, 3, 4)
        if image_latents is not None:
            latent_model_input = torch.cat(&#91;
                latent_model_input,
                image_latents.to(latent_model_input.device, latent_model_input.dtype),
            &#93;,
                                           dim=1)
        timestep = self.dmd_denoising_steps&#91;indexes&#93;

        # Prepare inputs for transformer
        latent_vis_dict&#91;&quot;noisy_input&quot;&#93; = noisy_input.permute(0, 2, 1, 3, 4).detach().clone().cpu()
        latent_vis_dict&#91;&quot;x0&quot;&#93; = target_latent.permute(0, 2, 1, 3, 4).detach().clone().cpu()

        latent_model_input = latent_model_input.to(device, dtype=torch.bfloat16)
        timestep = timestep.to(device, dtype=torch.bfloat16)

        input_kwargs = &#123;
            &quot;hidden_states&quot;: latent_model_input,
            &quot;encoder_hidden_states&quot;: None,
            &quot;encoder_hidden_states_image&quot;: image_embeds,
            &quot;timestep&quot;: timestep,
            &quot;mouse_cond&quot;: mouse_cond,
            &quot;keyboard_cond&quot;: keyboard_cond,
            &quot;return_dict&quot;: False,
        &#125;
        # Predict noise and step the scheduler to obtain next latent
        with set_forward_context(current_timestep=timestep, attn_metadata=None, forward_batch=None):
            noise_pred = self.transformer(**input_kwargs).permute(0, 2, 1, 3, 4)

        from fastvideo.models.utils import pred_noise_to_pred_video
        pred_video = pred_noise_to_pred_video(pred_noise=noise_pred.flatten(0, 1),
                                              noise_input_latent=noisy_input.flatten(0, 1),
                                              timestep=timestep.to(dtype=torch.bfloat16).flatten(0, 1),
                                              scheduler=self.modules&#91;&quot;scheduler&quot;&#93;).unflatten(0, noise_pred.shape&#91;:2&#93;)
        latent_vis_dict&#91;&quot;pred_video&quot;&#93; = pred_video.permute(0, 2, 1, 3, 4).detach().clone().cpu()

        return pred_video, target_latent, timestep, latent_vis_dict

    def train_one_step(self, training_batch):  # type: ignore&#91;override&#93;
        self.transformer.train()
        self.optimizer.zero_grad()
        training_batch.total_loss = 0.0
        args = cast(TrainingArgs, self.training_args)

        # Using cached nearest index per DMD step; computation happens in _step_predict_next_latent

        for _ in range(args.gradient_accumulation_steps):
            training_batch, traj_latents, traj_timesteps = self._get_next_batch(training_batch)
            image_embeds = training_batch.image_embeds
            image_latents = training_batch.image_latents
            keyboard_cond = training_batch.keyboard_cond
            mouse_cond = training_batch.mouse_cond
            assert traj_latents.shape&#91;0&#93; == 1

            # Shapes: traj_latents &#91;B, S, C, T, H, W&#93;, traj_timesteps &#91;B, S&#93;
            _, S = traj_latents.shape&#91;0&#93;, traj_latents.shape&#91;1&#93;
            if S &lt; 2:
                raise ValueError(&quot;Trajectory must contain at least 2 steps&quot;)

            # Forward to predict next latent by stepping scheduler with predicted noise
            noise_pred, target_latent, t, latent_vis_dict = self._step_predict_next_latent(
                traj_latents, traj_timesteps, image_embeds, image_latents, keyboard_cond, mouse_cond)

            training_batch.latent_vis_dict.update(latent_vis_dict)

            mask = t != 0

            # Compute loss
            loss = F.mse_loss(noise_pred&#91;mask&#93;, target_latent&#91;mask&#93;, reduction=&quot;mean&quot;)
            loss = loss / args.gradient_accumulation_steps

            with set_forward_context(current_timestep=t, attn_metadata=None, forward_batch=None):
                loss.backward()
            avg_loss = loss.detach().clone()
            training_batch.total_loss += avg_loss.item()

        # Clip grad and step optimizers
        grad_norm = clip_grad_norm_while_handling_failing_dtensor_cases(
            &#91;p for p in self.transformer.parameters() if p.requires_grad&#93;,
            args.max_grad_norm if args.max_grad_norm is not None else 0.0)

        self.optimizer.step()
        self.lr_scheduler.step()

        if grad_norm is None:
            grad_value = 0.0
        else:
            try:
                if isinstance(grad_norm, torch.Tensor):
                    grad_value = float(grad_norm.detach().float().item())
                else:
                    grad_value = float(grad_norm)
            except Exception:
                grad_value = 0.0
        training_batch.grad_norm = grad_value
        B, S, T, C, H, W = traj_latents.shape
        training_batch.raw_latent_shape = (B, C, T, H, W)
        return training_batch

    def _prepare_validation_batch(self, sampling_param: SamplingParam, training_args: TrainingArgs,
                                  validation_batch: dict&#91;str, Any&#93;, num_inference_steps: int) -&gt; ForwardBatch:
        sampling_param.prompt = validation_batch&#91;&#x27;prompt&#x27;&#93;
        sampling_param.height = training_args.num_height
        sampling_param.width = training_args.num_width
        sampling_param.image_path = validation_batch.get(&#x27;image_path&#x27;) or validation_batch.get(&#x27;video_path&#x27;)
        sampling_param.num_inference_steps = num_inference_steps
        sampling_param.data_type = &quot;video&quot;
        assert self.seed is not None
        sampling_param.seed = self.seed

        latents_size = &#91;(sampling_param.num_frames - 1) // 4 + 1, sampling_param.height // 8, sampling_param.width // 8&#93;
        n_tokens = latents_size&#91;0&#93; * latents_size&#91;1&#93; * latents_size&#91;2&#93;
        temporal_compression_factor = training_args.pipeline_config.vae_config.arch_config.temporal_compression_ratio
        num_frames = (training_args.num_latent_t - 1) * temporal_compression_factor + 1
        sampling_param.num_frames = num_frames
        batch = ForwardBatch(
            **shallow_asdict(sampling_param),
            generator=torch.Generator(device=&quot;cpu&quot;).manual_seed(self.seed),
            n_tokens=n_tokens,
            eta=0.0,
            VSA_sparsity=training_args.VSA_sparsity,
        )
        if &quot;image&quot; in validation_batch and validation_batch&#91;&quot;image&quot;&#93; is not None:
            batch.pil_image = validation_batch&#91;&quot;image&quot;&#93;

        if &quot;keyboard_cond&quot; in validation_batch and validation_batch&#91;&quot;keyboard_cond&quot;&#93; is not None:
            keyboard_cond = validation_batch&#91;&quot;keyboard_cond&quot;&#93;
            keyboard_cond = torch.tensor(keyboard_cond, dtype=torch.bfloat16)
            keyboard_cond = keyboard_cond.unsqueeze(0)
            batch.keyboard_cond = keyboard_cond

        if &quot;mouse_cond&quot; in validation_batch and validation_batch&#91;&quot;mouse_cond&quot;&#93; is not None:
            mouse_cond = validation_batch&#91;&quot;mouse_cond&quot;&#93;
            mouse_cond = torch.tensor(mouse_cond, dtype=torch.bfloat16)
            mouse_cond = mouse_cond.unsqueeze(0)
            batch.mouse_cond = mouse_cond

        return batch

    def visualize_intermediate_latents(self, training_batch: TrainingBatch, training_args: TrainingArgs, step: int):
        tracker_loss_dict: dict&#91;str, Any&#93; = &#123;&#125;
        latents_vis_dict = training_batch.latent_vis_dict
        latent_log_keys = &#91;&#x27;noisy_input&#x27;, &#x27;x0&#x27;, &#x27;pred_video&#x27;&#93;
        for latent_key in latent_log_keys:
            assert latent_key in latents_vis_dict and latents_vis_dict&#91;latent_key&#93; is not None
            latent = latents_vis_dict&#91;latent_key&#93;
            pixel_latent = self.decoding_stage.decode(latent, training_args)

            video = pixel_latent.cpu().float()
            video = video.permute(0, 2, 1, 3, 4)
            video = (video * 255).numpy().astype(np.uint8)
            video_artifact = self.tracker.video(video, fps=16, format=&quot;mp4&quot;)  # change to 16 for Wan2.1
            if video_artifact is not None:
                tracker_loss_dict&#91;latent_key&#93; = video_artifact
            # Clean up references
            del video, pixel_latent, latent

        if self.global_rank == 0 and tracker_loss_dict:
            self.tracker.log_artifacts(tracker_loss_dict, step)</code></pre></details>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline.initialize_pipeline"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline.initialize_pipeline</code></h3>
<pre class="doc-signature"><code>initialize_pipeline(fastvideo_args: FastVideoArgs)</code></pre>

<details><summary>Source</summary><pre><code>def initialize_pipeline(self, fastvideo_args: FastVideoArgs):
    # Match the preprocess/generation scheduler for consistent stepping
    self.modules&#91;&quot;scheduler&quot;&#93; = SelfForcingFlowMatchScheduler(shift=fastvideo_args.pipeline_config.flow_shift,
                                                              sigma_min=0.0,
                                                              extra_one_step=True)
    self.modules&#91;&quot;scheduler&quot;&#93;.set_timesteps(num_inference_steps=1000, training=True)</code></pre></details>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline.set_schemas"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline.set_schemas</code></h3>
<pre class="doc-signature"><code>set_schemas()</code></pre>

<details><summary>Source</summary><pre><code>def set_schemas(self):
    self.train_dataset_schema = pyarrow_schema_matrixgame2_ode_trajectory</code></pre></details>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline.initialize_training_pipeline"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline.initialize_training_pipeline</code></h3>
<pre class="doc-signature"><code>initialize_training_pipeline(training_args: TrainingArgs)</code></pre>

<details><summary>Source</summary><pre><code>def initialize_training_pipeline(self, training_args: TrainingArgs):
    super().initialize_training_pipeline(training_args)

    self.noise_scheduler = self.get_module(&quot;scheduler&quot;)
    self.vae = self.get_module(&quot;vae&quot;)
    self.vae.requires_grad_(False)

    self.timestep_shift = self.training_args.pipeline_config.flow_shift
    self.noise_scheduler = SelfForcingFlowMatchScheduler(shift=self.timestep_shift,
                                                         sigma_min=0.0,
                                                         extra_one_step=True)
    self.noise_scheduler.set_timesteps(num_inference_steps=1000, training=True)

    self.add_stage(stage_name=&quot;decoding_stage&quot;, stage=DecodingStage(vae=self.get_module(&quot;vae&quot;)))

    logger.info(&quot;dmd_denoising_steps: %s&quot;, self.training_args.pipeline_config.dmd_denoising_steps)
    self.dmd_denoising_steps = torch.tensor(&#91;1000, 750, 500, 250, 0&#93;,
                                            dtype=torch.long,
                                            device=get_local_torch_device())
    if training_args.warp_denoising_step:  # Warp the denoising step according to the scheduler time shift
        timesteps = torch.cat((self.noise_scheduler.timesteps.cpu(), torch.tensor(&#91;0&#93;, dtype=torch.float32))).cuda()
        logger.info(&quot;timesteps: %s&quot;, timesteps)
        self.dmd_denoising_steps = timesteps&#91;1000 - self.dmd_denoising_steps&#93;
        logger.info(&quot;warped self.dmd_denoising_steps: %s&quot;, self.dmd_denoising_steps)
    else:
        raise ValueError(&quot;warp_denoising_step must be true&quot;)

    self.dmd_denoising_steps = self.dmd_denoising_steps.to(get_local_torch_device())

    logger.info(&quot;denoising_step_list: %s&quot;, self.dmd_denoising_steps)

    logger.info(&quot;Initialized ODE-init training pipeline with %s denoising steps&quot;, len(self.dmd_denoising_steps))
    # Cache for nearest trajectory index per DMD step (computed lazily on first batch)
    self._cached_closest_idx_per_dmd = None
    self.num_train_timestep = self.noise_scheduler.num_train_timesteps
    self.manual_idx = 0</code></pre></details>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline.initialize_validation_pipeline"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline.initialize_validation_pipeline</code></h3>
<pre class="doc-signature"><code>initialize_validation_pipeline(training_args: TrainingArgs)</code></pre>

<details><summary>Source</summary><pre><code>def initialize_validation_pipeline(self, training_args: TrainingArgs):
    logger.info(&quot;Initializing validation pipeline...&quot;)
    args_copy = deepcopy(training_args)
    args_copy.inference_mode = True
    # Use the same flow-matching scheduler as training for consistent validation.
    validation_scheduler = SelfForcingFlowMatchScheduler(shift=args_copy.pipeline_config.flow_shift,
                                                         sigma_min=0.0,
                                                         extra_one_step=True)
    validation_scheduler.set_timesteps(num_inference_steps=1000, training=True)
    # Warm start validation with current transformer
    self.validation_pipeline = MatrixGame2CausalDMDPipeline.from_pretrained(
        training_args.model_path,
        args=args_copy,  # type: ignore
        inference_mode=True,
        loaded_modules=&#123;
            &quot;transformer&quot;: self.get_module(&quot;transformer&quot;),
            &quot;vae&quot;: self.get_module(&quot;vae&quot;),
            &quot;scheduler&quot;: validation_scheduler,
        &#125;,
        tp_size=training_args.tp_size,
        sp_size=training_args.sp_size,
        num_gpus=training_args.num_gpus,
        pin_cpu_memory=training_args.pin_cpu_memory,
        dit_cpu_offload=True)</code></pre></details>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline.train_one_step"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline.train_one_step</code></h3>
<pre class="doc-signature"><code>train_one_step(training_batch)</code></pre>

<details><summary>Source</summary><pre><code>def train_one_step(self, training_batch):  # type: ignore&#91;override&#93;
    self.transformer.train()
    self.optimizer.zero_grad()
    training_batch.total_loss = 0.0
    args = cast(TrainingArgs, self.training_args)

    # Using cached nearest index per DMD step; computation happens in _step_predict_next_latent

    for _ in range(args.gradient_accumulation_steps):
        training_batch, traj_latents, traj_timesteps = self._get_next_batch(training_batch)
        image_embeds = training_batch.image_embeds
        image_latents = training_batch.image_latents
        keyboard_cond = training_batch.keyboard_cond
        mouse_cond = training_batch.mouse_cond
        assert traj_latents.shape&#91;0&#93; == 1

        # Shapes: traj_latents &#91;B, S, C, T, H, W&#93;, traj_timesteps &#91;B, S&#93;
        _, S = traj_latents.shape&#91;0&#93;, traj_latents.shape&#91;1&#93;
        if S &lt; 2:
            raise ValueError(&quot;Trajectory must contain at least 2 steps&quot;)

        # Forward to predict next latent by stepping scheduler with predicted noise
        noise_pred, target_latent, t, latent_vis_dict = self._step_predict_next_latent(
            traj_latents, traj_timesteps, image_embeds, image_latents, keyboard_cond, mouse_cond)

        training_batch.latent_vis_dict.update(latent_vis_dict)

        mask = t != 0

        # Compute loss
        loss = F.mse_loss(noise_pred&#91;mask&#93;, target_latent&#91;mask&#93;, reduction=&quot;mean&quot;)
        loss = loss / args.gradient_accumulation_steps

        with set_forward_context(current_timestep=t, attn_metadata=None, forward_batch=None):
            loss.backward()
        avg_loss = loss.detach().clone()
        training_batch.total_loss += avg_loss.item()

    # Clip grad and step optimizers
    grad_norm = clip_grad_norm_while_handling_failing_dtensor_cases(
        &#91;p for p in self.transformer.parameters() if p.requires_grad&#93;,
        args.max_grad_norm if args.max_grad_norm is not None else 0.0)

    self.optimizer.step()
    self.lr_scheduler.step()

    if grad_norm is None:
        grad_value = 0.0
    else:
        try:
            if isinstance(grad_norm, torch.Tensor):
                grad_value = float(grad_norm.detach().float().item())
            else:
                grad_value = float(grad_norm)
        except Exception:
            grad_value = 0.0
    training_batch.grad_norm = grad_value
    B, S, T, C, H, W = traj_latents.shape
    training_batch.raw_latent_shape = (B, C, T, H, W)
    return training_batch</code></pre></details>
<h3 id="fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline.visualize_intermediate_latents"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.MatrixGame2ODEInitTrainingPipeline.visualize_intermediate_latents</code></h3>
<pre class="doc-signature"><code>visualize_intermediate_latents(training_batch: TrainingBatch, training_args: TrainingArgs, step: int)</code></pre>

<details><summary>Source</summary><pre><code>def visualize_intermediate_latents(self, training_batch: TrainingBatch, training_args: TrainingArgs, step: int):
    tracker_loss_dict: dict&#91;str, Any&#93; = &#123;&#125;
    latents_vis_dict = training_batch.latent_vis_dict
    latent_log_keys = &#91;&#x27;noisy_input&#x27;, &#x27;x0&#x27;, &#x27;pred_video&#x27;&#93;
    for latent_key in latent_log_keys:
        assert latent_key in latents_vis_dict and latents_vis_dict&#91;latent_key&#93; is not None
        latent = latents_vis_dict&#91;latent_key&#93;
        pixel_latent = self.decoding_stage.decode(latent, training_args)

        video = pixel_latent.cpu().float()
        video = video.permute(0, 2, 1, 3, 4)
        video = (video * 255).numpy().astype(np.uint8)
        video_artifact = self.tracker.video(video, fps=16, format=&quot;mp4&quot;)  # change to 16 for Wan2.1
        if video_artifact is not None:
            tracker_loss_dict&#91;latent_key&#93; = video_artifact
        # Clean up references
        del video, pixel_latent, latent

    if self.global_rank == 0 and tracker_loss_dict:
        self.tracker.log_artifacts(tracker_loss_dict, step)</code></pre></details>
<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.main"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.main</code></h2>
<pre class="doc-signature"><code>main(args) -&gt; None</code></pre>

<h2 id="fastvideo.training.matrixgame2_ode_causal_pipeline.build_parser"><code>fastvideo.training.matrixgame2_ode_causal_pipeline.build_parser</code></h2>
<pre class="doc-signature"><code>build_parser(pipeline_class: str | None = None, pipeline_module: str | None = None) -&gt; FlexibleArgumentParser</code></pre>
<p>Build the training-runner CLI parser.</p>
<p>When <code>pipeline_class</code>/<code>pipeline_module</code> are given they become optional defaults,
so the deprecated per-pipeline <code>__main__</code> blocks keep working without the flags.</p>
</div>
