---
title: flux_stages
---

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

<h2 id="fastvideo.pipelines.stages.flux_stages.get_local_torch_device"><code>fastvideo.pipelines.stages.flux_stages.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.pipelines.stages.flux_stages.FastVideoArgs"><code>fastvideo.pipelines.stages.flux_stages.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.flux_stages.FastVideoArgs.is_output_rank"><code>fastvideo.pipelines.stages.flux_stages.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.flux_stages.FastVideoArgs.add_cli_args"><code>fastvideo.pipelines.stages.flux_stages.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.flux_stages.FastVideoArgs.from_cli_args"><code>fastvideo.pipelines.stages.flux_stages.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.flux_stages.FastVideoArgs.from_kwargs"><code>fastvideo.pipelines.stages.flux_stages.FastVideoArgs.from_kwargs</code></h3>
<pre class="doc-signature"><code>from_kwargs(**kwargs: Any) -&gt; FastVideoArgs</code></pre>

<h3 id="fastvideo.pipelines.stages.flux_stages.FastVideoArgs.check_fastvideo_args"><code>fastvideo.pipelines.stages.flux_stages.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.flux_stages.FastVideoArgs.finalize_device_offload_policy"><code>fastvideo.pipelines.stages.flux_stages.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.flux_stages.FastVideoArgs.disable_offload_on_unified_memory"><code>fastvideo.pipelines.stages.flux_stages.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.flux_stages.set_forward_context"><code>fastvideo.pipelines.stages.flux_stages.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.flux_stages.init_logger"><code>fastvideo.pipelines.stages.flux_stages.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.flux_stages.ForwardBatch"><code>fastvideo.pipelines.stages.flux_stages.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.flux_stages.PipelineStage"><code>fastvideo.pipelines.stages.flux_stages.PipelineStage</code></h2>
<pre class="doc-signature"><code>PipelineStage()</code></pre>
<p>Abstract base class for all pipeline stages.</p>
<p>A pipeline stage represents a discrete step in the diffusion process that can be
composed with other stages to create a complete pipeline. Each stage is responsible
for a specific part of the process, such as prompt encoding, latent preparation, etc.</p>
<h3 id="fastvideo.pipelines.stages.flux_stages.PipelineStage.verify_input"><code>fastvideo.pipelines.stages.flux_stages.PipelineStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify the input for the stage.</p>
<h4>Example</h4>
<p>from fastvideo.pipelines.stages.validators import V, VerificationResult</p>
<p>def verify_input(self, batch, fastvideo_args):
    result = VerificationResult()
    result.add_check("height", batch.height, V.positive_int_divisible(8))
    result.add_check("width", batch.width, V.positive_int_divisible(8))
    result.add_check("image_latent", batch.image_latent, V.is_tensor)
    return result</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>VerificationResult</code></dt><dd><p>A VerificationResult containing the verification status.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.stages.flux_stages.PipelineStage.verify_output"><code>fastvideo.pipelines.stages.flux_stages.PipelineStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify the output for the stage.</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>VerificationResult</code></dt><dd><p>A VerificationResult containing the verification status.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.stages.flux_stages.PipelineStage.device"><code>fastvideo.pipelines.stages.flux_stages.PipelineStage.device</code></h3>
<pre class="doc-signature"><code>device: torch.device</code></pre>
<p>Get the device for this stage.</p>
<h3 id="fastvideo.pipelines.stages.flux_stages.PipelineStage.set_logging"><code>fastvideo.pipelines.stages.flux_stages.PipelineStage.set_logging</code></h3>
<pre class="doc-signature"><code>set_logging(enable: bool)</code></pre>
<p>Enable or disable logging for this stage.</p>
<h4>Parameters</h4>
<dl>
<dt><code>enable: bool</code></dt><dd><p>Whether to enable logging.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.stages.flux_stages.PipelineStage.forward"><code>fastvideo.pipelines.stages.flux_stages.PipelineStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>
<p>Forward pass of the stage's processing.</p>
<p>This method should be implemented by subclasses to provide the forward
processing logic for the stage.</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 updated batch information after this stage's processing.</p></dd>
</dl>
<h2 id="fastvideo.pipelines.stages.flux_stages.InputValidationStage"><code>fastvideo.pipelines.stages.flux_stages.InputValidationStage</code></h2>
<pre class="doc-signature"><code>InputValidationStage()</code></pre>
<p>Stage for validating and preparing inputs for diffusion pipelines.</p>
<p>This stage validates that all required inputs are present and properly formatted
before proceeding with the diffusion process.</p>
<h3 id="fastvideo.pipelines.stages.flux_stages.InputValidationStage.forward"><code>fastvideo.pipelines.stages.flux_stages.InputValidationStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>
<p>Validate and prepare inputs.</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 validated batch information.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.stages.flux_stages.InputValidationStage.verify_input"><code>fastvideo.pipelines.stages.flux_stages.InputValidationStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify input validation stage inputs.</p>
<h3 id="fastvideo.pipelines.stages.flux_stages.InputValidationStage.verify_output"><code>fastvideo.pipelines.stages.flux_stages.InputValidationStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify input validation stage outputs.</p>
<h2 id="fastvideo.pipelines.stages.flux_stages.TimestepPreparationStage"><code>fastvideo.pipelines.stages.flux_stages.TimestepPreparationStage</code></h2>
<pre class="doc-signature"><code>TimestepPreparationStage(scheduler)</code></pre>
<p>Stage for preparing timesteps for the diffusion process.</p>
<p>This stage handles the preparation of the timestep sequence that will be used
during the diffusion process.</p>

