---
title: matrixgame3_denoising
---

<div class="python-reference">
<a id="fastvideo.pipelines.stages.matrixgame3_denoising-classes"></a>
<a id="fastvideo.pipelines.stages.matrixgame3_denoising-functions"></a>
<a id="fastvideo.pipelines.stages.matrixgame3_denoising"></a>

<h2 id="fastvideo.pipelines.stages.matrixgame3_denoising.FastVideoArgs"><code>fastvideo.pipelines.stages.matrixgame3_denoising.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.pipelines.stages.matrixgame3_denoising.FastVideoArgs.is_output_rank"><code>fastvideo.pipelines.stages.matrixgame3_denoising.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.pipelines.stages.matrixgame3_denoising.FastVideoArgs.add_cli_args"><code>fastvideo.pipelines.stages.matrixgame3_denoising.FastVideoArgs.add_cli_args</code></h3>
<pre class="doc-signature"><code>add_cli_args(parser: FlexibleArgumentParser) -&gt; FlexibleArgumentParser</code></pre>

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

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

<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.FastVideoArgs.check_fastvideo_args"><code>fastvideo.pipelines.stages.matrixgame3_denoising.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.pipelines.stages.matrixgame3_denoising.FastVideoArgs.finalize_device_offload_policy"><code>fastvideo.pipelines.stages.matrixgame3_denoising.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.pipelines.stages.matrixgame3_denoising.FastVideoArgs.disable_offload_on_unified_memory"><code>fastvideo.pipelines.stages.matrixgame3_denoising.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.pipelines.stages.matrixgame3_denoising.set_forward_context"><code>fastvideo.pipelines.stages.matrixgame3_denoising.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.pipelines.stages.matrixgame3_denoising.init_logger"><code>fastvideo.pipelines.stages.matrixgame3_denoising.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.pipelines.stages.matrixgame3_denoising.compute_relative_poses"><code>fastvideo.pipelines.stages.matrixgame3_denoising.compute_relative_poses</code></h2>
<pre class="doc-signature"><code>compute_relative_poses(c2ws_mat: torch.Tensor, framewise: bool = False, normalize_trans: bool = True) -&gt; torch.Tensor</code></pre>

<h2 id="fastvideo.pipelines.stages.matrixgame3_denoising.build_extrinsics_from_actions"><code>fastvideo.pipelines.stages.matrixgame3_denoising.build_extrinsics_from_actions</code></h2>
<pre class="doc-signature"><code>build_extrinsics_from_actions(keyboard_conditions: torch.Tensor, mouse_conditions: torch.Tensor) -&gt; torch.Tensor</code></pre>

<h2 id="fastvideo.pipelines.stages.matrixgame3_denoising.build_matrixgame3_action_preset"><code>fastvideo.pipelines.stages.matrixgame3_denoising.build_matrixgame3_action_preset</code></h2>
<pre class="doc-signature"><code>build_matrixgame3_action_preset(num_frames: int, seed: int | None = None) -&gt; tuple&#91;torch.Tensor, torch.Tensor&#93;</code></pre>

<h2 id="fastvideo.pipelines.stages.matrixgame3_denoising.build_plucker_from_c2ws"><code>fastvideo.pipelines.stages.matrixgame3_denoising.build_plucker_from_c2ws</code></h2>
<pre class="doc-signature"><code>build_plucker_from_c2ws(c2ws_seq: torch.Tensor, src_indices: np.ndarray, tgt_indices: np.ndarray, *, target_h: int, target_w: int, latent_h: int, latent_w: int, framewise: bool = True) -&gt; torch.Tensor</code></pre>

<h2 id="fastvideo.pipelines.stages.matrixgame3_denoising.build_plucker_from_pose"><code>fastvideo.pipelines.stages.matrixgame3_denoising.build_plucker_from_pose</code></h2>
<pre class="doc-signature"><code>build_plucker_from_pose(c2ws_pose: torch.Tensor, *, target_h: int, target_w: int, latent_h: int, latent_w: int) -&gt; torch.Tensor</code></pre>

<h2 id="fastvideo.pipelines.stages.matrixgame3_denoising.interpolate_camera_poses_handedness"><code>fastvideo.pipelines.stages.matrixgame3_denoising.interpolate_camera_poses_handedness</code></h2>
<pre class="doc-signature"><code>interpolate_camera_poses_handedness(src_indices: np.ndarray, src_rot_mat: np.ndarray, src_trans_vec: np.ndarray, tgt_indices: np.ndarray) -&gt; torch.Tensor</code></pre>

