The Cosmos, DreamX-World, Flux, GLM-Image, HunyuanVideo, HyWorld,
Kandinsky5, LingBot, LongCat, Matrix-Game, SD3.5, TurboDiffusion, and
Z-Image pipelines read flow_shift, precisions, vae_tiling,
dmd_denoising_steps, output_type, offload, autocast, and the LongCat BSA
settings from typed paths. LingBot's refine switch reads
pipeline.ltx2.refine.enabled, so the typed field also turns its refiner off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012M91wnVFmPEvJ9h39r5BH7
- LTX-2: the refine settings are read from pipeline.ltx2.refine.* and
pipeline.components.upsampler_weights. The checkpoint's model_index.json
defaults fill the fields that are still None, and the remaining switches
get their defaults, in one recorded override that rebinds the pipeline's
config. An explicit input value now always wins over the checkpoint
default; the flat sentinels (the generic refine_* names and the class
default of the step count) are gone.
- MiniMax-H3: the sequential load, decode backend, TAEH3, parallel VAE,
offload, and checkpoint schedule settings are read from typed paths.
- Wan, MMAudio, MagiHuman, Stable Audio: flow_shift, dmd_denoising_steps,
output_type, workload_type, offload, and autocast settings are read from
typed paths. MagiHuman no longer reads the never-set log_level_progress
name.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012M91wnVFmPEvJ9h39r5BH7
Every parameter, attribute, and keyword argument that carries the runtime
config is named resolved_config instead of fastvideo_args, including the
RPC kwargs keys between the executors and the workers. The module path
fastvideo.fastvideo_args is unchanged. The rename is mechanical (a
token-level rewrite) plus yapf line wrapping.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012M91wnVFmPEvJ9h39r5BH7
ResolvedGeneratorConfig becomes the runtime config of every mode. Resolution
builds the model's PipelineConfig once, freezes it, and attaches it as
resolved_config.pipeline_config; it also exposes mode, training_mode, and
inference_mode. VideoGenerator, fastvideo serve, the OpenAI server state,
the executors, the worker, and ComposedPipelineBase receive the resolved
config instead of a FastVideoArgs, and generator_config_to_fastvideo_args
is no longer on the inference path.
- Schema: ExecutionMode and WorkloadType move to fastvideo/api/schema.py;
typed homes for mode, output_type, boundary_ratio, master_port,
moba_config, and the LTX-2 refine settings; Enum parsing.
- Resolution: steps for the refine preset overrides, flat experimental
keys, the V-MoBA config, the validation that check_fastvideo_args did,
the num_gpus bump, the model's vae_tiling default, and a final
fill_runtime_defaults step for typed fields no earlier step decides.
- fastvideo/api/training_schema.py: TrainingRunConfig and
PreprocessRunConfig roots, their resolvers, and a --config plus dotted
override loader.
- fastvideo/api/device_policy.py: the device offload policy as functions
that return an overridden config; the worker keeps the result. The LTX-2
and MiniMax-H3 checkpoint defaults rebind the pipeline's config.
- fastvideo/api/flat_name_fallback.py answers the flat FastVideoArgs names
on the resolved config until the readers move to typed paths.
Golden changes: the decisions of the steps above are recorded, and
FastVideoArgs.ltx2_vae_tiling holds the model's vae_tiling (it held None;
no runtime code reads it). Against the 3f6893a0 goldens every
FastVideoArgs field, PipelineConfig, and SamplingParam matches, except
disable_autocast and boundary_ratio, which FastVideoArgs held at their
defaults because flattening routed them only to PipelineConfig.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012M91wnVFmPEvJ9h39r5BH7
VideoGenerator.generate(request) is the one inference entry point. The
generate_video keyword call, its mapping from flat keywords to a request
(legacy_generate_call_to_request and its helpers), and the tests of that
mapping are removed. Comments and docs that named generate_video describe
generate and request extensions instead.
scripts/ltx2_sr_alignment.py keeps its generate_video call, because its
reference run imports the separate FastVideo-internal package.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012M91wnVFmPEvJ9h39r5BH7
A request's embedded_cfg_scale (request extension or legacy generate_video
keyword) was applied to a deep copy of FastVideoArgs.pipeline_config in
VideoGenerator. The worker runs the pipeline with its own FastVideoArgs
(GpuWorker.execute_forward passes self.fastvideo_args), so the copy never
reached the denoising stages and the request value was ignored.
embedded_cfg_scale is now a per-request sampling value:
- the request field request.sampling.embedded_cfg_scale (the extension key
still works);
- SamplingParam.embedded_cfg_scale and ForwardBatch.embedded_cfg_scale;
- embedded_cfg_scale_for_batch(batch, fastvideo_args), which the denoising,
SR denoising, Wan DMD, and Flux2 text-encoding stages read. It returns the
batch value, else pipeline_config.embedded_cfg_scale, so training and
requests without the field are unchanged.
VideoGenerator no longer copies or changes FastVideoArgs per request, and
request_to_pipeline_overrides is removed. The golden snapshots record the new
SamplingParam field, and the request with extensions.embedded_cfg_scale now
carries 3.0 on SamplingParam instead of on a pipeline override.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012M91wnVFmPEvJ9h39r5BH7
generator_config_to_fastvideo_args passes the ResolvedGeneratorConfig to
FastVideoArgs through the resolved_config init-only argument. Such an
object keeps the config as resolved_config, skips the environment folds that
resolution has already decided, and becomes read-only after construction.
Its PipelineConfig becomes read-only too:
- Assigning a configuration field raises AttributeError and names
FastVideoArgs.override.
- Runtime state stays writable: model_paths, model_loaded, and the Ray
placement handles. So do nested component configs, which loaders fill
with checkpoint data.
- A FastVideoArgs built directly, as the training and argparse entry points
do, is unchanged and stays writable.
FastVideoArgs.override(source, values) is the one way to change fields after
construction. It records (source, values) in override_log and records the
change on resolved_config for fields that have a typed path. The writers that
changed configuration in place now go through it:
- device_policy:* for the unified-memory, lazy-load, MPS, and layerwise
offload decisions that each worker makes after binding its device;
- checkpoint:model_index.json for the LTX-2 refine defaults;
- checkpoint:fastvideo_inference.json for the FastH3 DMD schedule;
- request for the per-request embedded_cfg_scale copy.
Behavior change: an explicit false for engine.compile.regional or
pipeline.minimax_h3.vae_parallel_decode/encode now wins over
FASTVIDEO_INFERENCE_TORCH_COMPILE and FASTVIDEO_VAE_PARALLEL_*. The resolution
steps fill these fields only while they are unset, and FastVideoArgs no
longer folds the environment a second time.
A test run that froze every FastVideoArgs logged no other non-test writer in
the stages, pipelines, loader, worker, hooks, entrypoints, and platforms
suites.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012M91wnVFmPEvJ9h39r5BH7
The from_pretrained keyword ltx2_refine_lora_path set
pipeline.components.lora_path, which reaches FastVideoArgs.lora_path and loads
as the main LoRA on the stage-1 transformer. The refine stage reads
FastVideoArgs.ltx2_refine_lora_path, which stayed unset. The conversion also
turned an empty string into None. An empty string is how callers such as the
Dreamverse GPU pool disable the refine LoRA, and None makes LTX2Pipeline load
the checkpoint default instead: fastvideo_refine_lora_path in model_index.json
is FastVideo/LTX2-Distilled-LoRA for the LTX-2 Diffusers checkpoints.
The refine LoRA gets its own field, pipeline.ltx2.refine.lora_path, whose
flat name is ltx2_refine_lora_path. None keeps the checkpoint default, and an
empty string disables the refine LoRA. The Dreamverse contract test, the
Dynamo contract example, and the parity inventory point at the field.
Golden changes: kwargs/ltx2_refine_lora_path now records the path on
ltx2_refine_lora_path instead of lora_path, and the added case
kwargs/ltx2_refine_lora_disabled pins the empty string.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012M91wnVFmPEvJ9h39r5BH7
With the device-to-host copy gone, the remaining host-to-device copy is the
stage's cost, and from pageable memory it is staged through a bounce buffer at
roughly 2.6 GB/s instead of full PCIe speed. The host copies are made once, so
pinning them costs nothing per request.
It does cost the module's size in non-pageable host memory (10.4 GB for the
H3 video VAE, 0.6 GB for the audio VAE, per rank) for as long as the pipeline
is alive. It follows --pin-cpu-memory, which is on by default; --no-pin-cpu-
memory keeps the copies pageable and only loses the bandwidth. Note that this
flag did not already reach the VAE: its other use is FSDP's own CPUOffloadPolicy
and the VAE does not go through FSDP.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ATw7g6cxq9N2LtnMratsru
The decode stages move the 10.4 GB fp32 video VAE (and the 0.6 GB audio VAE)
with module.to(device) / module.to("cpu") on every request. The weights are
frozen -- the whole stage runs under no_grad -- so the copy back to the host
returns bytes the host already has.
Keep one host copy per tensor, made the first time the module is loaded, and
on unload point .data back at it instead of copying. One H2D per request, no
D2H at all; the module still lives on the host between requests. Where the old
path allocated a fresh host tensor per cycle and freed the previous one, this
reuses one buffer, so peak host memory can only go down.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ATw7g6cxq9N2LtnMratsru
Accept the causal-VAE-aligned 362-frame bucket (15.083 s) for 15-second H3 requests.
- Hoist MINIMAX_H3_MIN/MAX_ALIGNED_FRAMES next to align_num_frames and reuse them in the CUDA stage, the MLX runtime, and the LoRA example so the bound is consistent across entry points.
- State the accepted frame range in the error messages.
- Cover seconds="15" -> 362 at OpenAI admission and the MLX resolve_geometry bound.
- Update the Spark/openai cookbook frame caps from 345 to 362.
Known gaps: no GPU-lane coverage for the 362 bucket (SSIM runs 124 frames; the golden gate is a fixed-geometry fingerprint), and explicit num_frames=360 still hits the pre-existing grid gate.