---
title: magi_human_pipeline
---

<div class="python-reference">
<a id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline-classes"></a>
<a id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline-functions"></a>
<a id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanPipeline-functions"></a>
<a id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline"></a>
<p>MagiHuman base text-to-AV pipeline.</p>
<p>Top-level composition for the daVinci-MagiHuman base model. Wires:</p>
<pre><code>InputValidationStage -&gt; TextEncodingStage (T5-Gemma)
    -&gt; MagiHumanLatentPreparationStage
    -&gt; MagiHumanDenoisingStage
    -&gt; DecodingStage (Wan 2.2 TI2V-5B VAE decode for video)
    -&gt; MagiHumanAudioDecodingStage (Stable Audio Open 1.0 VAE decode)
</code></pre>
<p>The base checkpoint is a joint audio-visual generator; both the video
and audio paths run in the denoising loop and both are decoded.</p>
<p><code>load_modules</code> is overridden so the four cross-variant shared components
(text_encoder, tokenizer, audio_vae, video vae) lazy-load from their
canonical upstream HF repos at first build time instead of being
bundled inside every converted MagiHuman variant. This keeps each
variant's converted repo at ~5-30 GB (transformer + scheduler +
model_index.json) instead of ~30-55 GB, and lets all variants share
the same ~25 GB of cached upstream weights.</p>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.T5GemmaEncoderConfig"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.T5GemmaEncoderConfig</code></h2>
<pre class="doc-signature"><code>T5GemmaEncoderConfig(arch_config: TextEncoderArchConfig = T5GemmaEncoderArchConfig(), prefix: str = &#x27;t5gemma&#x27;, quant_config: QuantizationConfig | None = None, lora_config: Any | None = None, is_chat_model: bool = False, treat_empty_as_dot: bool = False, *, _resolved_attention_backend: AttentionBackendEnum | None = None, chat_template_enable_thinking: bool = False)</code></pre>


<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.OobleckVAEConfig"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.OobleckVAEConfig</code></h2>
<pre class="doc-signature"><code>OobleckVAEConfig(arch_config: VAEArchConfig = OobleckVAEArchConfig(), load_encoder: bool = True, load_decoder: bool = True, tile_sample_min_height: int = 256, tile_sample_min_width: int = 256, tile_sample_min_num_frames: int = 16, tile_sample_stride_height: int = 192, tile_sample_stride_width: int = 192, tile_sample_stride_num_frames: int = 12, blend_num_frames: int = 0, use_tiling: bool = False, use_temporal_tiling: bool = False, use_parallel_tiling: bool = False, use_temporal_scaling_frames: bool = True, pretrained_path: str = &#x27;stabilityai/stable-audio-open-1.0&#x27;, pretrained_subfolder: str = &#x27;vae&#x27;, pretrained_dtype: str = &#x27;float16&#x27;, *, _resolved_attention_backend: AttentionBackendEnum | None = None)</code></pre>
<p>FastVideo VAE config wrapping the Oobleck arch.</p>
<p>Audio VAEs don't use the temporal/spatial tiling defaults that the
base VAEConfig is shaped for (those exist for video VAEs); they are
retained but irrelevant for audio.</p>

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


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

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

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

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FastVideoArgs.check_fastvideo_args"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FastVideoArgs.check_fastvideo_args</code></h3>
<pre class="doc-signature"><code>check_fastvideo_args() -&gt; None</code></pre>
<p>Validate inference arguments for consistency</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FastVideoArgs.finalize_device_offload_policy"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FastVideoArgs.finalize_device_offload_policy</code></h3>
<pre class="doc-signature"><code>finalize_device_offload_policy(device_id: int = 0) -&gt; bool</code></pre>
<p>Apply device-local memory policy, then resolve incompatible modes.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FastVideoArgs.disable_offload_on_unified_memory"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FastVideoArgs.disable_offload_on_unified_memory</code></h3>
<pre class="doc-signature"><code>disable_offload_on_unified_memory(device_id: int = 0, *, offload_flag: str | None = None) -&gt; bool</code></pre>
<p>Disable host offload after a worker has selected its device.</p>
<p>CUDA's unified-memory probe reads runtime device properties and may
initialize a CUDA context. Callers must therefore use this only inside
a device-owning process, after selecting and binding <code>device_id</code>.
Returning the classification lets direct component-loader callers
apply the same policy to explicit per-call overrides. When
<code>offload_flag</code> is given, the return value says whether this policy
covers that component role.</p>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.init_logger"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.init_logger</code></h2>
<pre class="doc-signature"><code>init_logger(name: str) -&gt; _FastvideoLogger</code></pre>
<p>The main purpose of this function is to ensure that loggers are
retrieved in such a way that we can be sure the root fastvideo logger has
already been configured.</p>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.T5GemmaEncoderModel"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.T5GemmaEncoderModel</code></h2>
<pre class="doc-signature"><code>T5GemmaEncoderModel(config: TextEncoderConfig)</code></pre>
<p>Thin wrapper over HuggingFace's <code>T5GemmaEncoderModel</code>.</p>
<p>On first <code>forward</code>, the wrapper lazily instantiates the upstream encoder
from <code>t5gemma_model_path</code> (defaulting to <code>google/t5gemma-9b-9b-ul2</code>).
Afterwards, forward returns a <code>BaseEncoderOutput</code> with
<code>last_hidden_state = [B, L, 3584]</code> matching MagiHuman's
<code>context.half()</code> output.</p>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.T5GemmaEncoderModel.named_parameters"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.T5GemmaEncoderModel.named_parameters</code></h3>
<pre class="doc-signature"><code>named_parameters(prefix: str = &#x27;&#x27;, recurse: bool = True)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.T5GemmaEncoderModel.forward"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.T5GemmaEncoderModel.forward</code></h3>
<pre class="doc-signature"><code>forward(input_ids: torch.Tensor | None = None, position_ids: torch.Tensor | None = None, attention_mask: torch.Tensor | None = None, inputs_embeds: torch.Tensor | None = None, output_hidden_states: bool | None = None, **kwargs) -&gt; BaseEncoderOutput</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.T5GemmaEncoderModel.load_weights"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.T5GemmaEncoderModel.load_weights</code></h3>
<pre class="doc-signature"><code>load_weights(weights: Iterable&#91;tuple&#91;str, torch.Tensor&#93;&#93;) -&gt; set&#91;str&#93;</code></pre>

<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.SAAudioVAEModel"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.SAAudioVAEModel</code></h2>
<pre class="doc-signature"><code>SAAudioVAEModel(config: OobleckVAEConfig)</code></pre>
<p>Pipeline-glue lazy loader around <code>OobleckVAE</code>.</p>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.SAAudioVAEModel.named_parameters"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.SAAudioVAEModel.named_parameters</code></h3>
<pre class="doc-signature"><code>named_parameters(prefix: str = &#x27;&#x27;, recurse: bool = True)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.SAAudioVAEModel.decode"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.SAAudioVAEModel.decode</code></h3>
<pre class="doc-signature"><code>decode(latent: torch.Tensor) -&gt; torch.Tensor</code></pre>
<p>Decode an audio latent (<code>[B, C_latent, L]</code>) -&gt; waveform
(<code>[B, audio_channels, samples]</code>).</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.SAAudioVAEModel.encode"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.SAAudioVAEModel.encode</code></h3>
<pre class="doc-signature"><code>encode(waveform: torch.Tensor, sample_posterior: bool = False) -&gt; torch.Tensor</code></pre>
<p>Encode <code>[B, C_audio, samples]</code> -&gt; latent <code>[B, C_latent, L]</code>.</p>
<p><code>sample_posterior=False</code> (default): deterministic mean.
<code>sample_posterior=True</code>: stochastic sample (<code>mean + softplus(scale) * randn</code>).</p>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler</code></h2>
<pre class="doc-signature"><code>FlowUniPCMultistepScheduler(num_train_timesteps: int = 1000, solver_order: int = 2, prediction_type: str = &#x27;flow_prediction&#x27;, shift: float | None = 1.0, use_dynamic_shifting = False, thresholding: bool = False, dynamic_thresholding_ratio: float = 0.995, sample_max_value: float = 1.0, predict_x0: bool = True, solver_type: str = &#x27;bh2&#x27;, lower_order_final: bool = True, disable_corrector: tuple = (), solver_p: SchedulerMixin = None, timestep_spacing: str = &#x27;linspace&#x27;, steps_offset: int = 0, final_sigmas_type: str | None = &#x27;zero&#x27;, **kwargs)</code></pre>
<p><code>UniPCMultistepScheduler</code> is a training-free framework designed for the fast sampling of diffusion models.</p>
<p>This model inherits from [<code>SchedulerMixin</code>] and [<code>ConfigMixin</code>]. Check the superclass documentation for the generic
methods the library implements for all schedulers such as loading and saving.</p>
<h3>Parameters</h3>
<dl>
<dt><code>num_train_timesteps: `int`, defaults to 1000</code></dt><dd><p>The number of diffusion steps to train the model.</p></dd>
<dt><code>solver_order: `int`, default `2`</code></dt><dd><p>The UniPC order which can be any positive integer. The effective order of accuracy is <code>solver_order + 1</code>
due to the UniC. It is recommended to use <code>solver_order=2</code> for guided sampling, and <code>solver_order=3</code> for
unconditional sampling.</p></dd>
<dt><code>prediction_type: `str`, defaults to &quot;flow_prediction&quot;</code></dt><dd><p>Prediction type of the scheduler function; must be <code>flow_prediction</code> for this scheduler, which predicts
the flow of the diffusion process.</p></dd>
<dt><code>thresholding: `bool`, defaults to `False`</code></dt><dd><p>Whether to use the "dynamic thresholding" method. This is unsuitable for latent-space diffusion models such
as Stable Diffusion.</p></dd>
<dt><code>dynamic_thresholding_ratio: `float`, defaults to 0.995</code></dt><dd><p>The ratio for the dynamic thresholding method. Valid only when <code>thresholding=True</code>.</p></dd>
<dt><code>sample_max_value: `float`, defaults to 1.0</code></dt><dd><p>The threshold value for dynamic thresholding. Valid only when <code>thresholding=True</code> and <code>predict_x0=True</code>.</p></dd>
<dt><code>predict_x0: `bool`, defaults to `True`</code></dt><dd><p>Whether to use the updating algorithm on the predicted x0.</p></dd>
<dt><code>solver_type: `str`, default `bh2`</code></dt><dd><p>Solver type for UniPC. It is recommended to use <code>bh1</code> for unconditional sampling when steps &lt; 10, and <code>bh2</code>
otherwise.</p></dd>
<dt><code>lower_order_final: `bool`, default `True`</code></dt><dd><p>Whether to use lower-order solvers in the final steps. Only valid for &lt; 15 inference steps. This can
stabilize the sampling of DPMSolver for steps &lt; 15, especially for steps &lt;= 10.</p></dd>
<dt><code>disable_corrector: `list`, default `[]`</code></dt><dd><p>Decides which step to disable the corrector to mitigate the misalignment between <code>epsilon_theta(x_t, c)</code>
and <code>epsilon_theta(x_t^c, c)</code> which can influence convergence for a large guidance scale. Corrector is
usually disabled during the first few steps.</p></dd>
<dt><code>solver_p: `SchedulerMixin`, default `None`</code></dt><dd><p>Any other scheduler that if specified, the algorithm becomes <code>solver_p + UniC</code>.</p></dd>
<dt><code>use_karras_sigmas: `bool`, *optional*, defaults to `False`</code></dt><dd><p>Whether to use Karras sigmas for step sizes in the noise schedule during the sampling process. If <code>True</code>,
the sigmas are determined according to a sequence of noise levels &#123;σi&#125;.</p></dd>
<dt><code>use_exponential_sigmas: `bool`, *optional*, defaults to `False`</code></dt><dd><p>Whether to use exponential sigmas for step sizes in the noise schedule during the sampling process.</p></dd>
<dt><code>timestep_spacing: `str`, defaults to `&quot;linspace&quot;`</code></dt><dd><p>The way the timesteps should be scaled. Refer to Table 2 of the <a href="https://huggingface.co/papers/2305.08891">Common Diffusion Noise Schedules and
Sample Steps are Flawed</a> for more information.</p></dd>
<dt><code>steps_offset: `int`, defaults to 0</code></dt><dd><p>An offset added to the inference steps, as required by some model families.</p></dd>
<dt><code>final_sigmas_type: `str`, defaults to `&quot;zero&quot;`</code></dt><dd><p>The final <code>sigma</code> value for the noise schedule during the sampling process. If <code>"sigma_min"</code>, the final
sigma is the same as the last sigma in the training schedule. If <code>zero</code>, the final sigma is set to 0.</p></dd>
</dl>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.step_index"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.step_index</code></h3>
<pre class="doc-signature"><code>step_index</code></pre>
<p>The index counter for current timestep. It will increase 1 after each scheduler step.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.begin_index"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.begin_index</code></h3>
<pre class="doc-signature"><code>begin_index</code></pre>
<p>The index for the first timestep. It should be set from pipeline with <code>set_begin_index</code> method.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.set_shift"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.set_shift</code></h3>
<pre class="doc-signature"><code>set_shift(shift: float) -&gt; None</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.set_begin_index"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.set_begin_index</code></h3>
<pre class="doc-signature"><code>set_begin_index(begin_index: int = 0)</code></pre>
<p>Sets the begin index for the scheduler. This function should be run from pipeline before the inference.</p>
<h4>Parameters</h4>
<dl>
<dt><code>begin_index: `int`</code></dt><dd><p>The begin index for the scheduler.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.set_timesteps"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.set_timesteps</code></h3>
<pre class="doc-signature"><code>set_timesteps(num_inference_steps: int | None = None, device: str | torch.device = None, sigmas: list&#91;float&#93; | None = None, mu: float | None | None = None, shift: float | None | None = None, use_karras_sigmas: bool | None = None, use_kerras_sigma: bool | None = None)</code></pre>
<p>Sets the discrete timesteps used for the diffusion chain (to be run before inference).
Args:
    num_inference_steps (<code>int</code>):
        Total number of the spacing of the time steps.
    device (<code>str</code> or <code>torch.device</code>, <em>optional</em>):
        The device to which the timesteps should be moved to. If <code>None</code>, the timesteps are not moved.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.time_shift"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.time_shift</code></h3>
<pre class="doc-signature"><code>time_shift(mu: float, sigma: float, t: torch.Tensor)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.convert_model_output"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.convert_model_output</code></h3>
<pre class="doc-signature"><code>convert_model_output(model_output: torch.Tensor, *args, sample: torch.Tensor = None, **kwargs) -&gt; torch.Tensor</code></pre>
<p>Convert the model output to the corresponding type the UniPC algorithm needs.</p>
<h4>Parameters</h4>
<dl>
<dt><code>model_output: `torch.Tensor`</code></dt><dd><p>The direct output from the learned diffusion model.</p></dd>
<dt><code>timestep: `int`</code></dt><dd><p>The current discrete timestep in the diffusion chain.</p></dd>
<dt><code>sample: `torch.Tensor`</code></dt><dd><p>A current instance of a sample created by the diffusion process.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>torch.Tensor</code></dt><dd><p><code>torch.Tensor</code>:
The converted model output.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.multistep_uni_p_bh_update"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.multistep_uni_p_bh_update</code></h3>
<pre class="doc-signature"><code>multistep_uni_p_bh_update(model_output: torch.Tensor, *args, sample: torch.Tensor = None, order: int | None = None, **kwargs) -&gt; torch.Tensor</code></pre>
<p>One step for the UniP (B(h) version). Alternatively, <code>self.solver_p</code> is used if is specified.</p>
<h4>Parameters</h4>
<dl>
<dt><code>model_output: `torch.Tensor`</code></dt><dd><p>The direct output from the learned diffusion model at the current timestep.</p></dd>
<dt><code>prev_timestep: `int`</code></dt><dd><p>The previous discrete timestep in the diffusion chain.</p></dd>
<dt><code>sample: `torch.Tensor`</code></dt><dd><p>A current instance of a sample created by the diffusion process.</p></dd>
<dt><code>order: `int`</code></dt><dd><p>The order of UniP at this timestep (corresponds to the <em>p</em> in UniPC-p).</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>torch.Tensor</code></dt><dd><p><code>torch.Tensor</code>:
The sample tensor at the previous timestep.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.multistep_uni_c_bh_update"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.multistep_uni_c_bh_update</code></h3>
<pre class="doc-signature"><code>multistep_uni_c_bh_update(this_model_output: torch.Tensor, *args, last_sample: torch.Tensor = None, this_sample: torch.Tensor = None, order: int | None = None, **kwargs) -&gt; torch.Tensor</code></pre>
<p>One step for the UniC (B(h) version).</p>
<h4>Parameters</h4>
<dl>
<dt><code>this_model_output: `torch.Tensor`</code></dt><dd><p>The model outputs at <code>x_t</code>.</p></dd>
<dt><code>this_timestep: `int`</code></dt><dd><p>The current timestep <code>t</code>.</p></dd>
<dt><code>last_sample: `torch.Tensor`</code></dt><dd><p>The generated sample before the last predictor <code>x_&#123;t-1&#125;</code>.</p></dd>
<dt><code>this_sample: `torch.Tensor`</code></dt><dd><p>The generated sample after the last predictor <code>x_&#123;t&#125;</code>.</p></dd>
<dt><code>order: `int`</code></dt><dd><p>The <code>p</code> of UniC-p at this step. The effective order of accuracy should be <code>order + 1</code>.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>torch.Tensor</code></dt><dd><p><code>torch.Tensor</code>:
The corrected sample tensor at the current timestep.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.index_for_timestep"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.index_for_timestep</code></h3>
<pre class="doc-signature"><code>index_for_timestep(timestep, schedule_timesteps = None) -&gt; int</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.step"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.step</code></h3>
<pre class="doc-signature"><code>step(model_output: torch.Tensor, timestep: int | torch.Tensor, sample: torch.Tensor, return_dict: bool = True, generator = None) -&gt; SchedulerOutput | tuple</code></pre>
<p>Predict the sample from the previous timestep by reversing the SDE. This function propagates the sample with
the multistep UniPC.</p>
<h4>Parameters</h4>
<dl>
<dt><code>model_output: `torch.Tensor`</code></dt><dd><p>The direct output from learned diffusion model.</p></dd>
<dt><code>timestep: `int`</code></dt><dd><p>The current discrete timestep in the diffusion chain.</p></dd>
<dt><code>sample: `torch.Tensor`</code></dt><dd><p>A current instance of a sample created by the diffusion process.</p></dd>
<dt><code>return_dict: `bool`</code></dt><dd><p>Whether or not to return a [<code>~schedulers.scheduling_utils.SchedulerOutput</code>] or <code>tuple</code>.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>SchedulerOutput | tuple</code></dt><dd><p>[<code>~schedulers.scheduling_utils.SchedulerOutput</code>] or <code>tuple</code>:
If return_dict is <code>True</code>, [<code>~schedulers.scheduling_utils.SchedulerOutput</code>] is returned, otherwise a
tuple is returned where the first element is the sample tensor.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.scale_model_input"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.scale_model_input</code></h3>
<pre class="doc-signature"><code>scale_model_input(sample: torch.Tensor, *args, **kwargs) -&gt; torch.Tensor</code></pre>
<p>Ensures interchangeability with schedulers that need to scale the denoising model input depending on the
current timestep.</p>
<h4>Parameters</h4>
<dl>
<dt><code>sample: `torch.Tensor`</code></dt><dd><p>The input sample.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>torch.Tensor</code></dt><dd><p><code>torch.Tensor</code>:
A scaled input sample.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.add_noise"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.FlowUniPCMultistepScheduler.add_noise</code></h3>
<pre class="doc-signature"><code>add_noise(original_samples: torch.Tensor, noise: torch.Tensor, timesteps: torch.IntTensor) -&gt; torch.Tensor</code></pre>

<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanAudioDecodingStage"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanAudioDecodingStage</code></h2>
<pre class="doc-signature"><code>MagiHumanAudioDecodingStage(audio_vae, time_stretching: float = _UPSTREAM_AUDIO_TIME_STRETCH)</code></pre>
<p>Decode <code>batch.audio_latents</code> to a waveform using Stable Audio's VAE.</p>
<p>The VAE is loaded lazily by <code>SAAudioVAEModel.sa_audio_vae_model</code> — the
first call triggers a snapshot_download (requires HF token + accepted
terms on stabilityai/stable-audio-open-1.0).</p>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanAudioDecodingStage.verify_input"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanAudioDecodingStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch, fastvideo_args)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanAudioDecodingStage.verify_output"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanAudioDecodingStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch, fastvideo_args)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanAudioDecodingStage.forward"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanAudioDecodingStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>

<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanDenoisingStage"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanDenoisingStage</code></h2>
<pre class="doc-signature"><code>MagiHumanDenoisingStage(transformer, scheduler, patch_size: tuple&#91;int, int, int&#93; = (1, 2, 2), video_in_channels: int = 192, audio_in_channels: int = 64, video_txt_guidance_scale: float = 5.0, audio_txt_guidance_scale: float = 5.0, cfg_number: int = 2, coords_style: str = &#x27;v2&#x27;, video_guidance_high_t_threshold: int = 500, video_guidance_low_t_value: float = 2.0)</code></pre>
<p>UniPC-flow joint denoising with CFG=2 over (video, audio) latents.</p>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanDenoisingStage.verify_input"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanDenoisingStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch, fastvideo_args)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanDenoisingStage.verify_output"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanDenoisingStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch, fastvideo_args)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanDenoisingStage.forward"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanDenoisingStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>

<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanLatentPreparationStage"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanLatentPreparationStage</code></h2>
<pre class="doc-signature"><code>MagiHumanLatentPreparationStage(vae_stride: tuple&#91;int, int, int&#93; = (4, 16, 16), z_dim: int = 48, patch_size: tuple&#91;int, int, int&#93; = (1, 2, 2), fps: int = 25, t5_gemma_target_length: int = 640, coords_style: Literal&#91;&#x27;v1&#x27;, &#x27;v2&#x27;&#93; = &#x27;v2&#x27;, text_offset: int = 0, audio_in_channels: int = 64)</code></pre>
<p>Prepare latents, coords, modality maps, and padded text embed.</p>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanLatentPreparationStage.verify_input"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanLatentPreparationStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch, fastvideo_args)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanLatentPreparationStage.verify_output"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanLatentPreparationStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch, fastvideo_args)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanLatentPreparationStage.forward"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanLatentPreparationStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>

<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanReferenceImageStage"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanReferenceImageStage</code></h2>
<pre class="doc-signature"><code>MagiHumanReferenceImageStage(vae: Any, vae_scale_factor: int = 16)</code></pre>
<p>Encode a TI2V reference image into the first-frame video latent.</p>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanReferenceImageStage.verify_input"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanReferenceImageStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch, fastvideo_args)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanReferenceImageStage.verify_output"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanReferenceImageStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch, fastvideo_args)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanReferenceImageStage.forward"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanReferenceImageStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>

<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRDenoisingStage"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRDenoisingStage</code></h2>
<pre class="doc-signature"><code>MagiHumanSRDenoisingStage(transformer, scheduler, patch_size: tuple&#91;int, int, int&#93; = (1, 2, 2), video_in_channels: int = 192, audio_in_channels: int = 64, sr_num_inference_steps: int = 5, sr_video_txt_guidance_scale: float = 3.5, use_cfg_trick: bool = True, cfg_trick_start_frame: int = 13, cfg_trick_value: float = 2.0, cfg_number: int = 2, coords_style: str = &#x27;v1&#x27;)</code></pre>
<p>Denoise only the SR video latent; audio passes through unchanged.</p>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRDenoisingStage.verify_input"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRDenoisingStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch, fastvideo_args)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRDenoisingStage.verify_output"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRDenoisingStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch, fastvideo_args)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRDenoisingStage.forward"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRDenoisingStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>

<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRLatentPreparationStage"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRLatentPreparationStage</code></h2>
<pre class="doc-signature"><code>MagiHumanSRLatentPreparationStage(vae: Any, vae_stride: tuple&#91;int, int, int&#93; = (4, 16, 16), patch_size: tuple&#91;int, int, int&#93; = (1, 2, 2), noise_value: int = 220, sr_audio_noise_scale: float = 0.7, sr_height: int = 512, sr_width: int = 896, vae_scale_factor: int = 16)</code></pre>
<p>Upsample base latents, add SR noise, and refresh SR conditioning.</p>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRLatentPreparationStage.verify_input"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRLatentPreparationStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch, fastvideo_args)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRLatentPreparationStage.verify_output"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRLatentPreparationStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch, fastvideo_args)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRLatentPreparationStage.forward"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRLatentPreparationStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>

<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase</code></h2>
<pre class="doc-signature"><code>ComposedPipelineBase(model_path: str, fastvideo_args: FastVideoArgs | TrainingArgs, required_config_modules: list&#91;str&#93; | None = None, loaded_modules: dict&#91;str, torch.nn.Module&#93; | None = None)</code></pre>
<p>Base class for pipelines composed of multiple stages.</p>
<p>This class provides the framework for creating pipelines by composing multiple
stages together. Each stage is responsible for a specific part of the diffusion
process, and the pipeline orchestrates the execution of these stages.</p>
<p>Initialize the pipeline. After <strong>init</strong>, the pipeline should be ready to
use. The pipeline should be stateless and not hold any batch state.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.get_hf_download_component_dirs"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.get_hf_download_component_dirs</code></h3>
<pre class="doc-signature"><code>get_hf_download_component_dirs() -&gt; tuple&#91;str, ...&#93; | None</code></pre>
<p>Return component directories for an opt-in partial Hub download.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.get_hf_download_allow_patterns"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.get_hf_download_allow_patterns</code></h3>
<pre class="doc-signature"><code>get_hf_download_allow_patterns() -&gt; list&#91;str&#93; | None</code></pre>
<p>Return Hub patterns for the manifest and selected components.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.set_trainable"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.set_trainable</code></h3>
<pre class="doc-signature"><code>set_trainable() -&gt; None</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.post_init"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.post_init</code></h3>
<pre class="doc-signature"><code>post_init() -&gt; None</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.initialize_training_pipeline"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.initialize_training_pipeline</code></h3>
<pre class="doc-signature"><code>initialize_training_pipeline(training_args: TrainingArgs)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.initialize_validation_pipeline"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.initialize_validation_pipeline</code></h3>
<pre class="doc-signature"><code>initialize_validation_pipeline(training_args: TrainingArgs)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.from_pretrained"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.from_pretrained</code></h3>
<pre class="doc-signature"><code>from_pretrained(model_path: str, device: str | None = None, torch_dtype: torch.dtype | None = None, pipeline_config: str | PipelineConfig | None = None, args: argparse.Namespace | None = None, required_config_modules: list&#91;str&#93; | None = None, loaded_modules: dict&#91;str, torch.nn.Module&#93; | None = None, **kwargs) -&gt; ComposedPipelineBase</code></pre>
<p>Load a pipeline from a pretrained model.
loaded_modules: Optional[Dict[str, torch.nn.Module]] = None,
If provided, loaded_modules will be used instead of loading from config/pretrained weights.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.get_module"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.get_module</code></h3>
<pre class="doc-signature"><code>get_module(module_name: str, default_value: Any = None) -&gt; Any</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.add_module"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.add_module</code></h3>
<pre class="doc-signature"><code>add_module(module_name: str, module: Any)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.required_config_modules"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.required_config_modules</code></h3>
<pre class="doc-signature"><code>required_config_modules: list&#91;str&#93;</code></pre>
<p>List of modules that are required by the pipeline. The names should match
the diffusers directory and model_index.json file. These modules will be
loaded using the PipelineComponentLoader and made available in the
modules dictionary. Access these modules using the get_module method.</p>
<p>class ConcretePipeline(ComposedPipelineBase):
    _required_config_modules = ["vae", "text_encoder", "transformer", "scheduler", "tokenizer"]</p>
<pre><code>@property
def required_config_modules(self):
    return self._required_config_modules
</code></pre>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.stages"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.stages</code></h3>
<pre class="doc-signature"><code>stages: list&#91;PipelineStage&#93;</code></pre>
<p>List of stages in the pipeline.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.create_pipeline_stages"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.create_pipeline_stages</code></h3>
<pre class="doc-signature"><code>create_pipeline_stages(fastvideo_args: FastVideoArgs)</code></pre>
<p>Create the inference pipeline stages.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.create_training_stages"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.create_training_stages</code></h3>
<pre class="doc-signature"><code>create_training_stages(training_args: TrainingArgs)</code></pre>
<p>Create the training pipeline stages.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.initialize_pipeline"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.initialize_pipeline</code></h3>
<pre class="doc-signature"><code>initialize_pipeline(fastvideo_args: FastVideoArgs)</code></pre>
<p>Initialize the pipeline.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.load_modules"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.load_modules</code></h3>
<pre class="doc-signature"><code>load_modules(fastvideo_args: FastVideoArgs, loaded_modules: dict&#91;str, torch.nn.Module&#93; | None = None) -&gt; dict&#91;str, Any&#93;</code></pre>
<p>Load the modules from the config.
loaded_modules: Optional[Dict[str, torch.nn.Module]] = None, 
If provided, loaded_modules will be used instead of loading from config/pretrained weights.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.add_stage"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.add_stage</code></h3>
<pre class="doc-signature"><code>add_stage(stage_name: str, stage: PipelineStage)</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.forward"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>
<p>Generate a video or image using the pipeline.</p>
<h4>Parameters</h4>
<dl>
<dt><code>batch: ForwardBatch</code></dt><dd><p>The batch to generate from.</p></dd>
<dt><code>fastvideo_args: FastVideoArgs</code></dt><dd><p>The inference arguments.</p></dd>
</dl>
<p>Returns:
    ForwardBatch: The batch with the generated video or image.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.train"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.train</code></h3>
<pre class="doc-signature"><code>train() -&gt; None</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.close"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.ComposedPipelineBase.close</code></h3>
<pre class="doc-signature"><code>close() -&gt; None</code></pre>

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

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.DecodingStage.verify_input"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.DecodingStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify decoding stage inputs.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.DecodingStage.verify_output"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.DecodingStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify decoding stage outputs.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.DecodingStage.decode"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.DecodingStage.decode</code></h3>
<pre class="doc-signature"><code>decode(latents: torch.Tensor, fastvideo_args: FastVideoArgs) -&gt; torch.Tensor</code></pre>
<p>Decode latent representations into pixel space using VAE.</p>
<h4>Parameters</h4>
<dl>
<dt><code>latents: torch.Tensor</code></dt><dd><p>Input latent tensor with shape (batch, channels, frames, height_latents, width_latents)</p></dd>
<dt><code>fastvideo_args: FastVideoArgs</code></dt><dd><p>Configuration containing:
- disable_autocast: Whether to disable automatic mixed precision (default: False)
- pipeline_config.vae_precision: VAE computation precision ("fp32", "fp16", "bf16")
- pipeline_config.vae_tiling: Whether to enable VAE tiling for memory efficiency</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>torch.Tensor</code></dt><dd><p>Decoded video tensor with shape (batch, channels, frames, height, width), </p></dd>
<dt><code>torch.Tensor</code></dt><dd><p>normalized to [0, 1] range and moved to CPU as float32</p></dd>
</dl>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.DecodingStage.streaming_decode"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.DecodingStage.streaming_decode</code></h3>
<pre class="doc-signature"><code>streaming_decode(latents: torch.Tensor, fastvideo_args: FastVideoArgs, cache: list&#91;torch.Tensor | None&#93; | None = None, is_first_chunk: bool = False) -&gt; tuple&#91;torch.Tensor, list&#91;torch.Tensor | None&#93;&#93;</code></pre>
<p>Decode latent representations into pixel space using VAE with streaming cache.</p>
<h4>Parameters</h4>
<dl>
<dt><code>latents: torch.Tensor</code></dt><dd><p>Input latent tensor with shape (batch, channels, frames, height_latents, width_latents)</p></dd>
<dt><code>fastvideo_args: FastVideoArgs</code></dt><dd><p>Configuration object.</p></dd>
<dt><code>cache: list[torch.Tensor | None] | None</code></dt><dd><p>VAE cache from previous call, or None to initialize a new cache.</p></dd>
<dt><code>is_first_chunk: bool</code></dt><dd><p>Whether this is the first chunk.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>tuple[torch.Tensor, list[torch.Tensor | None]]</code></dt><dd><p>A tuple of (decoded_frames, updated_cache).</p></dd>
</dl>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.DecodingStage.forward"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.DecodingStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>
<p>Decode latent representations into pixel space.</p>
<p>This method processes the batch through the VAE decoder, converting latent
representations to pixel-space video/images. It also optionally decodes
trajectory latents for visualization purposes.</p>
<h4>Parameters</h4>
<dl>
<dt><code>batch: ForwardBatch</code></dt><dd><p>The current batch containing:
- latents: Tensor to decode (batch, channels, frames, height_latents, width_latents)
- return_trajectory_decoded (optional): Flag to decode trajectory latents
- trajectory_latents (optional): Latents at different timesteps
- trajectory_timesteps (optional): Corresponding timesteps</p></dd>
<dt><code>fastvideo_args: FastVideoArgs</code></dt><dd><p>Configuration containing:
- output_type: "latent" to skip decoding, otherwise decode to pixels
- vae_cpu_offload: Whether to offload VAE to CPU after decoding
- model_loaded: Track VAE loading state
- model_paths: Path to VAE model if loading needed</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>ForwardBatch</code></dt><dd><p>Modified batch with:
- output: Decoded frames (batch, channels, frames, height, width) as CPU float32
- trajectory_decoded (if requested): List of decoded frames per timestep</p></dd>
</dl>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.InputValidationStage"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.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.basic.magi_human.magi_human_pipeline.InputValidationStage.forward"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.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.basic.magi_human.magi_human_pipeline.InputValidationStage.verify_input"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.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.basic.magi_human.magi_human_pipeline.InputValidationStage.verify_output"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.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.basic.magi_human.magi_human_pipeline.TextEncodingStage"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.TextEncodingStage</code></h2>
<pre class="doc-signature"><code>TextEncodingStage(text_encoders, tokenizers)</code></pre>
<p>Stage for encoding text prompts into embeddings for diffusion models.</p>
<p>This stage handles the encoding of text prompts into the embedding space
expected by the diffusion model.</p>
<p>Initialize the prompt encoding stage.</p>
<h3>Parameters</h3>
<dl>
<dt><code>enable_logging</code></dt><dd><p>Whether to enable logging for this stage.</p></dd>
<dt><code>is_secondary</code></dt><dd><p>Whether this is a secondary text encoder.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.TextEncodingStage.forward"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.TextEncodingStage.forward</code></h3>
<pre class="doc-signature"><code>forward(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; ForwardBatch</code></pre>
<p>Encode the prompt into text encoder hidden states.</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 encoded prompt embeddings.</p></dd>
</dl>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.TextEncodingStage.verify_input"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.TextEncodingStage.verify_input</code></h3>
<pre class="doc-signature"><code>verify_input(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify text encoding stage inputs.</p>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.TextEncodingStage.encode_text"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.TextEncodingStage.encode_text</code></h3>
<pre class="doc-signature"><code>encode_text(text: str | list&#91;str&#93;, fastvideo_args: FastVideoArgs, encoder_index: int | list&#91;int&#93; | None = None, return_attention_mask: bool = False, return_type: str = &#x27;list&#x27;, device: torch.device | str | None = None, dtype: torch.dtype | None = None, max_length: int | Sequence&#91;int | None&#93; | None = None, truncation: bool | None = None, padding: bool | str | None = None)</code></pre>
<p>Encode plain text using selected text encoder(s) and return embeddings.</p>
<h4>Parameters</h4>
<dl>
<dt><code>text: str | list[str]</code></dt><dd><p>A single string or a list of strings to encode.</p></dd>
<dt><code>fastvideo_args: FastVideoArgs</code></dt><dd><p>The inference arguments providing pipeline config,
including tokenizer and encoder settings, preprocess and postprocess
functions.</p></dd>
<dt><code>encoder_index: int | list[int] | None</code></dt><dd><p>Encoder selector by index. Accepts an int or list of ints.</p></dd>
<dt><code>return_attention_mask: bool</code></dt><dd><p>If True, also return attention masks for each
selected encoder.</p></dd>
<dt><code>return_type: str</code></dt><dd><p>"list" (default) returns a list aligned with selection;
"dict" returns a dict keyed by encoder index as a string; "stack" stacks along a
new first dimension (requires matching shapes).</p></dd>
<dt><code>device: torch.device | str | None</code></dt><dd><p>Optional device override for inputs; defaults to local torch device.</p></dd>
<dt><code>dtype: torch.dtype | None</code></dt><dd><p>Optional dtype to cast returned embeddings to.</p></dd>
<dt><code>max_length: int | Sequence[int | None] | None</code></dt><dd><p>Optional per-call tokenizer override. Either one value applied to every
selected encoder (existing behavior), or a sequence with one entry per encoder in
<code>encoder_index</code> order -- <code>None</code> at a position falls back to that encoder's own
configured default instead of the override.</p></dd>
<dt><code>truncation: bool | None</code></dt><dd><p>Optional per-call tokenizer override.</p></dd>
<dt><code>padding: bool | str | None</code></dt><dd><p>Optional per-call tokenizer override.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code></code></dt><dd><p>Depending on return_type and return_attention_mask:</p></dd>
<dt><code></code></dt><dd><ul>
<li>list: List[Tensor] or (List[Tensor], List[Tensor])</li>
</ul></dd>
<dt><code></code></dt><dd><ul>
<li>dict: Dict[str, Tensor] or (Dict[str, Tensor], Dict[str, Tensor])</li>
</ul></dd>
<dt><code></code></dt><dd><ul>
<li>stack: Tensor of shape [num_encoders, ...] or a tuple with stacked
attention masks</li>
</ul></dd>
</dl>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.TextEncodingStage.return_embeds"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.TextEncodingStage.return_embeds</code></h3>
<pre class="doc-signature"><code>return_embeds(embeds_list: list&#91;torch.Tensor&#93;, attn_masks_list: list&#91;torch.Tensor&#93;, return_type: str = &#x27;list&#x27;, return_attention_mask: bool = False, indices: list&#91;int&#93; | None = None) -&gt; Any</code></pre>

<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.TextEncodingStage.verify_output"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.TextEncodingStage.verify_output</code></h3>
<pre class="doc-signature"><code>verify_output(batch: ForwardBatch, fastvideo_args: FastVideoArgs) -&gt; VerificationResult</code></pre>
<p>Verify text encoding stage outputs.</p>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.maybe_download_model"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.maybe_download_model</code></h2>
<pre class="doc-signature"><code>maybe_download_model(model_name_or_path: str, local_dir: str | None = None, download: bool = True, revision: str | None = None, allow_patterns: list&#91;str&#93; | None = None) -&gt; str</code></pre>
<p>Check if the model path is a Hugging Face Hub model ID and download it if needed.</p>
<p>Supports an "umbrella" repo layout where a single HF repo holds multiple
pipeline variants under sibling subfolders. If the input is shaped as
<code>org/repo/subfolder</code> (i.e. a non-existent local path with 3+ slash-
separated components and at least one segment that does not look like a
posix-absolute path), treat the first two components as the HF repo id
and the remainder as a subfolder; only the subfolder's blobs are
downloaded, and the returned local path points inside that subfolder.</p>
<h3>Parameters</h3>
<dl>
<dt><code>model_name_or_path: str</code></dt><dd><p>Local path, Hugging Face Hub model ID, or
<code>org/repo/subfolder</code> umbrella-repo reference.</p></dd>
<dt><code>local_dir: str | None</code></dt><dd><p>Local directory to save the model</p></dd>
<dt><code>download: bool</code></dt><dd><p>Whether to download the model from Hugging Face Hub</p></dd>
<dt><code>revision: str | None</code></dt><dd><p>Optional immutable Hub revision.</p></dd>
<dt><code>allow_patterns: list[str] | None</code></dt><dd><p>Optional Hub glob patterns limiting downloaded files.
Local paths are returned unchanged. For umbrella references, the
patterns are interpreted relative to the selected subfolder.</p></dd>
</dl>
<h3>Returns</h3>
<dl>
<dt><code>str</code></dt><dd><p>Local path to the model (or to the subfolder inside the snapshot).</p></dd>
</dl>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.resolve_hf_token"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.resolve_hf_token</code></h2>
<pre class="doc-signature"><code>resolve_hf_token() -&gt; str | None</code></pre>
<p>Return the first non-empty Hugging Face token from the environment.</p>
<p>Reads <code>HF_TOKEN</code>, then <code>HUGGING_FACE_HUB_TOKEN</code>, then the deprecated
FastVideo-specific aliases <code>HUGGINGFACE_HUB_TOKEN</code> and <code>HF_API_KEY</code>,
which log a deprecation warning. Does not mutate <code>os.environ</code>.</p>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanPipeline"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanPipeline</code></h2>
<pre class="doc-signature"><code>MagiHumanPipeline(model_path: str, fastvideo_args: FastVideoArgs | TrainingArgs, required_config_modules: list&#91;str&#93; | None = None, loaded_modules: dict&#91;str, torch.nn.Module&#93; | None = None)</code></pre>
<p>Base MagiHuman text-to-AV pipeline (no LoRA, no distill, no SR).</p>
<details><summary>Source</summary><pre><code>class MagiHumanPipeline(ComposedPipelineBase):
    &quot;&quot;&quot;Base MagiHuman text-to-AV pipeline (no LoRA, no distill, no SR).&quot;&quot;&quot;

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

    def load_modules(
        self,
        fastvideo_args: FastVideoArgs,
        loaded_modules: dict&#91;str, Any&#93; | None = None,
    ) -&gt; dict&#91;str, Any&#93;:
        &quot;&quot;&quot;Load the variant-specific transformer + scheduler from the
        converted MagiHuman repo and lazy-load the four cross-variant
        shared components from their canonical upstream HF repos:

          * text_encoder, tokenizer -&gt; ``google/t5gemma-9b-9b-ul2``
            (gated, requires HF token with accepted terms of use)
          * audio_vae -&gt; ``stabilityai/stable-audio-open-1.0`` (gated)
          * vae -&gt; ``Wan-AI/Wan2.2-TI2V-5B-Diffusers``

        Backwards-compatible with bundled converted repos: if any of
        these subfolders is present locally and listed in
        ``model_index.json``, the standard component loader picks it up
        via super(). Otherwise the loader is told to skip the entry and
        we lazy-load it here.
        &quot;&quot;&quot;
        # T5-Gemma is gated: expose `HF_API_KEY` as `HF_TOKEN` if needed.
        _ensure_hf_token_env()

        # Resolve to a local cache path so we can inspect
        # model_index.json before invoking super(). `maybe_download_model`
        # is idempotent for local paths; super() repeats the call cheaply
        # via `_load_config`.
        local_path = maybe_download_model(self.model_path)

        # Identify which cross-variant shared keys are bundled in the
        # converted repo (declared in model_index.json with a non-null
        # spec) versus absent (the umbrella scheme). Bundled keys stay
        # in `required_config_modules` and are loaded normally by super()
        # from `&lt;model_path&gt;/&lt;key&gt;/`. Absent keys are temporarily
        # dropped so super() does not fail the &quot;every required entry
        # must appear in model_index.json&quot; check, then lazy-loaded
        # below.
        model_index: dict&#91;str, Any&#93; = &#123;&#125;
        try:
            with open(Path(local_path) / &quot;model_index.json&quot;) as f:
                model_index = json.load(f)
        except (FileNotFoundError, json.JSONDecodeError):
            pass

        def _is_bundled(key: str) -&gt; bool:
            spec = model_index.get(key)
            return (isinstance(spec, list | tuple) and len(spec) &gt;= 1 and spec&#91;0&#93; is not None)

        deferred = &#91;&#93;
        for key in (&quot;text_encoder&quot;, &quot;tokenizer&quot;, &quot;audio_vae&quot;, &quot;vae&quot;):
            if key in self.required_config_modules and not _is_bundled(key):
                self.required_config_modules.remove(key)
                deferred.append(key)

        try:
            modules = super().load_modules(fastvideo_args, loaded_modules)
        finally:
            for key in deferred:
                if key not in self.required_config_modules:
                    self.required_config_modules.append(key)

        # For each lazy-load key, prefer whatever super() already loaded
        # (a bundled subfolder, or a caller-provided override merged in
        # via `loaded_modules`). Fall back to the caller-provided
        # `loaded_modules` entry for keys absent from model_index.json
        # (super() never iterates those). Otherwise lazy-load from the
        # canonical upstream HF repo.
        def _resolve(key: str) -&gt; bool:
            &quot;&quot;&quot;Return True if `modules&#91;key&#93;` is already populated.&quot;&quot;&quot;
            if modules.get(key) is not None:
                return True
            if loaded_modules and key in loaded_modules:
                modules&#91;key&#93; = loaded_modules&#91;key&#93;
                return True
            return False

        if not _resolve(&quot;text_encoder&quot;):
            logger.info(&quot;Building T5-Gemma text encoder (lazy-load from %s)&quot;, _T5GEMMA_HF_ID)
            enc_config = T5GemmaEncoderConfig()
            enc_config.arch_config.t5gemma_model_path = _T5GEMMA_HF_ID
            modules&#91;&quot;text_encoder&quot;&#93; = T5GemmaEncoderModel(enc_config)

        if not _resolve(&quot;tokenizer&quot;):
            logger.info(&quot;Loading T5-Gemma tokenizer from %s&quot;, _T5GEMMA_HF_ID)
            modules&#91;&quot;tokenizer&quot;&#93; = AutoTokenizer.from_pretrained(_T5GEMMA_HF_ID)

        if not _resolve(&quot;audio_vae&quot;):
            logger.info(
                &quot;Building Stable Audio Open 1.0 VAE (lazy-load from %s) — &quot;
                &quot;requires HF terms accepted for gated repo&quot;,
                _SA_AUDIO_HF_ID,
            )
            audio_config = OobleckVAEConfig()
            audio_config.pretrained_path = _SA_AUDIO_HF_ID
            modules&#91;&quot;audio_vae&quot;&#93; = SAAudioVAEModel(audio_config)

        if not _resolve(&quot;vae&quot;):
            modules&#91;&quot;vae&quot;&#93; = self._load_video_vae(fastvideo_args)

        return modules

    def _load_video_vae(self, fastvideo_args: FastVideoArgs) -&gt; Any:
        &quot;&quot;&quot;Resolve the video VAE: prefer a bundled ``vae/`` subfolder in
        the converted repo (legacy), fall back to lazy-downloading the
        Wan 2.2 TI2V-5B VAE shards from upstream.

        Either way the load goes through FastVideo&#x27;s standard
        ``VAELoader`` so the result is the same FV ``AutoencoderKLWan``
        nn.Module that the bundled path produces.
        &quot;&quot;&quot;
        from fastvideo.models.loader.component_loader import VAELoader

        bundled = Path(self.model_path) / &quot;vae&quot;
        if bundled.is_dir() and (bundled / &quot;config.json&quot;).is_file():
            logger.info(&quot;Loading bundled video VAE from %s&quot;, bundled)
            return VAELoader().load(str(bundled), fastvideo_args)

        from huggingface_hub import snapshot_download

        logger.info(
            &quot;Bundled vae/ not found at %s; lazy-loading Wan 2.2 TI2V-5B VAE from %s&quot;,
            self.model_path,
            _WAN_VAE_HF_ID,
        )
        snapshot = snapshot_download(
            repo_id=_WAN_VAE_HF_ID,
            allow_patterns=&#91;&quot;vae/*&quot;&#93;,
        )
        vae_dir = os.path.join(snapshot, &quot;vae&quot;)
        if not os.path.isdir(vae_dir):
            raise RuntimeError(
                f&quot;snapshot_download returned &#123;snapshot&#125; but no vae/ &quot;
                f&quot;subfolder was found inside it. Check that &#123;_WAN_VAE_HF_ID&#125; &quot;
                &quot;still exposes a Diffusers-format vae/ folder.&quot;, )
        return VAELoader().load(vae_dir, fastvideo_args)

    def initialize_pipeline(self, fastvideo_args: FastVideoArgs) -&gt; None:
        # MagiHuman applies `flow_shift` during timestep setup; keep the
        # scheduler constructor at its default no-op shift.
        self.modules&#91;&quot;scheduler&quot;&#93; = FlowUniPCMultistepScheduler()

    def create_pipeline_stages(self, fastvideo_args: FastVideoArgs) -&gt; None:
        self._add_input_and_conditioning_stages(fastvideo_args)
        self._add_base_latent_and_denoising_stages(fastvideo_args)
        self._add_decode_stages()

    def _add_input_and_conditioning_stages(self, fastvideo_args: FastVideoArgs) -&gt; None:
        self.add_stage(
            stage_name=&quot;input_validation_stage&quot;,
            stage=InputValidationStage(),
        )

        self.add_stage(
            stage_name=&quot;prompt_encoding_stage&quot;,
            stage=TextEncodingStage(
                text_encoders=&#91;self.get_module(&quot;text_encoder&quot;)&#93;,
                tokenizers=&#91;self.get_module(&quot;tokenizer&quot;)&#93;,
            ),
        )

        self._add_reference_image_stage(fastvideo_args)

    def _add_base_latent_and_denoising_stages(self, fastvideo_args: FastVideoArgs) -&gt; None:
        pc = fastvideo_args.pipeline_config
        dit_arch = pc.dit_config.arch_config

        # Data-proxy + eval knobs come from the PipelineConfig (`pc`).
        # Only DiT-architecture fields live on `dit_arch` now.
        self.add_stage(
            stage_name=&quot;latent_preparation_stage&quot;,
            stage=MagiHumanLatentPreparationStage(
                vae_stride=tuple(pc.vae_stride),
                z_dim=pc.z_dim,
                patch_size=tuple(dit_arch.patch_size),
                fps=pc.fps,
                t5_gemma_target_length=pc.t5_gemma_target_length,
                coords_style=pc.coords_style,
                text_offset=pc.text_offset,
                audio_in_channels=dit_arch.audio_in_channels,
            ),
        )

        self.add_stage(
            stage_name=&quot;denoising_stage&quot;,
            stage=MagiHumanDenoisingStage(
                transformer=self.get_module(&quot;transformer&quot;),
                scheduler=self.get_module(&quot;scheduler&quot;),
                patch_size=tuple(dit_arch.patch_size),
                video_in_channels=dit_arch.video_in_channels,
                audio_in_channels=dit_arch.audio_in_channels,
                video_txt_guidance_scale=pc.video_txt_guidance_scale,
                audio_txt_guidance_scale=pc.audio_txt_guidance_scale,
                cfg_number=pc.cfg_number,
                coords_style=pc.coords_style,
                video_guidance_high_t_threshold=pc.video_guidance_high_t_threshold,
                video_guidance_low_t_value=pc.video_guidance_low_t_value,
            ),
        )

    def _add_decode_stages(self) -&gt; None:
        self.add_stage(
            stage_name=&quot;decoding_stage&quot;,
            stage=DecodingStage(vae=self.get_module(&quot;vae&quot;), pipeline=self),
        )

        self.add_stage(
            stage_name=&quot;audio_decoding_stage&quot;,
            stage=MagiHumanAudioDecodingStage(audio_vae=self.get_module(&quot;audio_vae&quot;), ),
        )

    def _add_reference_image_stage(self, fastvideo_args: FastVideoArgs) -&gt; None:
        return</code></pre></details>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanPipeline.load_modules"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanPipeline.load_modules</code></h3>
<pre class="doc-signature"><code>load_modules(fastvideo_args: FastVideoArgs, loaded_modules: dict&#91;str, Any&#93; | None = None) -&gt; dict&#91;str, Any&#93;</code></pre>
<p>Load the variant-specific transformer + scheduler from the
converted MagiHuman repo and lazy-load the four cross-variant
shared components from their canonical upstream HF repos:</p>
<ul>
<li>text_encoder, tokenizer -&gt; <code>google/t5gemma-9b-9b-ul2</code>
    (gated, requires HF token with accepted terms of use)</li>
<li>audio_vae -&gt; <code>stabilityai/stable-audio-open-1.0</code> (gated)</li>
<li>vae -&gt; <code>Wan-AI/Wan2.2-TI2V-5B-Diffusers</code></li>
</ul>
<p>Backwards-compatible with bundled converted repos: if any of
these subfolders is present locally and listed in
<code>model_index.json</code>, the standard component loader picks it up
via super(). Otherwise the loader is told to skip the entry and
we lazy-load it here.</p>
<details><summary>Source</summary><pre><code>def load_modules(
    self,
    fastvideo_args: FastVideoArgs,
    loaded_modules: dict&#91;str, Any&#93; | None = None,
) -&gt; dict&#91;str, Any&#93;:
    &quot;&quot;&quot;Load the variant-specific transformer + scheduler from the
    converted MagiHuman repo and lazy-load the four cross-variant
    shared components from their canonical upstream HF repos:

      * text_encoder, tokenizer -&gt; ``google/t5gemma-9b-9b-ul2``
        (gated, requires HF token with accepted terms of use)
      * audio_vae -&gt; ``stabilityai/stable-audio-open-1.0`` (gated)
      * vae -&gt; ``Wan-AI/Wan2.2-TI2V-5B-Diffusers``

    Backwards-compatible with bundled converted repos: if any of
    these subfolders is present locally and listed in
    ``model_index.json``, the standard component loader picks it up
    via super(). Otherwise the loader is told to skip the entry and
    we lazy-load it here.
    &quot;&quot;&quot;
    # T5-Gemma is gated: expose `HF_API_KEY` as `HF_TOKEN` if needed.
    _ensure_hf_token_env()

    # Resolve to a local cache path so we can inspect
    # model_index.json before invoking super(). `maybe_download_model`
    # is idempotent for local paths; super() repeats the call cheaply
    # via `_load_config`.
    local_path = maybe_download_model(self.model_path)

    # Identify which cross-variant shared keys are bundled in the
    # converted repo (declared in model_index.json with a non-null
    # spec) versus absent (the umbrella scheme). Bundled keys stay
    # in `required_config_modules` and are loaded normally by super()
    # from `&lt;model_path&gt;/&lt;key&gt;/`. Absent keys are temporarily
    # dropped so super() does not fail the &quot;every required entry
    # must appear in model_index.json&quot; check, then lazy-loaded
    # below.
    model_index: dict&#91;str, Any&#93; = &#123;&#125;
    try:
        with open(Path(local_path) / &quot;model_index.json&quot;) as f:
            model_index = json.load(f)
    except (FileNotFoundError, json.JSONDecodeError):
        pass

    def _is_bundled(key: str) -&gt; bool:
        spec = model_index.get(key)
        return (isinstance(spec, list | tuple) and len(spec) &gt;= 1 and spec&#91;0&#93; is not None)

    deferred = &#91;&#93;
    for key in (&quot;text_encoder&quot;, &quot;tokenizer&quot;, &quot;audio_vae&quot;, &quot;vae&quot;):
        if key in self.required_config_modules and not _is_bundled(key):
            self.required_config_modules.remove(key)
            deferred.append(key)

    try:
        modules = super().load_modules(fastvideo_args, loaded_modules)
    finally:
        for key in deferred:
            if key not in self.required_config_modules:
                self.required_config_modules.append(key)

    # For each lazy-load key, prefer whatever super() already loaded
    # (a bundled subfolder, or a caller-provided override merged in
    # via `loaded_modules`). Fall back to the caller-provided
    # `loaded_modules` entry for keys absent from model_index.json
    # (super() never iterates those). Otherwise lazy-load from the
    # canonical upstream HF repo.
    def _resolve(key: str) -&gt; bool:
        &quot;&quot;&quot;Return True if `modules&#91;key&#93;` is already populated.&quot;&quot;&quot;
        if modules.get(key) is not None:
            return True
        if loaded_modules and key in loaded_modules:
            modules&#91;key&#93; = loaded_modules&#91;key&#93;
            return True
        return False

    if not _resolve(&quot;text_encoder&quot;):
        logger.info(&quot;Building T5-Gemma text encoder (lazy-load from %s)&quot;, _T5GEMMA_HF_ID)
        enc_config = T5GemmaEncoderConfig()
        enc_config.arch_config.t5gemma_model_path = _T5GEMMA_HF_ID
        modules&#91;&quot;text_encoder&quot;&#93; = T5GemmaEncoderModel(enc_config)

    if not _resolve(&quot;tokenizer&quot;):
        logger.info(&quot;Loading T5-Gemma tokenizer from %s&quot;, _T5GEMMA_HF_ID)
        modules&#91;&quot;tokenizer&quot;&#93; = AutoTokenizer.from_pretrained(_T5GEMMA_HF_ID)

    if not _resolve(&quot;audio_vae&quot;):
        logger.info(
            &quot;Building Stable Audio Open 1.0 VAE (lazy-load from %s) — &quot;
            &quot;requires HF terms accepted for gated repo&quot;,
            _SA_AUDIO_HF_ID,
        )
        audio_config = OobleckVAEConfig()
        audio_config.pretrained_path = _SA_AUDIO_HF_ID
        modules&#91;&quot;audio_vae&quot;&#93; = SAAudioVAEModel(audio_config)

    if not _resolve(&quot;vae&quot;):
        modules&#91;&quot;vae&quot;&#93; = self._load_video_vae(fastvideo_args)

    return modules</code></pre></details>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanPipeline.initialize_pipeline"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanPipeline.initialize_pipeline</code></h3>
<pre class="doc-signature"><code>initialize_pipeline(fastvideo_args: FastVideoArgs) -&gt; None</code></pre>

<details><summary>Source</summary><pre><code>def initialize_pipeline(self, fastvideo_args: FastVideoArgs) -&gt; None:
    # MagiHuman applies `flow_shift` during timestep setup; keep the
    # scheduler constructor at its default no-op shift.
    self.modules&#91;&quot;scheduler&quot;&#93; = FlowUniPCMultistepScheduler()</code></pre></details>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanPipeline.create_pipeline_stages"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanPipeline.create_pipeline_stages</code></h3>
<pre class="doc-signature"><code>create_pipeline_stages(fastvideo_args: FastVideoArgs) -&gt; None</code></pre>

<details><summary>Source</summary><pre><code>def create_pipeline_stages(self, fastvideo_args: FastVideoArgs) -&gt; None:
    self._add_input_and_conditioning_stages(fastvideo_args)
    self._add_base_latent_and_denoising_stages(fastvideo_args)
    self._add_decode_stages()</code></pre></details>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanI2VPipeline"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanI2VPipeline</code></h2>
<pre class="doc-signature"><code>MagiHumanI2VPipeline(model_path: str, fastvideo_args: FastVideoArgs | TrainingArgs, required_config_modules: list&#91;str&#93; | None = None, loaded_modules: dict&#91;str, torch.nn.Module&#93; | None = None)</code></pre>
<p>MagiHuman text+image-to-AV pipeline using the T2V DiT weights.</p>
<details><summary>Source</summary><pre><code>class MagiHumanI2VPipeline(MagiHumanPipeline):
    &quot;&quot;&quot;MagiHuman text+image-to-AV pipeline using the T2V DiT weights.&quot;&quot;&quot;

    def _add_reference_image_stage(self, fastvideo_args: FastVideoArgs) -&gt; None:
        pc = fastvideo_args.pipeline_config
        self.add_stage(
            stage_name=&quot;reference_image_stage&quot;,
            stage=MagiHumanReferenceImageStage(
                vae=self.get_module(&quot;vae&quot;),
                vae_scale_factor=pc.vae_stride&#91;1&#93;,
            ),
        )</code></pre></details>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRPipeline"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRPipeline</code></h2>
<pre class="doc-signature"><code>MagiHumanSRPipeline(model_path: str, fastvideo_args: FastVideoArgs | TrainingArgs, required_config_modules: list&#91;str&#93; | None = None, loaded_modules: dict&#91;str, torch.nn.Module&#93; | None = None)</code></pre>
<p>Two-stage MagiHuman base + SR-540p text-to-AV pipeline.</p>
<details><summary>Source</summary><pre><code>class MagiHumanSRPipeline(MagiHumanPipeline):
    &quot;&quot;&quot;Two-stage MagiHuman base + SR-540p text-to-AV pipeline.&quot;&quot;&quot;

    _required_config_modules = &#91;
        &quot;text_encoder&quot;,
        &quot;tokenizer&quot;,
        &quot;vae&quot;,
        &quot;transformer&quot;,
        &quot;sr_transformer&quot;,
        &quot;scheduler&quot;,
        &quot;audio_vae&quot;,
    &#93;

    def create_pipeline_stages(self, fastvideo_args: FastVideoArgs) -&gt; None:
        self._add_input_and_conditioning_stages(fastvideo_args)
        self._add_base_latent_and_denoising_stages(fastvideo_args)
        self._add_sr_latent_and_denoising_stages(fastvideo_args)
        self._add_decode_stages()

    def _add_sr_latent_and_denoising_stages(self, fastvideo_args: FastVideoArgs) -&gt; None:
        pc = fastvideo_args.pipeline_config
        dit_arch = pc.dit_config.arch_config
        sr_transformer = self.get_module(&quot;sr_transformer&quot;)
        sr_local_attn_layers = tuple(getattr(pc, &quot;sr_local_attn_layers&quot;, ()))
        if sr_local_attn_layers and hasattr(sr_transformer, &quot;configure_local_attention&quot;):
            sr_transformer.configure_local_attention(
                sr_local_attn_layers,
                frame_receptive_field=pc.frame_receptive_field,
            )

        self.add_stage(
            stage_name=&quot;sr_latent_preparation_stage&quot;,
            stage=MagiHumanSRLatentPreparationStage(
                vae=self.get_module(&quot;vae&quot;),
                vae_stride=tuple(pc.vae_stride),
                patch_size=tuple(dit_arch.patch_size),
                noise_value=pc.noise_value,
                sr_audio_noise_scale=pc.sr_audio_noise_scale,
                sr_height=pc.sr_height,
                sr_width=pc.sr_width,
                vae_scale_factor=pc.vae_stride&#91;1&#93;,
            ),
        )
        self.add_stage(
            stage_name=&quot;sr_denoising_stage&quot;,
            stage=MagiHumanSRDenoisingStage(
                transformer=sr_transformer,
                scheduler=self.get_module(&quot;scheduler&quot;),
                patch_size=tuple(dit_arch.patch_size),
                video_in_channels=dit_arch.video_in_channels,
                audio_in_channels=dit_arch.audio_in_channels,
                sr_num_inference_steps=pc.sr_num_inference_steps,
                sr_video_txt_guidance_scale=pc.sr_video_txt_guidance_scale,
                use_cfg_trick=pc.use_cfg_trick,
                cfg_trick_start_frame=pc.cfg_trick_start_frame,
                cfg_trick_value=pc.cfg_trick_value,
                cfg_number=pc.cfg_number,
                coords_style=&quot;v1&quot;,
            ),
        )</code></pre></details>
<h3 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRPipeline.create_pipeline_stages"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRPipeline.create_pipeline_stages</code></h3>
<pre class="doc-signature"><code>create_pipeline_stages(fastvideo_args: FastVideoArgs) -&gt; None</code></pre>

<details><summary>Source</summary><pre><code>def create_pipeline_stages(self, fastvideo_args: FastVideoArgs) -&gt; None:
    self._add_input_and_conditioning_stages(fastvideo_args)
    self._add_base_latent_and_denoising_stages(fastvideo_args)
    self._add_sr_latent_and_denoising_stages(fastvideo_args)
    self._add_decode_stages()</code></pre></details>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRI2VPipeline"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSRI2VPipeline</code></h2>
<pre class="doc-signature"><code>MagiHumanSRI2VPipeline(model_path: str, fastvideo_args: FastVideoArgs | TrainingArgs, required_config_modules: list&#91;str&#93; | None = None, loaded_modules: dict&#91;str, torch.nn.Module&#93; | None = None)</code></pre>
<p>Two-stage MagiHuman base + SR-540p text+image-to-AV pipeline.</p>
<details><summary>Source</summary><pre><code>class MagiHumanSRI2VPipeline(MagiHumanSRPipeline):
    &quot;&quot;&quot;Two-stage MagiHuman base + SR-540p text+image-to-AV pipeline.&quot;&quot;&quot;

    def _add_reference_image_stage(self, fastvideo_args: FastVideoArgs) -&gt; None:
        pc = fastvideo_args.pipeline_config
        self.add_stage(
            stage_name=&quot;reference_image_stage&quot;,
            stage=MagiHumanReferenceImageStage(
                vae=self.get_module(&quot;vae&quot;),
                vae_scale_factor=pc.vae_stride&#91;1&#93;,
            ),
        )</code></pre></details>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSR1080pPipeline"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSR1080pPipeline</code></h2>
<pre class="doc-signature"><code>MagiHumanSR1080pPipeline(model_path: str, fastvideo_args: FastVideoArgs | TrainingArgs, required_config_modules: list&#91;str&#93; | None = None, loaded_modules: dict&#91;str, torch.nn.Module&#93; | None = None)</code></pre>
<p>Two-stage MagiHuman base + SR-1080p text-to-AV pipeline.</p>
<p>The stage chain is identical to SR-540p. The paired pipeline config enables
block-sparse local-window attention on 32 SR-DiT layers and requests the
1080p latent target.</p>
<details><summary>Source</summary><pre><code>class MagiHumanSR1080pPipeline(MagiHumanSRPipeline):
    &quot;&quot;&quot;Two-stage MagiHuman base + SR-1080p text-to-AV pipeline.

    The stage chain is identical to SR-540p. The paired pipeline config enables
    block-sparse local-window attention on 32 SR-DiT layers and requests the
    1080p latent target.
    &quot;&quot;&quot;</code></pre></details>
<h2 id="fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSR1080pI2VPipeline"><code>fastvideo.pipelines.basic.magi_human.magi_human_pipeline.MagiHumanSR1080pI2VPipeline</code></h2>
<pre class="doc-signature"><code>MagiHumanSR1080pI2VPipeline(model_path: str, fastvideo_args: FastVideoArgs | TrainingArgs, required_config_modules: list&#91;str&#93; | None = None, loaded_modules: dict&#91;str, torch.nn.Module&#93; | None = None)</code></pre>
<p>Two-stage MagiHuman base + SR-1080p text+image-to-AV pipeline.</p>
<details><summary>Source</summary><pre><code>class MagiHumanSR1080pI2VPipeline(MagiHumanSRI2VPipeline):
    &quot;&quot;&quot;Two-stage MagiHuman base + SR-1080p text+image-to-AV pipeline.&quot;&quot;&quot;</code></pre></details>
</div>
