Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
19 KiB
Inference Architecture
This section documents the FastVideo inference pipeline: how models are discovered, configs resolved, components loaded, and stages composed to generate video. Training-specific code paths (FSDP, gradient checkpointing) are out of scope.
Registries
FastVideo uses three registries that work together to resolve a
user-provided model_path into a runnable pipeline.
Model Registry (fastvideo/models/registry.py)
Maps HuggingFace architecture class names (e.g. "WanTransformer3DModel")
to FastVideo model classes. Two discovery mechanisms:
- Hardcoded dicts —
_TEXT_TO_VIDEO_DIT_MODELS,_VAE_MODELS,_SCHEDULERS,_TEXT_ENCODER_MODELS,_IMAGE_ENCODER_MODELS,_UPSAMPLERS,_AUDIO_MODELS. Each entry is{hf_class_name: (component_name, module_name, class_name)}. - AST-based discovery —
_discover_and_register_models()walksfastvideo/models/and parses each.pyfile's AST looking for anEntryClassvariable assignment. Discovered models take priority over hardcoded entries. For example,fastvideo/models/dits/wanvideo.pyexportsEntryClass = WanTransformer3DModel.
Both feed into a unified _FAST_VIDEO_MODELS dict, which populates the
singleton ModelRegistry — an instance of _ModelRegistry. Components are
wrapped in _LazyRegisteredModel for deferred import.
Key API: ModelRegistry.resolve_model_cls(architectures) iterates
candidate architecture strings and returns the first matching
(model_cls, arch) tuple. Called by TransformerLoader, VAELoader, etc.
Config Registry (fastvideo/registry.py)
Maps model paths and names to (PipelineConfig, SamplingParam) class
pairs. Registration happens at module load via _register_configs(), which
calls register_configs() for each model family:
register_configs(
sampling_param_cls=WanT2V_1_3B_SamplingParam,
pipeline_config_cls=WanT2V480PConfig,
hf_model_paths=["Wan-AI/Wan2.1-T2V-1.3B-Diffusers"],
model_detectors=[lambda path: "wanpipeline" in path.lower()],
)
Each call populates three data structures:
_CONFIG_REGISTRY: dict[str, ConfigInfo]— auto-incrementing ID toConfigInfo(sampling_param_cls, pipeline_config_cls)._MODEL_HF_PATH_TO_NAME: dict[str, str]— HF path to registry ID._MODEL_NAME_DETECTORS: list[tuple[str, Callable]]— lambda detectors.
Resolution priority (_get_config_info()):
- Exact HF path match in
_MODEL_HF_PATH_TO_NAME. - Partial match on short model name (last path segment, case-insensitive).
- Detector-based match — runs each detector against the lowercased path
and the
_class_namefrommodel_index.json. RuntimeErrorif no match.
Top-level resolver: get_model_info(model_path, pipeline_type, workload_type) combines config resolution with pipeline resolution to
return a ModelInfo(pipeline_cls, sampling_param_cls, pipeline_config_cls).
Pipeline Registry (fastvideo/pipelines/pipeline_registry.py)
Discovers pipeline classes by scanning Python packages under
fastvideo/pipelines/{basic,preprocess,training}/.
import_pipeline_classes() iterates architecture subdirectories
(e.g. wan/, hunyuan/), imports each module, and collects those
exporting an EntryClass attribute. Supports single class or list.
Returns {pipeline_type_str: {pipeline_class_name: pipeline_cls}}.
_PipelineRegistry.resolve_pipeline_cls(pipeline_name, pipeline_type, workload_type) looks up the pipeline class by the _class_name field
from model_index.json.
Config Mechanism
Config Hierarchy
PipelineConfig (fastvideo/configs/pipelines/base.py)
├── WanT2V480PConfig (fastvideo/configs/pipelines/wan.py)
│ ├── WanT2V720PConfig
│ └── WanI2V480PConfig
├── HunyuanConfig (fastvideo/configs/pipelines/hunyuan.py)
├── LTX2T2VConfig (fastvideo/configs/pipelines/ltx2.py)
├── CosmosConfig (fastvideo/configs/pipelines/cosmos.py)
└── ... (15+ model families)
PipelineConfig holds:
- Video generation params:
embedded_cfg_scale,flow_shift,disable_autocast,is_causal. - Nested model configs:
dit_config: DiTConfig,vae_config: VAEConfig,text_encoder_configs: tuple[EncoderConfig, ...]. - Precision settings:
dit_precision,vae_precision,text_encoder_precisions.
Model-specific subclasses override defaults. For example,
WanT2V480PConfig sets flow_shift=3.0 and uses WanVideoConfig as
its DiT config.
ModelConfig / ArchConfig (fastvideo/configs/models/base.py)
ModelConfig wraps an ArchConfig using __getattr__ proxy — attribute
access falls through to arch_config transparently. ArchConfig holds
architecture fields from config.json (hidden_size, num_attention_heads,
etc.) and is immutable after initialization. update_model_arch() writes
to ArchConfig; update_model_config() writes to ModelConfig fields.
Concrete hierarchy: DiTConfig → DiTArchConfig, VAEConfig →
VAEArchConfig, EncoderConfig → EncoderArchConfig.
Config Construction
PipelineConfig.from_pretrained(model_path)— resolves config class viaget_pipeline_config_cls_from_name(), instantiates with defaults.PipelineConfig.from_kwargs(kwargs)— resolves class, optionally loads JSON viaload_from_json(), then applies CLI overrides viaupdate_config_from_dict().dump_to_json()/load_from_json()— JSON persistence. Callable fields andarch_configare excluded from dumps.
SamplingParam (fastvideo/api/sampling_param.py)
Generation parameters separate from pipeline config. Each model family
provides defaults via a profile (see fastvideo/pipelines/basic/<family>/profiles.py):
sp = SamplingParam.from_pretrained("Wan-AI/Wan2.1-T2V-1.3B-Diffusers")
# sp.height == 480, sp.width == 832, sp.num_frames == 81, etc.
Component Loading
ComponentLoader (fastvideo/models/loader/component_loader.py)
Abstract base with a load(model_path, fastvideo_args) method.
ComponentLoader.for_module_type(module_type, library) is a factory
that dispatches to specialized loaders via a module_loaders dict:
| Module type | Loader class | Library |
|---|---|---|
scheduler |
SchedulerLoader |
diffusers |
transformer, transformer_2, transformer_3 |
TransformerLoader |
diffusers |
vae |
VAELoader |
diffusers |
text_encoder, text_encoder_2, text_encoder_3 |
TextEncoderLoader |
transformers |
tokenizer, tokenizer_2, tokenizer_3 |
TokenizerLoader |
transformers |
image_encoder |
ImageEncoderLoader |
transformers |
image_processor, feature_extractor |
ImageProcessorLoader |
transformers |
audio_vae, audio_decoder |
AudioDecoderLoader |
diffusers |
vocoder |
VocoderLoader |
diffusers |
upsampler, upsampler_2 |
UpsamplerLoader |
diffusers |
TransformerLoader reads config.json from the component directory,
resolves the class via ModelRegistry.resolve_model_cls(), instantiates
the model, and loads safetensors weights. CPU offload and layerwise
offload are applied based on FastVideoArgs.
Unknown module types fall back to GenericComponentLoader.
model_index.json
Diffusers-format JSON at the model root. Keys are module names; values
are [library, class_name] tuples:
{
"_class_name": "WanPipeline",
"_diffusers_version": "0.24.0",
"transformer": ["diffusers", "WanTransformer3DModel"],
"vae": ["diffusers", "AutoencoderKLWan"],
"text_encoder": ["transformers", "UMT5EncoderModel"],
"tokenizer": ["transformers", "AutoTokenizer"],
"scheduler": ["diffusers", "FlowMatchEulerDiscreteScheduler"]
}
ComposedPipelineBase.load_modules() reads this file via
_load_config(), strips metadata keys (_class_name,
_diffusers_version, _name_or_path), detects MoE pipelines via
boundary_ratio, then loads each module listed in the pipeline's
required_config_modules. Modules not in required_config_modules are
skipped. _extra_config_module_map allows aliasing (e.g. mapping
"transformer_2" to an alternate directory name).
PipelineComponentLoader.load_module() orchestrates per-component
loading by calling ComponentLoader.for_module_type() then .load().
Stage Design
PipelineStage (fastvideo/pipelines/stages/base.py)
Abstract base class using the Template Method pattern:
__call__(batch, fastvideo_args)— orchestrates verification, timing, and error handling. Not overridden by subclasses.forward(batch, fastvideo_args) -> ForwardBatch— abstract, contains the stage logic.verify_input()/verify_output()— optional hooks returningVerificationResult. Default: no checks.
When fastvideo_args.enable_stage_verification is True, __call__
runs input verification before forward() and output verification after.
When envs.FASTVIDEO_STAGE_LOGGING is set, execution time is measured
with torch.cuda.synchronize() and logged.
ForwardBatch (fastvideo/pipelines/pipeline_batch_info.py)
Dataclass carrying all pipeline state between stages. Key field groups:
- Inputs:
prompt,negative_prompt,image_path,pil_image,video_path. - Embeddings:
prompt_embeds: list[Tensor],negative_prompt_embeds,prompt_attention_mask,image_embeds. - Latents:
latents,image_latent,noise_pred,lq_latents. - Dimensions:
height,width,num_frames,height_latents,width_latents. - Scheduler:
timesteps,num_inference_steps,guidance_scale,sigmas. - Task-specific:
mouse_cond/keyboard_cond(Matrix-Game 2.0),pose(HYWorld),camera_states(GameCraft),c2ws_plucker_emb(LingBotWorld). - Output:
output: Tensor | None. - Logging:
logging_info: PipelineLoggingInfo.
__post_init__ enables CFG when guidance_scale > 1.0 or LTX2 text
CFG scales differ from 1.0.
Stage Catalog
Standard stages (typical execution order):
| Stage | File | Purpose |
|---|---|---|
InputValidationStage |
stages/input_validation.py |
Validates input dimensions and types |
TextEncodingStage |
stages/text_encoding.py |
Encodes prompts via text encoders |
ImageEncodingStage |
stages/image_encoding.py |
Encodes input images (I2V pipelines) |
ConditioningStage |
stages/conditioning.py |
Prepares conditioning embeddings |
TimestepPreparationStage |
stages/timestep_preparation.py |
Sets up scheduler timesteps |
LatentPreparationStage |
stages/latent_preparation.py |
Initializes noise latents |
DenoisingStage |
stages/denoising.py |
Main diffusion denoising loop |
DecodingStage |
stages/decoding.py |
Decodes latents to video via VAE |
Specialized variants: CausalDenoisingStage, LTX2DenoisingStage,
LongCatDenoisingStage, GameCraftDenoisingStage,
HYWorldDenoisingStage, MatrixGame2CausalDenoisingStage,
SRDenoisingStage, LTX2AudioDecodingStage, SD35ConditioningStage,
LTX2TextEncodingStage, LTX2LatentPreparationStage.
Verification System (fastvideo/pipelines/stages/validators.py)
StageValidators (aliased as V) provides static validators:
not_none, positive_int, is_tensor, tensor_with_dims,
positive_int_divisible(divisor), etc.
VerificationResult collects check results:
result = VerificationResult()
result.add_check("height", batch.height, V.positive_int_divisible(8))
result.add_check("width", batch.width, V.positive_int_divisible(8))
is_valid() returns whether all checks passed. get_failure_summary()
provides detailed error messages. Failed verification raises
StageVerificationError.
Pipeline Architecture
ComposedPipelineBase (fastvideo/pipelines/composed_pipeline_base.py)
Abstract base for all inference pipelines. Lifecycle:
__init__(model_path, fastvideo_args)— initializes distributed environment viamaybe_init_distributed_environment_and_model_parallel (tp_size, sp_size), then callsload_modules()to populateself.modules.post_init()— callsinitialize_pipeline()(model-specific setup),create_pipeline_stages()(abstract — subclasses wire stages), optionally appliestorch.compileto transformers, and callswarmup_sequence_parallel_communication().forward(batch, fastvideo_args)— iteratesself.stagescalling each stage in order. Decorated with@torch.no_grad().
Key class attributes:
_required_config_modules: list[str]— module names to load frommodel_index.json._extra_config_module_map: dict[str, str]— aliases for module dirs.is_video_pipeline: bool— whether this produces video output.
Key methods:
add_stage(name, stage)— appends to_stageslist and_stage_name_mappingdict, also sets attribute onself.get_module(name, default)— retrieves a loaded module.from_pretrained(model_path, **kwargs)— class method constructingFastVideoArgsand callingcls(...)thenpost_init().
LoRAPipeline (fastvideo/pipelines/lora_pipeline.py)
Extends ComposedPipelineBase with LoRA adapter support. Sits in the
MRO between the concrete pipeline and ComposedPipelineBase:
class WanPipeline(LoRAPipeline, ComposedPipelineBase):
...
Key functionality:
convert_to_lora_layers()— scans transformer blocks, replaces target linear layers (default: q/k/v/o projections) with LoRA equivalents viaget_lora_layer().set_lora_adapter(path)— loads safetensors containinglora_A,lora_B,lora_alphaand maps weights to internal layers.merge_lora_weights()/unmerge_lora_weights()— activates or deactivates LoRA in the forward pass.LoRAModelLayers— groups LoRA layers by transformer block for efficient layerwise offload.
Distributed Inference
maybe_init_distributed_environment_and_model_parallel(tp_size, sp_size)
in fastvideo/distributed/ initializes torch.distributed and creates
tensor-parallel (TP) and sequence-parallel (SP) process groups.
Key APIs: get_tp_rank(), get_tp_world_size(), get_sp_rank(),
get_sp_world_size(), get_world_rank(), get_world_size().
warmup_sequence_parallel_communication() pre-warms NCCL communicators
to avoid slow first forward passes.
Usage: torchrun --nproc-per-node=N -m fastvideo.entrypoints.cli.main generate --model-path ... --tp-size N --sp-size M.
torch.compile Integration
When fastvideo_args.enable_torch_compile is True,
_maybe_compile_pipeline_module() checks for a _compile_conditions
attribute on the module. If present, only matching submodules are
compiled. Otherwise, the entire module is compiled. FSDP-wrapped
modules are skipped.
Entry Points
Python API (fastvideo/entrypoints/video_generator.py):
generator = VideoGenerator.from_pretrained(
model_path="Wan-AI/Wan2.1-T2V-14B-Diffusers",
num_gpus=1, tp_size=1, sp_size=1,
)
result = generator.generate_video(
prompt="A cat dancing",
height=720, width=1280, num_frames=81,
)
CLI (fastvideo/entrypoints/cli/):
fastvideo generate \
--model-path "Wan-AI/Wan2.1-T2V-14B-Diffusers" \
--prompt "A cat dancing" \
--num-gpus 1
FastVideoArgs (fastvideo/fastvideo_args.py): Central args dataclass.
Key fields: model_path, mode (ExecutionMode), workload_type
(WorkloadType), pipeline_config (PipelineConfig), num_gpus,
tp_size, sp_size, lora_path, dit_cpu_offload,
dit_layerwise_offload, enable_torch_compile,
enable_stage_verification.
Constructed via FastVideoArgs.from_kwargs(**kwargs) which resolves the
PipelineConfig from the registry, applies JSON config if provided, and
merges CLI overrides.
End-to-End Inference Flow
User: VideoGenerator.from_pretrained(model_path, **kwargs)
│
├─ FastVideoArgs.from_kwargs() → PipelineConfig resolved via registry
├─ get_model_info() → ModelInfo(pipeline_cls, sampling_param_cls, ...)
│ ├─ model_index.json read → _class_name extracted
│ ├─ pipeline_registry resolves pipeline_cls from _class_name
│ └─ config_registry resolves config classes from model_path
│
├─ pipeline_cls.__init__(model_path, fastvideo_args)
│ ├─ maybe_init_distributed(tp_size, sp_size)
│ └─ load_modules() → reads model_index.json, loads each component
│ ├─ ComponentLoader.for_module_type() → specialized loader
│ └─ loader.load() → model class resolved, weights loaded
│
└─ pipeline.post_init()
├─ initialize_pipeline() → model-specific setup
├─ create_pipeline_stages() → stages wired with modules
├─ torch.compile (if enabled)
└─ warmup_sequence_parallel_communication()
User: generator.generate_video(prompt, ...)
│
├─ ForwardBatch constructed from SamplingParam + user args
└─ pipeline.forward(batch, fastvideo_args)
├─ InputValidationStage → validates dims
├─ TextEncodingStage → prompt → embeddings
├─ ConditioningStage → prepares conditioning
├─ TimestepPreparationStage → scheduler timesteps
├─ LatentPreparationStage → random noise
├─ DenoisingStage → iterative denoising loop
└─ DecodingStage → latents → video frames
Adding a New Model Family — Checklist
-
Pipeline config — Create a
PipelineConfigsubclass infastvideo/configs/pipelines/<model>.py. Set DiT/VAE/encoder configs, flow_shift, precision defaults. -
Sampling param profile — Create a profile in
fastvideo/pipelines/basic/<model>/profiles.pywith default height, width, num_frames, guidance_scale, num_inference_steps. -
Register configs — In
fastvideo/registry.py, add aregister_configs()call inside_register_configs()withhf_model_pathsand/ormodel_detectors. -
Pipeline class — Create a subclass of
ComposedPipelineBase(orLoRAPipeline+ComposedPipelineBase) infastvideo/pipelines/basic/<model>/<model>_pipeline.py.- Set
_required_config_moduleslisting needed components. - Implement
create_pipeline_stages()wiring stages viaadd_stage(). - Optionally override
initialize_pipeline()for custom setup. - Export
EntryClass = YourPipelineat module level.
- Set
-
Model classes (if custom) — Add DiT/VAE implementations in
fastvideo/models/dits/orfastvideo/models/vaes/withEntryClass = YourModel. The AST discovery will register them automatically. -
Custom stages (if needed) — Subclass
PipelineStageinfastvideo/pipelines/stages/, implementforward(), optionally implementverify_input()/verify_output(). -
Verify — Run
fastvideo generate --config <config.yaml>with a minimal nested config to confirm the pipeline loads and generates output.