<h3 id="fastvideo.pipelines.stages.flux_stages.TimestepPreparationStage.forward"><code>fastvideo.pipelines.stages.flux_stages.TimestepPreparationStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>
<p>Prepare timesteps for the diffusion process.</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 prepared timesteps.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.stages.flux_stages.TimestepPreparationStage.verify_input"><code>fastvideo.pipelines.stages.flux_stages.TimestepPreparationStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify timestep preparation stage inputs.</p>
<h3 id="fastvideo.pipelines.stages.flux_stages.TimestepPreparationStage.verify_output"><code>fastvideo.pipelines.stages.flux_stages.TimestepPreparationStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify timestep preparation stage outputs.</p>
<h2 id="fastvideo.pipelines.stages.flux_stages.FluxInputValidationStage"><code>fastvideo.pipelines.stages.flux_stages.FluxInputValidationStage</code></h2>
<pre class="doc-signature"><code>FluxInputValidationStage()</code></pre>
<p>Require height/width divisible by 16 (VAE scale × 2 for FLUX packing).</p>
<details><summary>Source</summary><pre><code>class FluxInputValidationStage(InputValidationStage):
    &quot;&quot;&quot;Require height/width divisible by 16 (VAE scale × 2 for FLUX packing).&quot;&quot;&quot;

    def forward(
        self,
        batch: ForwardBatch,
        fastvideo_args: FastVideoArgs,
    ) -&gt; ForwardBatch:
        if (batch.height is not None and batch.width is not None and (batch.height % 16 != 0 or batch.width % 16 != 0)):
            raise ValueError(&quot;FLUX expects height and width divisible by 16 &quot;
                             f&quot;(VAE latent grid × 2× packing); got &#123;batch.height&#125;×&#123;batch.width&#125;.&quot;)
        return super().forward(batch, fastvideo_args)</code></pre></details>
<h3 id="fastvideo.pipelines.stages.flux_stages.FluxInputValidationStage.forward"><code>fastvideo.pipelines.stages.flux_stages.FluxInputValidationStage.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:
    if (batch.height is not None and batch.width is not None and (batch.height % 16 != 0 or batch.width % 16 != 0)):
        raise ValueError(&quot;FLUX expects height and width divisible by 16 &quot;
                         f&quot;(VAE latent grid × 2× packing); got &#123;batch.height&#125;×&#123;batch.width&#125;.&quot;)
    return super().forward(batch, fastvideo_args)</code></pre></details>
<h2 id="fastvideo.pipelines.stages.flux_stages.FluxConditioningStage"><code>fastvideo.pipelines.stages.flux_stages.FluxConditioningStage</code></h2>
<pre class="doc-signature"><code>FluxConditioningStage()</code></pre>
<p>Build CLIP pooled + T5 sequence + <code>text_ids</code> (and optional negative for true CFG).</p>
<details><summary>Source</summary><pre><code>class FluxConditioningStage(PipelineStage):
    &quot;&quot;&quot;Build CLIP pooled + T5 sequence + ``text_ids`` (and optional negative for true CFG).&quot;&quot;&quot;

    @torch.no_grad()
    def forward(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch:
        if len(batch.prompt_embeds) &lt; 2:
            raise ValueError(&quot;FluxConditioningStage expects 2 prompt_embeds (CLIP pooled, T5 sequence), &quot;
                             f&quot;got &#123;len(batch.prompt_embeds)&#125;&quot;)

        device = get_local_torch_device()
        target_dtype = PRECISION_TO_TYPE&#91;fastvideo_args.pipeline_config.dit_precision&#93;

        pooled = batch.prompt_embeds&#91;0&#93;.to(device=device, dtype=target_dtype)
        enc = batch.prompt_embeds&#91;1&#93;.to(device=device, dtype=target_dtype)
        seq_len = enc.shape&#91;1&#93;
        text_ids = torch.zeros(seq_len, 3, device=device, dtype=torch.long)

        batch.extra&#91;&quot;flux_pooled_projections&quot;&#93; = pooled
        batch.extra&#91;&quot;flux_encoder_hidden_states&quot;&#93; = enc
        batch.extra&#91;&quot;flux_text_ids&quot;&#93; = text_ids

        if batch.do_classifier_free_guidance:
            if not batch.negative_prompt_embeds or len(batch.negative_prompt_embeds) &lt; 2:
                raise ValueError(&quot;True CFG requires two negative_prompt_embeds (CLIP, T5).&quot;)
            neg_pooled = batch.negative_prompt_embeds&#91;0&#93;.to(device=device, dtype=target_dtype)
            neg_enc = batch.negative_prompt_embeds&#91;1&#93;.to(device=device, dtype=target_dtype)
            batch.extra&#91;&quot;flux_negative_pooled_projections&quot;&#93; = neg_pooled
            batch.extra&#91;&quot;flux_negative_encoder_hidden_states&quot;&#93; = neg_enc

        return batch</code></pre></details>
<h3 id="fastvideo.pipelines.stages.flux_stages.FluxConditioningStage.forward"><code>fastvideo.pipelines.stages.flux_stages.FluxConditioningStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>

<details><summary>Source</summary><pre><code>@torch.no_grad()
def forward(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch:
    if len(batch.prompt_embeds) &lt; 2:
        raise ValueError(&quot;FluxConditioningStage expects 2 prompt_embeds (CLIP pooled, T5 sequence), &quot;
                         f&quot;got &#123;len(batch.prompt_embeds)&#125;&quot;)

    device = get_local_torch_device()
    target_dtype = PRECISION_TO_TYPE&#91;fastvideo_args.pipeline_config.dit_precision&#93;

    pooled = batch.prompt_embeds&#91;0&#93;.to(device=device, dtype=target_dtype)
    enc = batch.prompt_embeds&#91;1&#93;.to(device=device, dtype=target_dtype)
    seq_len = enc.shape&#91;1&#93;
    text_ids = torch.zeros(seq_len, 3, device=device, dtype=torch.long)

    batch.extra&#91;&quot;flux_pooled_projections&quot;&#93; = pooled
    batch.extra&#91;&quot;flux_encoder_hidden_states&quot;&#93; = enc
    batch.extra&#91;&quot;flux_text_ids&quot;&#93; = text_ids

    if batch.do_classifier_free_guidance:
        if not batch.negative_prompt_embeds or len(batch.negative_prompt_embeds) &lt; 2:
            raise ValueError(&quot;True CFG requires two negative_prompt_embeds (CLIP, T5).&quot;)
        neg_pooled = batch.negative_prompt_embeds&#91;0&#93;.to(device=device, dtype=target_dtype)
        neg_enc = batch.negative_prompt_embeds&#91;1&#93;.to(device=device, dtype=target_dtype)
        batch.extra&#91;&quot;flux_negative_pooled_projections&quot;&#93; = neg_pooled
        batch.extra&#91;&quot;flux_negative_encoder_hidden_states&quot;&#93; = neg_enc

    return batch</code></pre></details>
<h2 id="fastvideo.pipelines.stages.flux_stages.FluxTimestepPreparationStage"><code>fastvideo.pipelines.stages.flux_stages.FluxTimestepPreparationStage</code></h2>
<pre class="doc-signature"><code>FluxTimestepPreparationStage(scheduler)</code></pre>
<p>Flow Match with resolution-dependent <code>mu</code> from packed image sequence length.</p>
<details><summary>Source</summary><pre><code>class FluxTimestepPreparationStage(TimestepPreparationStage):
    &quot;&quot;&quot;Flow Match with resolution-dependent ``mu`` from packed image sequence length.&quot;&quot;&quot;

    @staticmethod
    def _calculate_mu(
        image_seq_len: int,
        base_seq_len: int = 256,
        max_seq_len: int = 4096,
        base_shift: float = 0.5,
        max_shift: float = 1.15,
    ) -&gt; float:
        m = (max_shift - base_shift) / (max_seq_len - base_seq_len)
        b = base_shift - m * base_seq_len
        return float(image_seq_len) * m + b

    def forward(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch:
        sig = inspect.signature(self.scheduler.set_timesteps)
        if &quot;mu&quot; not in sig.parameters:
            logger.warning(
                &quot;FLUX timestep prep: scheduler %s.set_timesteps does not accept &#x27;mu&#x27;; falling back to the base &quot;
                &quot;timestep schedule. FLUX expects a FlowMatchEulerDiscreteScheduler with resolution-dependent &quot;
                &quot;dynamic shifting — output quality may degrade.&quot;,
                type(self.scheduler).__name__)
            return super().forward(batch, fastvideo_args)

        cfg = getattr(self.scheduler, &quot;config&quot;, None)
        use_dynamic = bool(getattr(cfg, &quot;use_dynamic_shifting&quot;, False)) if cfg is not None else False
        if not use_dynamic:
            logger.warning(
                &quot;FLUX timestep prep: scheduler has use_dynamic_shifting=False; falling back to the base timestep &quot;
                &quot;schedule and skipping the resolution-dependent &#x27;mu&#x27; shift. FLUX requires dynamic shifting for &quot;
                &quot;correct timesteps — output quality may degrade.&quot;)
            return super().forward(batch, fastvideo_args)

        if batch.height is None or batch.width is None:
            raise ValueError(&quot;height/width must be set before FluxTimestepPreparationStage&quot;)

        vae_arch = fastvideo_args.pipeline_config.vae_config.arch_config
        spatial_ratio = int(getattr(vae_arch, &quot;spatial_compression_ratio&quot;, 8))
        h_lat = batch.height // spatial_ratio
        w_lat = batch.width // spatial_ratio
        if h_lat % 2 != 0 or w_lat % 2 != 0:
            raise ValueError(
                f&quot;Latent spatial dims must be even for FLUX packing; got &#123;h_lat&#125;×&#123;w_lat&#125; from &#123;batch.height&#125;×&#123;batch.width&#125;.&quot;
            )
        image_seq_len = (h_lat // 2) * (w_lat // 2)

        base_seq_len = int(getattr(cfg, &quot;base_image_seq_len&quot;, 256))
        max_seq_len = int(getattr(cfg, &quot;max_image_seq_len&quot;, 4096))
        base_shift = float(getattr(cfg, &quot;base_shift&quot;, 0.5))
        max_shift = float(getattr(cfg, &quot;max_shift&quot;, 1.15))

        device = get_local_torch_device()
        mu = self._calculate_mu(
            image_seq_len=image_seq_len,
            base_seq_len=base_seq_len,
            max_seq_len=max_seq_len,
            base_shift=base_shift,
            max_shift=max_shift,
        )
        self.scheduler.set_timesteps(batch.num_inference_steps, device=device, mu=mu)
        batch.timesteps = self.scheduler.timesteps
        return batch</code></pre></details>
<h3 id="fastvideo.pipelines.stages.flux_stages.FluxTimestepPreparationStage.forward"><code>fastvideo.pipelines.stages.flux_stages.FluxTimestepPreparationStage.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:
    sig = inspect.signature(self.scheduler.set_timesteps)
    if &quot;mu&quot; not in sig.parameters:
        logger.warning(
            &quot;FLUX timestep prep: scheduler %s.set_timesteps does not accept &#x27;mu&#x27;; falling back to the base &quot;
            &quot;timestep schedule. FLUX expects a FlowMatchEulerDiscreteScheduler with resolution-dependent &quot;
            &quot;dynamic shifting — output quality may degrade.&quot;,
            type(self.scheduler).__name__)
        return super().forward(batch, fastvideo_args)

    cfg = getattr(self.scheduler, &quot;config&quot;, None)
    use_dynamic = bool(getattr(cfg, &quot;use_dynamic_shifting&quot;, False)) if cfg is not None else False
    if not use_dynamic:
        logger.warning(
            &quot;FLUX timestep prep: scheduler has use_dynamic_shifting=False; falling back to the base timestep &quot;
            &quot;schedule and skipping the resolution-dependent &#x27;mu&#x27; shift. FLUX requires dynamic shifting for &quot;
            &quot;correct timesteps — output quality may degrade.&quot;)
        return super().forward(batch, fastvideo_args)

    if batch.height is None or batch.width is None:
        raise ValueError(&quot;height/width must be set before FluxTimestepPreparationStage&quot;)

    vae_arch = fastvideo_args.pipeline_config.vae_config.arch_config
    spatial_ratio = int(getattr(vae_arch, &quot;spatial_compression_ratio&quot;, 8))
    h_lat = batch.height // spatial_ratio
    w_lat = batch.width // spatial_ratio
    if h_lat % 2 != 0 or w_lat % 2 != 0:
        raise ValueError(
            f&quot;Latent spatial dims must be even for FLUX packing; got &#123;h_lat&#125;×&#123;w_lat&#125; from &#123;batch.height&#125;×&#123;batch.width&#125;.&quot;
        )
    image_seq_len = (h_lat // 2) * (w_lat // 2)

    base_seq_len = int(getattr(cfg, &quot;base_image_seq_len&quot;, 256))
    max_seq_len = int(getattr(cfg, &quot;max_image_seq_len&quot;, 4096))
    base_shift = float(getattr(cfg, &quot;base_shift&quot;, 0.5))
    max_shift = float(getattr(cfg, &quot;max_shift&quot;, 1.15))

    device = get_local_torch_device()
    mu = self._calculate_mu(
        image_seq_len=image_seq_len,
        base_seq_len=base_seq_len,
        max_seq_len=max_seq_len,
        base_shift=base_shift,
        max_shift=max_shift,
    )
    self.scheduler.set_timesteps(batch.num_inference_steps, device=device, mu=mu)
    batch.timesteps = self.scheduler.timesteps
    return batch</code></pre></details>
<h2 id="fastvideo.pipelines.stages.flux_stages.FluxLatentPreparationStage"><code>fastvideo.pipelines.stages.flux_stages.FluxLatentPreparationStage</code></h2>
<pre class="doc-signature"><code>FluxLatentPreparationStage(scheduler)</code></pre>


<details><summary>Source</summary><pre><code>class FluxLatentPreparationStage(PipelineStage):

    def __init__(self, scheduler) -&gt; None:
        super().__init__()
        self.scheduler = scheduler

    @torch.no_grad()
    def forward(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch:
        if batch.height is None or batch.width is None:
            raise ValueError(&quot;height/width required for FluxLatentPreparationStage&quot;)

        if isinstance(batch.prompt, list):
            batch_size = len(batch.prompt)
        elif batch.prompt is not None:
            batch_size = 1
        else:
            if not batch.prompt_embeds:
                raise ValueError(&quot;prompt or prompt_embeds must be provided&quot;)
            batch_size = batch.prompt_embeds&#91;0&#93;.shape&#91;0&#93;

        batch_size *= batch.num_videos_per_prompt

        if isinstance(batch.generator, list) and len(batch.generator) != batch_size:
            raise ValueError(f&quot;generator list length &#123;len(batch.generator)&#125; does not match batch_size &#123;batch_size&#125;&quot;)

        arch = fastvideo_args.pipeline_config.dit_config.arch_config
        in_channels = int(getattr(arch, &quot;in_channels&quot;, 64))
        num_channels_latents = in_channels // 4

        vae_arch = fastvideo_args.pipeline_config.vae_config.arch_config
        spatial_ratio = int(getattr(vae_arch, &quot;spatial_compression_ratio&quot;, 8))

        h_lat = batch.height // spatial_ratio
        w_lat = batch.width // spatial_ratio

        dtype = PRECISION_TO_TYPE&#91;fastvideo_args.pipeline_config.dit_precision&#93;
        device = get_local_torch_device()

        shape = (batch_size, num_channels_latents, h_lat, w_lat)
        latents = batch.latents
        if latents is None:
            latents = randn_tensor(shape, generator=batch.generator, device=device, dtype=dtype)
            if hasattr(self.scheduler, &quot;init_noise_sigma&quot;):
                latents = latents * self.scheduler.init_noise_sigma
        else:
            latents = latents.to(device=device, dtype=dtype)
            if latents.shape != shape:
                raise ValueError(f&quot;Expected latents shape &#123;shape&#125;, got &#123;tuple(latents.shape)&#125;&quot;)
            if hasattr(self.scheduler, &quot;init_noise_sigma&quot;):
                latents = latents * self.scheduler.init_noise_sigma

        packed = _pack_latents(latents, batch_size, num_channels_latents, h_lat, w_lat)

        patch_h, patch_w = h_lat // 2, w_lat // 2
        img_ids = _prepare_latent_image_ids(patch_h, patch_w, device, dtype=torch.long)

        batch.latents = packed
        batch.raw_latent_shape = shape
        batch.extra&#91;&quot;flux_h_lat&quot;&#93; = h_lat
        batch.extra&#91;&quot;flux_w_lat&quot;&#93; = w_lat
        batch.extra&#91;&quot;flux_num_channels_latents&quot;&#93; = num_channels_latents
        batch.extra&#91;&quot;flux_latent_image_ids&quot;&#93; = img_ids

        return batch</code></pre></details>
<h3 id="fastvideo.pipelines.stages.flux_stages.FluxLatentPreparationStage.forward"><code>fastvideo.pipelines.stages.flux_stages.FluxLatentPreparationStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>

<details><summary>Source</summary><pre><code>@torch.no_grad()
def forward(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch:
    if batch.height is None or batch.width is None:
        raise ValueError(&quot;height/width required for FluxLatentPreparationStage&quot;)

    if isinstance(batch.prompt, list):
        batch_size = len(batch.prompt)
    elif batch.prompt is not None:
        batch_size = 1
    else:
        if not batch.prompt_embeds:
            raise ValueError(&quot;prompt or prompt_embeds must be provided&quot;)
        batch_size = batch.prompt_embeds&#91;0&#93;.shape&#91;0&#93;

    batch_size *= batch.num_videos_per_prompt

    if isinstance(batch.generator, list) and len(batch.generator) != batch_size:
        raise ValueError(f&quot;generator list length &#123;len(batch.generator)&#125; does not match batch_size &#123;batch_size&#125;&quot;)

    arch = fastvideo_args.pipeline_config.dit_config.arch_config
    in_channels = int(getattr(arch, &quot;in_channels&quot;, 64))
    num_channels_latents = in_channels // 4

    vae_arch = fastvideo_args.pipeline_config.vae_config.arch_config
    spatial_ratio = int(getattr(vae_arch, &quot;spatial_compression_ratio&quot;, 8))

    h_lat = batch.height // spatial_ratio
    w_lat = batch.width // spatial_ratio

    dtype = PRECISION_TO_TYPE&#91;fastvideo_args.pipeline_config.dit_precision&#93;
    device = get_local_torch_device()

    shape = (batch_size, num_channels_latents, h_lat, w_lat)
    latents = batch.latents
    if latents is None:
        latents = randn_tensor(shape, generator=batch.generator, device=device, dtype=dtype)
        if hasattr(self.scheduler, &quot;init_noise_sigma&quot;):
            latents = latents * self.scheduler.init_noise_sigma
    else:
        latents = latents.to(device=device, dtype=dtype)
        if latents.shape != shape:
            raise ValueError(f&quot;Expected latents shape &#123;shape&#125;, got &#123;tuple(latents.shape)&#125;&quot;)
        if hasattr(self.scheduler, &quot;init_noise_sigma&quot;):
            latents = latents * self.scheduler.init_noise_sigma

    packed = _pack_latents(latents, batch_size, num_channels_latents, h_lat, w_lat)

    patch_h, patch_w = h_lat // 2, w_lat // 2
    img_ids = _prepare_latent_image_ids(patch_h, patch_w, device, dtype=torch.long)

    batch.latents = packed
    batch.raw_latent_shape = shape
    batch.extra&#91;&quot;flux_h_lat&quot;&#93; = h_lat
    batch.extra&#91;&quot;flux_w_lat&quot;&#93; = w_lat
    batch.extra&#91;&quot;flux_num_channels_latents&quot;&#93; = num_channels_latents
    batch.extra&#91;&quot;flux_latent_image_ids&quot;&#93; = img_ids

    return batch</code></pre></details>
<h2 id="fastvideo.pipelines.stages.flux_stages.FluxDenoisingStage"><code>fastvideo.pipelines.stages.flux_stages.FluxDenoisingStage</code></h2>
<pre class="doc-signature"><code>FluxDenoisingStage(transformer, scheduler)</code></pre>


<details><summary>Source</summary><pre><code>class FluxDenoisingStage(PipelineStage):

    def __init__(self, transformer, scheduler) -&gt; None:
        super().__init__()
        self.transformer = transformer
        self.scheduler = scheduler

    @staticmethod
    def _step_kwargs(scheduler_step, batch: ForwardBatch) -&gt; dict&#91;str, Any&#93;:
        kwargs: dict&#91;str, Any&#93; = &#123;&#125;
        sig = inspect.signature(scheduler_step)
        if &quot;generator&quot; in sig.parameters:
            gen = batch.generator&#91;0&#93; if isinstance(batch.generator, list) else batch.generator
            kwargs&#91;&quot;generator&quot;&#93; = gen
        return kwargs

    @torch.no_grad()
    def forward(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch:
        if batch.timesteps is None:
            raise ValueError(&quot;timesteps must be set before FluxDenoisingStage&quot;)
        if batch.latents is None:
            raise ValueError(&quot;latents must be set before FluxDenoisingStage&quot;)

        packed = batch.latents
        timesteps = batch.timesteps

        pooled = batch.extra&#91;&quot;flux_pooled_projections&quot;&#93;
        enc = batch.extra&#91;&quot;flux_encoder_hidden_states&quot;&#93;
        txt_ids = batch.extra&#91;&quot;flux_text_ids&quot;&#93;
        img_ids = batch.extra&#91;&quot;flux_latent_image_ids&quot;&#93;

        neg_pooled = batch.extra.get(&quot;flux_negative_pooled_projections&quot;)
        neg_enc = batch.extra.get(&quot;flux_negative_encoder_hidden_states&quot;)

        true_cfg_scale = float(batch.true_cfg_scale)
        use_true_cfg = batch.do_classifier_free_guidance and true_cfg_scale &gt; 1.0

        # Prefer the loaded transformer&#x27;s arch (HF ``guidance_embeds``), not static pipeline defaults.
        tr_arch = self.transformer.fastvideo_config.arch_config
        guidance_embeds = bool(getattr(tr_arch, &quot;guidance_embeds&quot;, False))

        device = get_local_torch_device()
        target_dtype = PRECISION_TO_TYPE&#91;fastvideo_args.pipeline_config.dit_precision&#93;
        autocast_enabled = (target_dtype != torch.float32) and not fastvideo_args.disable_autocast

        bs = packed.shape&#91;0&#93;
        if guidance_embeds:
            guidance = torch.full((bs, ), float(batch.guidance_scale), device=device, dtype=torch.float32)
        else:
            guidance = None

        step_extras = self._step_kwargs(self.scheduler.step, batch)

        for t in timesteps:
            # Stop if interrupted
            if getattr(self, &quot;interrupt&quot;, False):
                break
            t_scalar = t
            if not isinstance(t_scalar, torch.Tensor):
                t_scalar = torch.tensor(&#91;t_scalar&#93;, device=device, dtype=torch.float32)
            t_scalar = t_scalar.to(device=device, dtype=torch.float32)

            timestep_model = t_scalar.expand(bs).float() / 1000.0
            timestep_model = timestep_model.to(dtype=target_dtype)

            ts_ctx = int(t_scalar.reshape(-1)&#91;0&#93;.item())
            with (
                    torch.autocast(
                        device_type=&quot;cuda&quot;,
                        dtype=target_dtype,
                        enabled=autocast_enabled and device.type == &quot;cuda&quot;,
                    ),
                    set_forward_context(
                        current_timestep=ts_ctx,
                        attn_metadata=None,
                        forward_batch=batch,
                    ),
            ):
                if use_true_cfg:
                    assert neg_enc is not None and neg_pooled is not None
                    n_neg = self.transformer(
                        hidden_states=packed,
                        encoder_hidden_states=neg_enc,
                        pooled_projections=neg_pooled,
                        timestep=timestep_model,
                        guidance=guidance,
                        txt_ids=txt_ids,
                        img_ids=img_ids,
                        return_dict=False,
                    )&#91;0&#93;
                    n_pos = self.transformer(
                        hidden_states=packed,
                        encoder_hidden_states=enc,
                        pooled_projections=pooled,
                        timestep=timestep_model,
                        guidance=guidance,
                        txt_ids=txt_ids,
                        img_ids=img_ids,
                        return_dict=False,
                    )&#91;0&#93;
                    noise_pred = n_neg + true_cfg_scale * (n_pos - n_neg)
                else:
                    noise_pred = self.transformer(
                        hidden_states=packed,
                        encoder_hidden_states=enc,
                        pooled_projections=pooled,
                        timestep=timestep_model,
                        guidance=guidance,
                        txt_ids=txt_ids,
                        img_ids=img_ids,
                        return_dict=False,
                    )&#91;0&#93;

            packed = self.scheduler.step(
                noise_pred,
                t_scalar,
                packed,
                return_dict=False,
                **step_extras,
            )&#91;0&#93;

        batch.latents = packed
        return batch</code></pre></details>
<h3 id="fastvideo.pipelines.stages.flux_stages.FluxDenoisingStage.forward"><code>fastvideo.pipelines.stages.flux_stages.FluxDenoisingStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>

<details><summary>Source</summary><pre><code>@torch.no_grad()
def forward(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch:
    if batch.timesteps is None:
        raise ValueError(&quot;timesteps must be set before FluxDenoisingStage&quot;)
    if batch.latents is None:
        raise ValueError(&quot;latents must be set before FluxDenoisingStage&quot;)

    packed = batch.latents
    timesteps = batch.timesteps

    pooled = batch.extra&#91;&quot;flux_pooled_projections&quot;&#93;
    enc = batch.extra&#91;&quot;flux_encoder_hidden_states&quot;&#93;
    txt_ids = batch.extra&#91;&quot;flux_text_ids&quot;&#93;
    img_ids = batch.extra&#91;&quot;flux_latent_image_ids&quot;&#93;

    neg_pooled = batch.extra.get(&quot;flux_negative_pooled_projections&quot;)
    neg_enc = batch.extra.get(&quot;flux_negative_encoder_hidden_states&quot;)

    true_cfg_scale = float(batch.true_cfg_scale)
    use_true_cfg = batch.do_classifier_free_guidance and true_cfg_scale &gt; 1.0

    # Prefer the loaded transformer&#x27;s arch (HF ``guidance_embeds``), not static pipeline defaults.
    tr_arch = self.transformer.fastvideo_config.arch_config
    guidance_embeds = bool(getattr(tr_arch, &quot;guidance_embeds&quot;, False))

    device = get_local_torch_device()
    target_dtype = PRECISION_TO_TYPE&#91;fastvideo_args.pipeline_config.dit_precision&#93;
    autocast_enabled = (target_dtype != torch.float32) and not fastvideo_args.disable_autocast

    bs = packed.shape&#91;0&#93;
    if guidance_embeds:
        guidance = torch.full((bs, ), float(batch.guidance_scale), device=device, dtype=torch.float32)
    else:
        guidance = None

    step_extras = self._step_kwargs(self.scheduler.step, batch)

    for t in timesteps:
        # Stop if interrupted
        if getattr(self, &quot;interrupt&quot;, False):
            break
        t_scalar = t
        if not isinstance(t_scalar, torch.Tensor):
            t_scalar = torch.tensor(&#91;t_scalar&#93;, device=device, dtype=torch.float32)
        t_scalar = t_scalar.to(device=device, dtype=torch.float32)

        timestep_model = t_scalar.expand(bs).float() / 1000.0
        timestep_model = timestep_model.to(dtype=target_dtype)

        ts_ctx = int(t_scalar.reshape(-1)&#91;0&#93;.item())
        with (
                torch.autocast(
                    device_type=&quot;cuda&quot;,
                    dtype=target_dtype,
                    enabled=autocast_enabled and device.type == &quot;cuda&quot;,
                ),
                set_forward_context(
                    current_timestep=ts_ctx,
                    attn_metadata=None,
                    forward_batch=batch,
                ),
        ):
            if use_true_cfg:
                assert neg_enc is not None and neg_pooled is not None
                n_neg = self.transformer(
                    hidden_states=packed,
                    encoder_hidden_states=neg_enc,
                    pooled_projections=neg_pooled,
                    timestep=timestep_model,
                    guidance=guidance,
                    txt_ids=txt_ids,
                    img_ids=img_ids,
                    return_dict=False,
                )&#91;0&#93;
                n_pos = self.transformer(
                    hidden_states=packed,
                    encoder_hidden_states=enc,
                    pooled_projections=pooled,
                    timestep=timestep_model,
                    guidance=guidance,
                    txt_ids=txt_ids,
                    img_ids=img_ids,
                    return_dict=False,
                )&#91;0&#93;
                noise_pred = n_neg + true_cfg_scale * (n_pos - n_neg)
            else:
                noise_pred = self.transformer(
                    hidden_states=packed,
                    encoder_hidden_states=enc,
                    pooled_projections=pooled,
                    timestep=timestep_model,
                    guidance=guidance,
                    txt_ids=txt_ids,
                    img_ids=img_ids,
                    return_dict=False,
                )&#91;0&#93;

        packed = self.scheduler.step(
            noise_pred,
            t_scalar,
            packed,
            return_dict=False,
            **step_extras,
        )&#91;0&#93;

    batch.latents = packed
    return batch</code></pre></details>
<h2 id="fastvideo.pipelines.stages.flux_stages.FluxDecodingStage"><code>fastvideo.pipelines.stages.flux_stages.FluxDecodingStage</code></h2>
<pre class="doc-signature"><code>FluxDecodingStage(vae)</code></pre>
<p>Unpack latents, apply VAE scaling/shift, decode to pixels (5D output <code>B×3×1×H×W</code>).</p>

<details><summary>Source</summary><pre><code>class FluxDecodingStage(PipelineStage):
    &quot;&quot;&quot;Unpack latents, apply VAE scaling/shift, decode to pixels (5D output ``B×3×1×H×W``).&quot;&quot;&quot;

    def __init__(self, vae) -&gt; None:
        super().__init__()
        self.vae = vae

    @staticmethod
    def _denormalize_latents(latents: torch.Tensor, vae: Any) -&gt; torch.Tensor:
        cfg = getattr(vae, &quot;config&quot;, None)
        sf = getattr(cfg, &quot;scaling_factor&quot;, None) if cfg is not None else None
        sh = getattr(cfg, &quot;shift_factor&quot;, None) if cfg is not None else None
        if sf is None and hasattr(vae, &quot;scaling_factor&quot;):
            sf = vae.scaling_factor
        if sh is None and hasattr(vae, &quot;shift_factor&quot;):
            sh = vae.shift_factor
        if sf is not None:
            latents = latents / (sf.to(latents.device, latents.dtype) if isinstance(sf, torch.Tensor) else sf)
            if sh is not None:
                latents = latents + (sh.to(latents.device, latents.dtype) if isinstance(sh, torch.Tensor) else sh)
        return latents

    @torch.no_grad()
    def forward(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch:
        if not fastvideo_args.is_output_rank:
            # Flux decoding has no collectives. Avoid duplicating the VAE
            # forward and device-to-host pixel copy on SPMD worker ranks whose
            # result is discarded by the executor.
            batch.output = torch.empty((0, 3, 0, 0, 0), device=&quot;cpu&quot;, dtype=torch.float32)
            return batch

        packed = batch.latents
        if packed is None:
            raise ValueError(&quot;latents must be set before FluxDecodingStage&quot;)

        h_lat = int(batch.extra&#91;&quot;flux_h_lat&quot;&#93;)
        w_lat = int(batch.extra&#91;&quot;flux_w_lat&quot;&#93;)
        num_ch = int(batch.extra&#91;&quot;flux_num_channels_latents&quot;&#93;)
        raw_shape = batch.raw_latent_shape
        if raw_shape is None:
            raise ValueError(&quot;raw_latent_shape missing; FluxLatentPreparationStage must run first.&quot;)
        batch_size = int(raw_shape&#91;0&#93;)

        infer_device = get_local_torch_device()
        packed = packed.to(infer_device)

        latents_4d = _unpack_latents(packed, batch_size, num_ch, h_lat, w_lat)
        latents_4d = self._denormalize_latents(latents_4d, self.vae)

        vae_device = next(self.vae.parameters()).device
        latents_4d = latents_4d.to(device=vae_device)

        vae_dtype = PRECISION_TO_TYPE&#91;fastvideo_args.pipeline_config.vae_precision&#93;
        autocast_enabled = (vae_dtype != torch.float32) and not fastvideo_args.disable_autocast
        use_cuda_autocast = autocast_enabled and vae_device.type == &quot;cuda&quot;

        with torch.autocast(
                device_type=&quot;cuda&quot;,
                dtype=vae_dtype,
                enabled=use_cuda_autocast,
        ):
            if not autocast_enabled:
                latents_4d = latents_4d.to(dtype=vae_dtype)
            dec = self.vae.decode(latents_4d)
            image = dec.sample if hasattr(dec, &quot;sample&quot;) else dec&#91;0&#93;

        image = (image / 2 + 0.5).clamp(0, 1)
        batch.output = image.unsqueeze(2).detach().float().cpu()
        return batch</code></pre></details>
<h3 id="fastvideo.pipelines.stages.flux_stages.FluxDecodingStage.forward"><code>fastvideo.pipelines.stages.flux_stages.FluxDecodingStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>

<details><summary>Source</summary><pre><code>@torch.no_grad()
def forward(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch:
    if not fastvideo_args.is_output_rank:
        # Flux decoding has no collectives. Avoid duplicating the VAE
        # forward and device-to-host pixel copy on SPMD worker ranks whose
        # result is discarded by the executor.
        batch.output = torch.empty((0, 3, 0, 0, 0), device=&quot;cpu&quot;, dtype=torch.float32)
        return batch

    packed = batch.latents
    if packed is None:
        raise ValueError(&quot;latents must be set before FluxDecodingStage&quot;)

    h_lat = int(batch.extra&#91;&quot;flux_h_lat&quot;&#93;)
    w_lat = int(batch.extra&#91;&quot;flux_w_lat&quot;&#93;)
    num_ch = int(batch.extra&#91;&quot;flux_num_channels_latents&quot;&#93;)
    raw_shape = batch.raw_latent_shape
    if raw_shape is None:
        raise ValueError(&quot;raw_latent_shape missing; FluxLatentPreparationStage must run first.&quot;)
    batch_size = int(raw_shape&#91;0&#93;)

    infer_device = get_local_torch_device()
    packed = packed.to(infer_device)

    latents_4d = _unpack_latents(packed, batch_size, num_ch, h_lat, w_lat)
    latents_4d = self._denormalize_latents(latents_4d, self.vae)

    vae_device = next(self.vae.parameters()).device
    latents_4d = latents_4d.to(device=vae_device)

    vae_dtype = PRECISION_TO_TYPE&#91;fastvideo_args.pipeline_config.vae_precision&#93;
    autocast_enabled = (vae_dtype != torch.float32) and not fastvideo_args.disable_autocast
    use_cuda_autocast = autocast_enabled and vae_device.type == &quot;cuda&quot;

    with torch.autocast(
            device_type=&quot;cuda&quot;,
            dtype=vae_dtype,
            enabled=use_cuda_autocast,
    ):
        if not autocast_enabled:
            latents_4d = latents_4d.to(dtype=vae_dtype)
        dec = self.vae.decode(latents_4d)
        image = dec.sample if hasattr(dec, &quot;sample&quot;) else dec&#91;0&#93;

    image = (image / 2 + 0.5).clamp(0, 1)
    batch.output = image.unsqueeze(2).detach().float().cpu()
    return batch</code></pre></details>
</div>