<h2 id="fastvideo.pipelines.stages.matrixgame3_denoising.select_memory_idx_fov"><code>fastvideo.pipelines.stages.matrixgame3_denoising.select_memory_idx_fov</code></h2>
<pre class="doc-signature"><code>select_memory_idx_fov(extrinsics_all: torch.Tensor | np.ndarray, current_start_frame_idx: int, selected_index_base: list&#91;int&#93;, *, height: int = 720, width: int = 1280, return_confidence: bool = False) -&gt; list&#91;int&#93; | tuple&#91;list&#91;int&#93;, list&#91;float&#93;&#93;</code></pre>

<h2 id="fastvideo.pipelines.stages.matrixgame3_denoising.ForwardBatch"><code>fastvideo.pipelines.stages.matrixgame3_denoising.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.pipelines.stages.matrixgame3_denoising.DenoisingStage"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage</code></h2>
<pre class="doc-signature"><code>DenoisingStage(transformer, scheduler, pipeline = None, transformer_2 = None, vae = None)</code></pre>
<p>Stage for running the denoising loop in diffusion pipelines.</p>
<p>This stage handles the iterative denoising process that transforms
the initial noise into the final output.</p>

<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.forward"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>
<p>Run the denoising loop.</p>
<h4>Parameters</h4>
<dl>
<dt><code>batch: ForwardBatch</code></dt><dd><p>The current batch information.</p></dd>
<dt><code>fastvideo_args: FastVideoArgs</code></dt><dd><p>The inference arguments.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>ForwardBatch</code></dt><dd><p>The batch with denoised latents.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.prepare_denoising"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.prepare_denoising</code></h3>
<pre class="doc-signature"><code>prepare_denoising(batch, fastvideo_args, target_dtype) -&gt; DenoisingState</code></pre>
<p>Build request-local state. Family stages specialize latent conditioning.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.prepare_model_kwargs"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.prepare_model_kwargs</code></h3>
<pre class="doc-signature"><code>prepare_model_kwargs(batch, fastvideo_args) -&gt; tuple&#91;dict&#91;str, Any&#93;, dict&#91;str, Any&#93;&#93;</code></pre>
<p>Step-invariant transformer kwargs as (conditional, unconditional).</p>
<p>Family stages add named conditioning here (Wan-S2V's audio, reference
and motion latents) without the shared loop learning about it.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.activate_transformer"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.activate_transformer</code></h3>
<pre class="doc-signature"><code>activate_transformer(model, inactive_model, fastvideo_args) -&gt; None</code></pre>
<p>Keep CPU/layerwise/FSDP offload decisions independent of the sampling recipe.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.select_model"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.select_model</code></h3>
<pre class="doc-signature"><code>select_model(timestep, batch, fastvideo_args, state) -&gt; tuple&#91;Any, float&#93;</code></pre>

<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.prepare_model_input"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.prepare_model_input</code></h3>
<pre class="doc-signature"><code>prepare_model_input(latents, batch, target_dtype, state) -&gt; torch.Tensor</code></pre>

<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.prepare_timestep"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.prepare_timestep</code></h3>
<pre class="doc-signature"><code>prepare_timestep(timestep, latent_model_input, batch, state) -&gt; torch.Tensor</code></pre>

<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.finish_step"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.finish_step</code></h3>
<pre class="doc-signature"><code>finish_step(latents, state) -&gt; torch.Tensor</code></pre>

<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.prepare_extra_func_kwargs"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.prepare_extra_func_kwargs</code></h3>
<pre class="doc-signature"><code>prepare_extra_func_kwargs(func, kwargs) -&gt; dict&#91;str, Any&#93;</code></pre>
<p>Prepare extra kwargs for the scheduler step / denoise step.</p>
<h4>Parameters</h4>
<dl>
<dt><code>func</code></dt><dd><p>The function to prepare kwargs for.</p></dd>
<dt><code>kwargs</code></dt><dd><p>The kwargs to prepare.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>dict[str, Any]</code></dt><dd><p>The prepared kwargs.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.progress_bar"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.progress_bar</code></h3>
<pre class="doc-signature"><code>progress_bar(iterable: Iterable | None = None, total: int | None = None) -&gt; tqdm</code></pre>
<p>Create a progress bar for the denoising process.</p>
<h4>Parameters</h4>
<dl>
<dt><code>iterable: Iterable | None</code></dt><dd><p>The iterable to iterate over.</p></dd>
<dt><code>total: int | None</code></dt><dd><p>The total number of items.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>tqdm</code></dt><dd><p>A tqdm progress bar.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.rescale_noise_cfg"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.rescale_noise_cfg</code></h3>
<pre class="doc-signature"><code>rescale_noise_cfg(noise_cfg, noise_pred_text, guidance_rescale = 0.0) -&gt; torch.Tensor</code></pre>
<p>Rescale noise prediction according to guidance_rescale.</p>
<p>Based on findings of "Common Diffusion Noise Schedules and Sample Steps are Flawed"
(https://arxiv.org/pdf/2305.08891.pdf), Section 3.4.</p>
<h4>Parameters</h4>
<dl>
<dt><code>noise_cfg</code></dt><dd><p>The noise prediction with guidance.</p></dd>
<dt><code>noise_pred_text</code></dt><dd><p>The text-conditioned noise prediction.</p></dd>
<dt><code>guidance_rescale</code></dt><dd><p>The guidance rescale factor.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>torch.Tensor</code></dt><dd><p>The rescaled noise prediction.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.verify_input"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify denoising stage inputs.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.verify_output"><code>fastvideo.pipelines.stages.matrixgame3_denoising.DenoisingStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify denoising stage outputs.</p>
<h2 id="fastvideo.pipelines.stages.matrixgame3_denoising.V"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V</code></h2>
<pre class="doc-signature"><code>V()</code></pre>
<p>Common validators for pipeline stages.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.not_none"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.not_none</code></h3>
<pre class="doc-signature"><code>not_none(value: Any) -&gt; bool</code></pre>
<p>Check if value is not None.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.positive_int"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.positive_int</code></h3>
<pre class="doc-signature"><code>positive_int(value: Any) -&gt; bool</code></pre>
<p>Check if value is a positive integer.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.non_negative_int"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.non_negative_int</code></h3>
<pre class="doc-signature"><code>non_negative_int(value: Any) -&gt; bool</code></pre>
<p>Check if value is a non-negative integer (allows 0).</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.positive_float"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.positive_float</code></h3>
<pre class="doc-signature"><code>positive_float(value: Any) -&gt; bool</code></pre>
<p>Check if value is a positive float.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.non_negative_float"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.non_negative_float</code></h3>
<pre class="doc-signature"><code>non_negative_float(value: Any) -&gt; bool</code></pre>
<p>Check if value is a non-negative float.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.divisible_by"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.divisible_by</code></h3>
<pre class="doc-signature"><code>divisible_by(value: Any, divisor: int) -&gt; bool</code></pre>
<p>Check if value is divisible by divisor.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.is_tensor"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.is_tensor</code></h3>
<pre class="doc-signature"><code>is_tensor(value: Any) -&gt; bool</code></pre>
<p>Check if value is a torch tensor and doesn't contain NaN values.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.tensor_with_dims"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.tensor_with_dims</code></h3>
<pre class="doc-signature"><code>tensor_with_dims(value: Any, dims: int) -&gt; bool</code></pre>
<p>Check if value is a tensor with specific dimensions and no NaN values.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.tensor_min_dims"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.tensor_min_dims</code></h3>
<pre class="doc-signature"><code>tensor_min_dims(value: Any, min_dims: int) -&gt; bool</code></pre>
<p>Check if value is a tensor with at least min_dims dimensions and no NaN values.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.tensor_shape_matches"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.tensor_shape_matches</code></h3>
<pre class="doc-signature"><code>tensor_shape_matches(value: Any, expected_shape: tuple) -&gt; bool</code></pre>
<p>Check if tensor shape matches expected shape (None for any size) and no NaN values.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.list_not_empty"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.list_not_empty</code></h3>
<pre class="doc-signature"><code>list_not_empty(value: Any) -&gt; bool</code></pre>
<p>Check if value is a non-empty list.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.list_length"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.list_length</code></h3>
<pre class="doc-signature"><code>list_length(value: Any, length: int) -&gt; bool</code></pre>
<p>Check if list has specific length.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.list_min_length"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.list_min_length</code></h3>
<pre class="doc-signature"><code>list_min_length(value: Any, min_length: int) -&gt; bool</code></pre>
<p>Check if list has at least min_length items.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.string_not_empty"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.string_not_empty</code></h3>
<pre class="doc-signature"><code>string_not_empty(value: Any) -&gt; bool</code></pre>
<p>Check if value is a non-empty string.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.string_or_list_strings"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.string_or_list_strings</code></h3>
<pre class="doc-signature"><code>string_or_list_strings(value: Any) -&gt; bool</code></pre>
<p>Check if value is a string or list of strings.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.bool_value"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.bool_value</code></h3>
<pre class="doc-signature"><code>bool_value(value: Any) -&gt; bool</code></pre>
<p>Check if value is a boolean.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.generator_or_list_generators"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.generator_or_list_generators</code></h3>
<pre class="doc-signature"><code>generator_or_list_generators(value: Any) -&gt; bool</code></pre>
<p>Check if value is a Generator or list of Generators.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.is_list"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.is_list</code></h3>
<pre class="doc-signature"><code>is_list(value: Any) -&gt; bool</code></pre>
<p>Check if value is a list (can be empty).</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.is_tuple"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.is_tuple</code></h3>
<pre class="doc-signature"><code>is_tuple(value: Any) -&gt; bool</code></pre>
<p>Check if value is a tuple.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.none_or_tensor"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.none_or_tensor</code></h3>
<pre class="doc-signature"><code>none_or_tensor(value: Any) -&gt; bool</code></pre>
<p>Check if value is None or a tensor without NaN values.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.list_of_tensors_with_dims"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.list_of_tensors_with_dims</code></h3>
<pre class="doc-signature"><code>list_of_tensors_with_dims(value: Any, dims: int) -&gt; bool</code></pre>
<p>Check if value is a non-empty list where all items are tensors with specific dimensions and no NaN values.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.list_of_tensors"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.list_of_tensors</code></h3>
<pre class="doc-signature"><code>list_of_tensors(value: Any) -&gt; bool</code></pre>
<p>Check if value is a non-empty list where all items are tensors without NaN values.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.list_of_tensors_with_min_dims"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.list_of_tensors_with_min_dims</code></h3>
<pre class="doc-signature"><code>list_of_tensors_with_min_dims(value: Any, min_dims: int) -&gt; bool</code></pre>
<p>Check if value is a non-empty list where all items are tensors with at least min_dims dimensions and no NaN values.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.none_or_tensor_with_dims"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.none_or_tensor_with_dims</code></h3>
<pre class="doc-signature"><code>none_or_tensor_with_dims(dims: int) -&gt; Callable&#91;&#91;Any&#93;, bool&#93;</code></pre>
<p>Return a validator that checks if value is None or a tensor with specific dimensions and no NaN values.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.none_or_list"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.none_or_list</code></h3>
<pre class="doc-signature"><code>none_or_list(value: Any) -&gt; bool</code></pre>
<p>Check if value is None or a list.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.none_or_positive_int"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.none_or_positive_int</code></h3>
<pre class="doc-signature"><code>none_or_positive_int(value: Any) -&gt; bool</code></pre>
<p>Check if value is None or a positive integer.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.with_dims"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.with_dims</code></h3>
<pre class="doc-signature"><code>with_dims(dims: int) -&gt; Callable&#91;&#91;Any&#93;, bool&#93;</code></pre>
<p>Return a validator that checks if tensor has specific dimensions and no NaN values.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.min_list_length"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.min_list_length</code></h3>
<pre class="doc-signature"><code>min_list_length(min_length: int) -&gt; Callable&#91;&#91;Any&#93;, bool&#93;</code></pre>
<p>Return a validator that checks if a list has at least min_length items.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.min_dims"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.min_dims</code></h3>
<pre class="doc-signature"><code>min_dims(min_dims: int) -&gt; Callable&#91;&#91;Any&#93;, bool&#93;</code></pre>
<p>Return a validator that checks if tensor has at least min_dims dimensions and no NaN values.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.divisible"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.divisible</code></h3>
<pre class="doc-signature"><code>divisible(divisor: int) -&gt; Callable&#91;&#91;Any&#93;, bool&#93;</code></pre>
<p>Return a validator that checks if value is divisible by divisor.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.positive_int_divisible"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.positive_int_divisible</code></h3>
<pre class="doc-signature"><code>positive_int_divisible(divisor: int) -&gt; Callable&#91;&#91;Any&#93;, bool&#93;</code></pre>
<p>Return a validator that checks if value is a positive integer divisible by divisor.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.list_of_tensors_dims"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.list_of_tensors_dims</code></h3>
<pre class="doc-signature"><code>list_of_tensors_dims(dims: int) -&gt; Callable&#91;&#91;Any&#93;, bool&#93;</code></pre>
<p>Return a validator that checks if value is a list of tensors with specific dimensions and no NaN values.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.V.list_of_tensors_min_dims"><code>fastvideo.pipelines.stages.matrixgame3_denoising.V.list_of_tensors_min_dims</code></h3>
<pre class="doc-signature"><code>list_of_tensors_min_dims(min_dims: int) -&gt; Callable&#91;&#91;Any&#93;, bool&#93;</code></pre>
<p>Return a validator that checks if value is a list of tensors with at least min_dims dimensions and no NaN values.</p>
<h2 id="fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult"><code>fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult</code></h2>
<pre class="doc-signature"><code>VerificationResult()</code></pre>
<p>Wrapper class for stage verification results.</p>

<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult.add_check"><code>fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult.add_check</code></h3>
<pre class="doc-signature"><code>add_check(field_name: str, value: Any, validators: Callable&#91;&#91;Any&#93;, bool&#93; | list&#91;Callable&#91;&#91;Any&#93;, bool&#93;&#93;) -&gt; VerificationResult</code></pre>
<p>Add a validation check for a field.</p>
<h4>Parameters</h4>
<dl>
<dt><code>field_name: str</code></dt><dd><p>Name of the field being checked</p></dd>
<dt><code>value: Any</code></dt><dd><p>The actual value to validate</p></dd>
<dt><code>validators: Callable[[Any], bool] | list[Callable[[Any], bool]]</code></dt><dd><p>Single validation function or list of validation functions.
       Each function will be called with the value as its first argument.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>VerificationResult</code></dt><dd><p>Self for method chaining</p></dd>
</dl>
<h4>Examples</h4>
<h1>Single validator</h1>
<p>result.add_check("tensor", my_tensor, V.is_tensor)</p>
<h1>Multiple validators (all must pass)</h1>
<p>result.add_check("latents", batch.latents, [V.is_tensor, V.with_dims(5)])</p>
<h1>Using partial functions for parameters</h1>
<p>result.add_check("height", batch.height, [V.not_none, V.divisible(8)])</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult.is_valid"><code>fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult.is_valid</code></h3>
<pre class="doc-signature"><code>is_valid() -&gt; bool</code></pre>
<p>Check if all validations passed.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult.get_failed_fields"><code>fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult.get_failed_fields</code></h3>
<pre class="doc-signature"><code>get_failed_fields() -&gt; list&#91;str&#93;</code></pre>
<p>Get list of fields that failed validation.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult.get_detailed_failures"><code>fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult.get_detailed_failures</code></h3>
<pre class="doc-signature"><code>get_detailed_failures() -&gt; dict&#91;str, list&#91;ValidationFailure&#93;&#93;</code></pre>
<p>Get detailed failure information for each failed field.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult.get_failure_summary"><code>fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult.get_failure_summary</code></h3>
<pre class="doc-signature"><code>get_failure_summary() -&gt; str</code></pre>
<p>Get a comprehensive summary of all validation failures.</p>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult.to_dict"><code>fastvideo.pipelines.stages.matrixgame3_denoising.VerificationResult.to_dict</code></h3>
<pre class="doc-signature"><code>to_dict() -&gt; dict</code></pre>
<p>Convert to dictionary for backward compatibility.</p>
<h2 id="fastvideo.pipelines.stages.matrixgame3_denoising.MatrixGame3DenoisingStage"><code>fastvideo.pipelines.stages.matrixgame3_denoising.MatrixGame3DenoisingStage</code></h2>
<pre class="doc-signature"><code>MatrixGame3DenoisingStage(transformer, scheduler, pipeline = None, transformer_2 = None, vae = None)</code></pre>

<details><summary>Source</summary><pre><code>class MatrixGame3DenoisingStage(DenoisingStage):

    def _infer_num_iterations(self, batch: ForwardBatch) -&gt; int:
        if batch.num_iterations is not None:
            return batch.num_iterations
        if isinstance(batch.num_frames, int) and batch.num_frames &gt; 57:
            return 1 + max(0, (batch.num_frames - 57 + 39) // 40)
        return 1

    def verify_input(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult:
        result = VerificationResult()
        result.add_check(&quot;latents&quot;, batch.latents, &#91;V.is_tensor, V.with_dims(5)&#93;)
        result.add_check(&quot;prompt_embeds&quot;, batch.prompt_embeds, V.list_not_empty)
        result.add_check(&quot;image_embeds&quot;, batch.image_embeds, V.is_list)
        result.add_check(&quot;image_latent&quot;, batch.image_latent, V.none_or_tensor_with_dims(5))
        result.add_check(&quot;num_inference_steps&quot;, batch.num_inference_steps, V.positive_int)
        result.add_check(&quot;guidance_scale&quot;, batch.guidance_scale, V.positive_float)
        result.add_check(&quot;eta&quot;, batch.eta, V.non_negative_float)
        result.add_check(&quot;generator&quot;, batch.generator, V.generator_or_list_generators)
        result.add_check(&quot;do_classifier_free_guidance&quot;, batch.do_classifier_free_guidance, V.bool_value)
        result.add_check(&quot;negative_prompt_embeds&quot;, batch.negative_prompt_embeds,
                         lambda x: not batch.do_classifier_free_guidance or V.list_not_empty(x))
        return result

    def forward(
        self,
        batch: ForwardBatch,
        fastvideo_args: FastVideoArgs,
    ) -&gt; ForwardBatch:
        assert batch.latents is not None, &quot;latents must be prepared before MatrixGame3 denoising&quot;
        assert batch.image_latent is not None, &quot;MatrixGame3 requires first-frame VAE latents&quot;
        assert batch.prompt_embeds, &quot;MatrixGame3 requires text embeddings&quot;

        target_dtype = torch.bfloat16
        autocast_enabled = (target_dtype != torch.float32) and not fastvideo_args.disable_autocast
        device = batch.latents.device

        extra_step_kwargs = self.prepare_extra_func_kwargs(
            self.scheduler.step,
            &#123;
                &quot;generator&quot;: batch.generator,
                &quot;eta&quot;: batch.eta,
            &#125;,
        )

        prompt_embeds = batch.prompt_embeds
        negative_prompt_embeds = batch.negative_prompt_embeds or &#91;&#93;
        use_base_model = batch.use_base_model

        latents = batch.latents
        img_cond = batch.image_latent.to(device=device, dtype=target_dtype)
        latent_h = latents.shape&#91;-2&#93;
        latent_w = latents.shape&#91;-1&#93;
        patch_h = int(getattr(self.transformer, &quot;patch_size&quot;, (1, 2, 2))&#91;1&#93;)
        patch_w = int(getattr(self.transformer, &quot;patch_size&quot;, (1, 2, 2))&#91;2&#93;)
        latent_h_aligned = (latent_h // patch_h) * patch_h
        latent_w_aligned = (latent_w // patch_w) * patch_w
        if latent_h_aligned != latent_h or latent_w_aligned != latent_w:
            logger.warning(
                &quot;Cropping MatrixGame3 latents to patch-aligned size: (%d, %d) -&gt; (%d, %d), patch=(%d,%d)&quot;,
                latent_h,
                latent_w,
                latent_h_aligned,
                latent_w_aligned,
                patch_h,
                patch_w,
            )
            latents = latents&#91;:, :, :, :latent_h_aligned, :latent_w_aligned&#93;
            img_cond = img_cond&#91;:, :, :, :latent_h_aligned, :latent_w_aligned&#93;
            latent_h = latent_h_aligned
            latent_w = latent_w_aligned
        spatial_ratio = fastvideo_args.pipeline_config.vae_config.arch_config.spatial_compression_ratio
        target_h = latent_h * spatial_ratio
        target_w = latent_w * spatial_ratio
        num_iterations = self._infer_num_iterations(batch)
        clip_frame = 56  # hardcode for now
        first_clip_frame = clip_frame + 1
        past_frame = 16

        def align_frame_to_block(frame_idx: int) -&gt; int:
            return (frame_idx - 1) // 4 * 4 + 1 if frame_idx &gt; 0 else 1

        def get_latent_idx(frame_idx: int) -&gt; int:
            return (frame_idx - 1) // 4 + 1

        total_video_frames = first_clip_frame + max(0, num_iterations - 1) * (clip_frame - past_frame)
        if batch.keyboard_cond is None or batch.mouse_cond is None:
            keyboard_cond, mouse_cond = build_matrixgame3_action_preset(total_video_frames, seed=batch.seed)
            batch.keyboard_cond = keyboard_cond.unsqueeze(0).to(device=device, dtype=target_dtype)
            batch.mouse_cond = mouse_cond.unsqueeze(0).to(device=device, dtype=target_dtype)
        else:
            batch.keyboard_cond = batch.keyboard_cond.to(device=device, dtype=target_dtype)
            batch.mouse_cond = batch.mouse_cond.to(device=device, dtype=target_dtype)

        # MG3 currently assumes batch_size=1 for camera-trajectory derivation. If a
        # future caller batches multiple action streams, build_extrinsics_from_actions
        # must be made per-batch-item; until then, fail loudly rather than silently
        # using item-0&#x27;s trajectory for the whole batch.
        assert batch.keyboard_cond.shape&#91;0&#93; == 1, (
            &quot;MatrixGame3 denoising stage requires batch_size=1 for action conditioning; &quot;
            f&quot;got batch.keyboard_cond.shape&#91;0&#93;=&#123;batch.keyboard_cond.shape&#91;0&#93;&#125;. &quot;
            &quot;If batched action streams are needed, update build_extrinsics_from_actions &quot;
            &quot;to handle per-batch-item trajectories.&quot;)
        extrinsics_all = build_extrinsics_from_actions(batch.keyboard_cond&#91;0&#93;, batch.mouse_cond&#91;0&#93;).to(device)
        all_latents: list&#91;torch.Tensor&#93; = &#91;&#93;

        for clip_idx in range(num_iterations):
            try:
                self.scheduler.set_timesteps(
                    batch.num_inference_steps,
                    device=device,
                    shift=fastvideo_args.pipeline_config.flow_shift,
                )
            except TypeError:
                self.scheduler.set_timesteps(batch.num_inference_steps, device=device)
            timesteps = self.scheduler.timesteps

            first_clip = clip_idx == 0
            current_end_frame_idx = first_clip_frame if first_clip else first_clip_frame + clip_idx * (clip_frame -
                                                                                                       past_frame)
            current_start_frame_idx = 0 if first_clip else current_end_frame_idx - clip_frame
            # 15 for first clip, 14 for later clips
            current_latent_frames = (first_clip_frame - 1) // 4 + 1 if first_clip else clip_frame // 4
            cond_frames = 1 if first_clip else 4
            latent_start_idx = get_latent_idx(current_start_frame_idx)
            latent_end_idx = get_latent_idx(current_end_frame_idx)

            clip_keyboard = batch.keyboard_cond&#91;:, current_start_frame_idx:current_end_frame_idx&#93;
            clip_mouse = batch.mouse_cond&#91;:, current_start_frame_idx:current_end_frame_idx&#93;

            cond_frames = min(cond_frames, img_cond.shape&#91;2&#93;)
            clip_generator = batch.generator&#91;0&#93; if isinstance(batch.generator, list) else batch.generator
            current_latents = torch.randn(
                (latents.shape&#91;0&#93;, latents.shape&#91;1&#93;, latent_end_idx - latent_start_idx, latent_h, latent_w),
                generator=clip_generator if isinstance(clip_generator, torch.Generator) else None,
                dtype=target_dtype).to(device)
            current_latents&#91;:, :, :cond_frames&#93; = img_cond&#91;:, :, :cond_frames&#93;

            c2ws_chunk = extrinsics_all&#91;current_start_frame_idx:current_end_frame_idx&#93;
            src_indices = np.linspace(current_start_frame_idx, current_end_frame_idx - 1,
                                      current_end_frame_idx - current_start_frame_idx)
            tgt_indices = np.linspace(0 if first_clip else current_start_frame_idx + 3, current_end_frame_idx - 1,
                                      current_latent_frames)

            if batch.c2ws_plucker_emb is not None:
                plucker_no_mem = batch.c2ws_plucker_emb&#91;:, :, current_start_frame_idx:current_end_frame_idx&#93;
                plucker_no_mem = plucker_no_mem.to(device=device, dtype=target_dtype)
            else:
                plucker_no_mem = build_plucker_from_c2ws(
                    c2ws_chunk,
                    src_indices,
                    tgt_indices,
                    target_h=target_h,
                    target_w=target_w,
                    latent_h=latent_h,
                    latent_w=latent_w,
                    framewise=True,
                ).to(device=device, dtype=target_dtype)

            x_memory = None
            timestep_memory = None
            mouse_cond_memory = None
            keyboard_cond_memory = None
            memory_latent_idx = None
            c2ws_plucker_emb = plucker_no_mem
            if all_latents:
                # t-1, t-9, t-17, t-25, t-33
                selected_index_base = &#91;current_end_frame_idx - offset for offset in range(1, 34, 8)&#93;
                selected_index = select_memory_idx_fov(
                    extrinsics_all,
                    current_start_frame_idx,
                    selected_index_base,
                    height=target_h,
                    width=target_w,
                )
                if len(selected_index) &gt; 0:
                    selected_index&#91;-1&#93; = 4

                memory_pluckers: list&#91;torch.Tensor&#93; = &#91;&#93;
                memory_latent_idx = &#91;&#93;
                for mem_idx, reference_idx in zip(selected_index, selected_index_base, strict=False):
                    memory_latent_idx.append(get_latent_idx(mem_idx))

                    mem_idx_aligned = align_frame_to_block(mem_idx)
                    mem_block = extrinsics_all&#91;mem_idx_aligned:mem_idx_aligned + 4&#93;
                    mem_src = np.linspace(mem_idx_aligned, mem_idx_aligned + mem_block.shape&#91;0&#93; - 1, mem_block.shape&#91;0&#93;)
                    mem_tgt = np.array(&#91;mem_idx_aligned + 3&#93;, dtype=np.float32)
                    mem_pose = interpolate_camera_poses_handedness(
                        src_indices=mem_src,
                        src_rot_mat=mem_block&#91;:, :3, :3&#93;.detach().cpu().numpy(),
                        src_trans_vec=mem_block&#91;:, :3, 3&#93;.detach().cpu().numpy(),
                        tgt_indices=mem_tgt,
                    ).to(device=device, dtype=target_dtype)
                    reference_pose = extrinsics_all&#91;reference_idx:reference_idx + 1&#93;.to(device=device,
                                                                                        dtype=target_dtype)
                    rel_pair = torch.cat(&#91;reference_pose, mem_pose&#93;, dim=0)
                    rel_pose = compute_relative_poses(rel_pair, framewise=False)&#91;1:2&#93;
                    memory_pluckers.append(
                        build_plucker_from_pose(
                            rel_pose,
                            target_h=target_h,
                            target_w=target_w,
                            latent_h=latent_h,
                            latent_w=latent_w,
                        ).to(device=device, dtype=target_dtype))

                if memory_pluckers:
                    c2ws_plucker_emb = torch.cat(memory_pluckers + &#91;plucker_no_mem&#93;, dim=2)
                    history = torch.cat(all_latents, dim=2)
                    x_memory = history&#91;:, :, memory_latent_idx&#93;
                    mouse_cond_memory = torch.ones(
                        (clip_keyboard.shape&#91;0&#93;, len(memory_latent_idx), clip_mouse.shape&#91;-1&#93;),
                        device=device,
                        dtype=target_dtype)
                    keyboard_cond_memory = -torch.ones(
                        (clip_keyboard.shape&#91;0&#93;, len(memory_latent_idx), clip_keyboard.shape&#91;-1&#93;),
                        device=device,
                        dtype=target_dtype)
                    timestep_memory = x_memory.new_zeros(
                        (x_memory.shape&#91;0&#93;, x_memory.shape&#91;2&#93; * x_memory.shape&#91;3&#93; * x_memory.shape&#91;4&#93; // 4))
            with self.progress_bar(total=len(timesteps)) as progress_bar:
                for timestep in timesteps:
                    # Stop if interrupted
                    if getattr(self, &quot;interrupt&quot;, False):
                        break
                    latent_model_input = current_latents
                    if hasattr(self.scheduler, &quot;scale_model_input&quot;):
                        latent_model_input = self.scheduler.scale_model_input(latent_model_input, timestep)

                    timestep_tokens = latent_model_input.new_full(
                        (
                            latent_model_input.shape&#91;2&#93;,
                            latent_model_input.shape&#91;3&#93; * latent_model_input.shape&#91;4&#93; // 4,
                        ),
                        timestep,
                    )
                    timestep_tokens&#91;:cond_frames&#93;.zero_()
                    timestep_tokens = timestep_tokens.flatten().unsqueeze(0)
                    with torch.autocast(device_type=&quot;cuda&quot;, dtype=target_dtype, enabled=autocast_enabled), \
                        set_forward_context(current_timestep=timestep,
                                            attn_metadata=None,
                                            forward_batch=batch):
                        noise_pred = self.transformer(
                            latent_model_input,
                            prompt_embeds,
                            timestep_tokens,
                            mouse_cond=clip_mouse,
                            keyboard_cond=clip_keyboard,
                            x_memory=x_memory,
                            timestep_memory=timestep_memory,
                            mouse_cond_memory=mouse_cond_memory,
                            keyboard_cond_memory=keyboard_cond_memory,
                            c2ws_plucker_emb=c2ws_plucker_emb,
                            memory_latent_idx=memory_latent_idx,
                            predict_latent_idx=(latent_start_idx, latent_end_idx),
                        )

                        if use_base_model and batch.do_classifier_free_guidance and negative_prompt_embeds:
                            null_mouse_cond = torch.ones_like(clip_mouse)
                            null_keyboard_cond = -torch.ones_like(clip_keyboard)
                            noise_pred_uncond = self.transformer(
                                latent_model_input,
                                negative_prompt_embeds,
                                timestep_tokens,
                                mouse_cond=null_mouse_cond,
                                keyboard_cond=null_keyboard_cond,
                                x_memory=None,
                                timestep_memory=None,
                                mouse_cond_memory=None,
                                keyboard_cond_memory=None,
                                c2ws_plucker_emb=plucker_no_mem,
                                memory_latent_idx=None,
                                predict_latent_idx=(latent_start_idx, latent_end_idx),
                            )
                            noise_pred = noise_pred_uncond + batch.guidance_scale * (noise_pred - noise_pred_uncond)

                    if noise_pred.shape != current_latents.shape:
                        aligned_t = min(noise_pred.shape&#91;2&#93;, current_latents.shape&#91;2&#93;)
                        aligned_h = min(noise_pred.shape&#91;3&#93;, current_latents.shape&#91;3&#93;)
                        aligned_w = min(noise_pred.shape&#91;4&#93;, current_latents.shape&#91;4&#93;)
                        logger.warning(
                            &quot;Aligning noise/sample shapes before scheduler.step: noise=%s sample=%s -&gt; (*,*,%d,%d,%d)&quot;,
                            tuple(noise_pred.shape),
                            tuple(current_latents.shape),
                            aligned_t,
                            aligned_h,
                            aligned_w,
                        )
                        noise_pred = noise_pred&#91;:, :, :aligned_t, :aligned_h, :aligned_w&#93;
                        current_latents = current_latents&#91;:, :, :aligned_t, :aligned_h, :aligned_w&#93;

                    current_latents = self.scheduler.step(noise_pred,
                                                          timestep,
                                                          current_latents,
                                                          **extra_step_kwargs,
                                                          return_dict=False)&#91;0&#93;
                    current_latents&#91;:, :, :cond_frames&#93; = img_cond&#91;:, :, :cond_frames&#93;
                    progress_bar.update()

            img_cond = current_latents&#91;:, :, -4:&#93;.detach()
            denoised_pred = current_latents if first_clip else current_latents&#91;:, :, -10:&#93;
            all_latents.append(denoised_pred.detach())

        batch.latents = torch.cat(all_latents, dim=2)
        return batch</code></pre></details>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.MatrixGame3DenoisingStage.verify_input"><code>fastvideo.pipelines.stages.matrixgame3_denoising.MatrixGame3DenoisingStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>

<details><summary>Source</summary><pre><code>def verify_input(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult:
    result = VerificationResult()
    result.add_check(&quot;latents&quot;, batch.latents, &#91;V.is_tensor, V.with_dims(5)&#93;)
    result.add_check(&quot;prompt_embeds&quot;, batch.prompt_embeds, V.list_not_empty)
    result.add_check(&quot;image_embeds&quot;, batch.image_embeds, V.is_list)
    result.add_check(&quot;image_latent&quot;, batch.image_latent, V.none_or_tensor_with_dims(5))
    result.add_check(&quot;num_inference_steps&quot;, batch.num_inference_steps, V.positive_int)
    result.add_check(&quot;guidance_scale&quot;, batch.guidance_scale, V.positive_float)
    result.add_check(&quot;eta&quot;, batch.eta, V.non_negative_float)
    result.add_check(&quot;generator&quot;, batch.generator, V.generator_or_list_generators)
    result.add_check(&quot;do_classifier_free_guidance&quot;, batch.do_classifier_free_guidance, V.bool_value)
    result.add_check(&quot;negative_prompt_embeds&quot;, batch.negative_prompt_embeds,
                     lambda x: not batch.do_classifier_free_guidance or V.list_not_empty(x))
    return result</code></pre></details>
<h3 id="fastvideo.pipelines.stages.matrixgame3_denoising.MatrixGame3DenoisingStage.forward"><code>fastvideo.pipelines.stages.matrixgame3_denoising.MatrixGame3DenoisingStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>

<details><summary>Source</summary><pre><code>def forward(
    self,
    batch: ForwardBatch,
    fastvideo_args: FastVideoArgs,
) -&gt; ForwardBatch:
    assert batch.latents is not None, &quot;latents must be prepared before MatrixGame3 denoising&quot;
    assert batch.image_latent is not None, &quot;MatrixGame3 requires first-frame VAE latents&quot;
    assert batch.prompt_embeds, &quot;MatrixGame3 requires text embeddings&quot;

    target_dtype = torch.bfloat16
    autocast_enabled = (target_dtype != torch.float32) and not fastvideo_args.disable_autocast
    device = batch.latents.device

    extra_step_kwargs = self.prepare_extra_func_kwargs(
        self.scheduler.step,
        &#123;
            &quot;generator&quot;: batch.generator,
            &quot;eta&quot;: batch.eta,
        &#125;,
    )

    prompt_embeds = batch.prompt_embeds
    negative_prompt_embeds = batch.negative_prompt_embeds or &#91;&#93;
    use_base_model = batch.use_base_model

    latents = batch.latents
    img_cond = batch.image_latent.to(device=device, dtype=target_dtype)
    latent_h = latents.shape&#91;-2&#93;
    latent_w = latents.shape&#91;-1&#93;
    patch_h = int(getattr(self.transformer, &quot;patch_size&quot;, (1, 2, 2))&#91;1&#93;)
    patch_w = int(getattr(self.transformer, &quot;patch_size&quot;, (1, 2, 2))&#91;2&#93;)
    latent_h_aligned = (latent_h // patch_h) * patch_h
    latent_w_aligned = (latent_w // patch_w) * patch_w
    if latent_h_aligned != latent_h or latent_w_aligned != latent_w:
        logger.warning(
            &quot;Cropping MatrixGame3 latents to patch-aligned size: (%d, %d) -&gt; (%d, %d), patch=(%d,%d)&quot;,
            latent_h,
            latent_w,
            latent_h_aligned,
            latent_w_aligned,
            patch_h,
            patch_w,
        )
        latents = latents&#91;:, :, :, :latent_h_aligned, :latent_w_aligned&#93;
        img_cond = img_cond&#91;:, :, :, :latent_h_aligned, :latent_w_aligned&#93;
        latent_h = latent_h_aligned
        latent_w = latent_w_aligned
    spatial_ratio = fastvideo_args.pipeline_config.vae_config.arch_config.spatial_compression_ratio
    target_h = latent_h * spatial_ratio
    target_w = latent_w * spatial_ratio
    num_iterations = self._infer_num_iterations(batch)
    clip_frame = 56  # hardcode for now
    first_clip_frame = clip_frame + 1
    past_frame = 16

    def align_frame_to_block(frame_idx: int) -&gt; int:
        return (frame_idx - 1) // 4 * 4 + 1 if frame_idx &gt; 0 else 1

    def get_latent_idx(frame_idx: int) -&gt; int:
        return (frame_idx - 1) // 4 + 1

    total_video_frames = first_clip_frame + max(0, num_iterations - 1) * (clip_frame - past_frame)
    if batch.keyboard_cond is None or batch.mouse_cond is None:
        keyboard_cond, mouse_cond = build_matrixgame3_action_preset(total_video_frames, seed=batch.seed)
        batch.keyboard_cond = keyboard_cond.unsqueeze(0).to(device=device, dtype=target_dtype)
        batch.mouse_cond = mouse_cond.unsqueeze(0).to(device=device, dtype=target_dtype)
    else:
        batch.keyboard_cond = batch.keyboard_cond.to(device=device, dtype=target_dtype)
        batch.mouse_cond = batch.mouse_cond.to(device=device, dtype=target_dtype)

    # MG3 currently assumes batch_size=1 for camera-trajectory derivation. If a
    # future caller batches multiple action streams, build_extrinsics_from_actions
    # must be made per-batch-item; until then, fail loudly rather than silently
    # using item-0&#x27;s trajectory for the whole batch.
    assert batch.keyboard_cond.shape&#91;0&#93; == 1, (
        &quot;MatrixGame3 denoising stage requires batch_size=1 for action conditioning; &quot;
        f&quot;got batch.keyboard_cond.shape&#91;0&#93;=&#123;batch.keyboard_cond.shape&#91;0&#93;&#125;. &quot;
        &quot;If batched action streams are needed, update build_extrinsics_from_actions &quot;
        &quot;to handle per-batch-item trajectories.&quot;)
    extrinsics_all = build_extrinsics_from_actions(batch.keyboard_cond&#91;0&#93;, batch.mouse_cond&#91;0&#93;).to(device)
    all_latents: list&#91;torch.Tensor&#93; = &#91;&#93;

    for clip_idx in range(num_iterations):
        try:
            self.scheduler.set_timesteps(
                batch.num_inference_steps,
                device=device,
                shift=fastvideo_args.pipeline_config.flow_shift,
            )
        except TypeError:
            self.scheduler.set_timesteps(batch.num_inference_steps, device=device)
        timesteps = self.scheduler.timesteps

        first_clip = clip_idx == 0
        current_end_frame_idx = first_clip_frame if first_clip else first_clip_frame + clip_idx * (clip_frame -
                                                                                                   past_frame)
        current_start_frame_idx = 0 if first_clip else current_end_frame_idx - clip_frame
        # 15 for first clip, 14 for later clips
        current_latent_frames = (first_clip_frame - 1) // 4 + 1 if first_clip else clip_frame // 4
        cond_frames = 1 if first_clip else 4
        latent_start_idx = get_latent_idx(current_start_frame_idx)
        latent_end_idx = get_latent_idx(current_end_frame_idx)

        clip_keyboard = batch.keyboard_cond&#91;:, current_start_frame_idx:current_end_frame_idx&#93;
        clip_mouse = batch.mouse_cond&#91;:, current_start_frame_idx:current_end_frame_idx&#93;

        cond_frames = min(cond_frames, img_cond.shape&#91;2&#93;)
        clip_generator = batch.generator&#91;0&#93; if isinstance(batch.generator, list) else batch.generator
        current_latents = torch.randn(
            (latents.shape&#91;0&#93;, latents.shape&#91;1&#93;, latent_end_idx - latent_start_idx, latent_h, latent_w),
            generator=clip_generator if isinstance(clip_generator, torch.Generator) else None,
            dtype=target_dtype).to(device)
        current_latents&#91;:, :, :cond_frames&#93; = img_cond&#91;:, :, :cond_frames&#93;

        c2ws_chunk = extrinsics_all&#91;current_start_frame_idx:current_end_frame_idx&#93;
        src_indices = np.linspace(current_start_frame_idx, current_end_frame_idx - 1,
                                  current_end_frame_idx - current_start_frame_idx)
        tgt_indices = np.linspace(0 if first_clip else current_start_frame_idx + 3, current_end_frame_idx - 1,
                                  current_latent_frames)

        if batch.c2ws_plucker_emb is not None:
            plucker_no_mem = batch.c2ws_plucker_emb&#91;:, :, current_start_frame_idx:current_end_frame_idx&#93;
            plucker_no_mem = plucker_no_mem.to(device=device, dtype=target_dtype)
        else:
            plucker_no_mem = build_plucker_from_c2ws(
                c2ws_chunk,
                src_indices,
                tgt_indices,
                target_h=target_h,
                target_w=target_w,
                latent_h=latent_h,
                latent_w=latent_w,
                framewise=True,
            ).to(device=device, dtype=target_dtype)

        x_memory = None
        timestep_memory = None
        mouse_cond_memory = None
        keyboard_cond_memory = None
        memory_latent_idx = None
        c2ws_plucker_emb = plucker_no_mem
        if all_latents:
            # t-1, t-9, t-17, t-25, t-33
            selected_index_base = &#91;current_end_frame_idx - offset for offset in range(1, 34, 8)&#93;
            selected_index = select_memory_idx_fov(
                extrinsics_all,
                current_start_frame_idx,
                selected_index_base,
                height=target_h,
                width=target_w,
            )
            if len(selected_index) &gt; 0:
                selected_index&#91;-1&#93; = 4

            memory_pluckers: list&#91;torch.Tensor&#93; = &#91;&#93;
            memory_latent_idx = &#91;&#93;
            for mem_idx, reference_idx in zip(selected_index, selected_index_base, strict=False):
                memory_latent_idx.append(get_latent_idx(mem_idx))

                mem_idx_aligned = align_frame_to_block(mem_idx)
                mem_block = extrinsics_all&#91;mem_idx_aligned:mem_idx_aligned + 4&#93;
                mem_src = np.linspace(mem_idx_aligned, mem_idx_aligned + mem_block.shape&#91;0&#93; - 1, mem_block.shape&#91;0&#93;)
                mem_tgt = np.array(&#91;mem_idx_aligned + 3&#93;, dtype=np.float32)
                mem_pose = interpolate_camera_poses_handedness(
                    src_indices=mem_src,
                    src_rot_mat=mem_block&#91;:, :3, :3&#93;.detach().cpu().numpy(),
                    src_trans_vec=mem_block&#91;:, :3, 3&#93;.detach().cpu().numpy(),
                    tgt_indices=mem_tgt,
                ).to(device=device, dtype=target_dtype)
                reference_pose = extrinsics_all&#91;reference_idx:reference_idx + 1&#93;.to(device=device,
                                                                                    dtype=target_dtype)
                rel_pair = torch.cat(&#91;reference_pose, mem_pose&#93;, dim=0)
                rel_pose = compute_relative_poses(rel_pair, framewise=False)&#91;1:2&#93;
                memory_pluckers.append(
                    build_plucker_from_pose(
                        rel_pose,
                        target_h=target_h,
                        target_w=target_w,
                        latent_h=latent_h,
                        latent_w=latent_w,
                    ).to(device=device, dtype=target_dtype))

            if memory_pluckers:
                c2ws_plucker_emb = torch.cat(memory_pluckers + &#91;plucker_no_mem&#93;, dim=2)
                history = torch.cat(all_latents, dim=2)
                x_memory = history&#91;:, :, memory_latent_idx&#93;
                mouse_cond_memory = torch.ones(
                    (clip_keyboard.shape&#91;0&#93;, len(memory_latent_idx), clip_mouse.shape&#91;-1&#93;),
                    device=device,
                    dtype=target_dtype)
                keyboard_cond_memory = -torch.ones(
                    (clip_keyboard.shape&#91;0&#93;, len(memory_latent_idx), clip_keyboard.shape&#91;-1&#93;),
                    device=device,
                    dtype=target_dtype)
                timestep_memory = x_memory.new_zeros(
                    (x_memory.shape&#91;0&#93;, x_memory.shape&#91;2&#93; * x_memory.shape&#91;3&#93; * x_memory.shape&#91;4&#93; // 4))
        with self.progress_bar(total=len(timesteps)) as progress_bar:
            for timestep in timesteps:
                # Stop if interrupted
                if getattr(self, &quot;interrupt&quot;, False):
                    break
                latent_model_input = current_latents
                if hasattr(self.scheduler, &quot;scale_model_input&quot;):
                    latent_model_input = self.scheduler.scale_model_input(latent_model_input, timestep)

                timestep_tokens = latent_model_input.new_full(
                    (
                        latent_model_input.shape&#91;2&#93;,
                        latent_model_input.shape&#91;3&#93; * latent_model_input.shape&#91;4&#93; // 4,
                    ),
                    timestep,
                )
                timestep_tokens&#91;:cond_frames&#93;.zero_()
                timestep_tokens = timestep_tokens.flatten().unsqueeze(0)
                with torch.autocast(device_type=&quot;cuda&quot;, dtype=target_dtype, enabled=autocast_enabled), \
                    set_forward_context(current_timestep=timestep,
                                        attn_metadata=None,
                                        forward_batch=batch):
                    noise_pred = self.transformer(
                        latent_model_input,
                        prompt_embeds,
                        timestep_tokens,
                        mouse_cond=clip_mouse,
                        keyboard_cond=clip_keyboard,
                        x_memory=x_memory,
                        timestep_memory=timestep_memory,
                        mouse_cond_memory=mouse_cond_memory,
                        keyboard_cond_memory=keyboard_cond_memory,
                        c2ws_plucker_emb=c2ws_plucker_emb,
                        memory_latent_idx=memory_latent_idx,
                        predict_latent_idx=(latent_start_idx, latent_end_idx),
                    )

                    if use_base_model and batch.do_classifier_free_guidance and negative_prompt_embeds:
                        null_mouse_cond = torch.ones_like(clip_mouse)
                        null_keyboard_cond = -torch.ones_like(clip_keyboard)
                        noise_pred_uncond = self.transformer(
                            latent_model_input,
                            negative_prompt_embeds,
                            timestep_tokens,
                            mouse_cond=null_mouse_cond,
                            keyboard_cond=null_keyboard_cond,
                            x_memory=None,
                            timestep_memory=None,
                            mouse_cond_memory=None,
                            keyboard_cond_memory=None,
                            c2ws_plucker_emb=plucker_no_mem,
                            memory_latent_idx=None,
                            predict_latent_idx=(latent_start_idx, latent_end_idx),
                        )
                        noise_pred = noise_pred_uncond + batch.guidance_scale * (noise_pred - noise_pred_uncond)

                if noise_pred.shape != current_latents.shape:
                    aligned_t = min(noise_pred.shape&#91;2&#93;, current_latents.shape&#91;2&#93;)
                    aligned_h = min(noise_pred.shape&#91;3&#93;, current_latents.shape&#91;3&#93;)
                    aligned_w = min(noise_pred.shape&#91;4&#93;, current_latents.shape&#91;4&#93;)
                    logger.warning(
                        &quot;Aligning noise/sample shapes before scheduler.step: noise=%s sample=%s -&gt; (*,*,%d,%d,%d)&quot;,
                        tuple(noise_pred.shape),
                        tuple(current_latents.shape),
                        aligned_t,
                        aligned_h,
                        aligned_w,
                    )
                    noise_pred = noise_pred&#91;:, :, :aligned_t, :aligned_h, :aligned_w&#93;
                    current_latents = current_latents&#91;:, :, :aligned_t, :aligned_h, :aligned_w&#93;

                current_latents = self.scheduler.step(noise_pred,
                                                      timestep,
                                                      current_latents,
                                                      **extra_step_kwargs,
                                                      return_dict=False)&#91;0&#93;
                current_latents&#91;:, :, :cond_frames&#93; = img_cond&#91;:, :, :cond_frames&#93;
                progress_bar.update()

        img_cond = current_latents&#91;:, :, -4:&#93;.detach()
        denoised_pred = current_latents if first_clip else current_latents&#91;:, :, -10:&#93;
        all_latents.append(denoised_pred.detach())

    batch.latents = torch.cat(all_latents, dim=2)
    return batch</code></pre></details>
</div>
