LTX Video
Mold's LTX Video family covers LTX-2, LTX-2.3, LTX-2.5, and the legacy LTX Video 0.9.x checkpoints on one page. Start with LTX-2.5 for the newest split-pack architecture and synchronized audio-video generation. LTX-2.3 and LTX-2 remain useful for their mature conditioning and LoRA workflows; the older silent 0.9.x family is documented lower on this page.
Choose a generation
| Generation | Best fit today | Mold family |
|---|---|---|
| LTX-2.5 | Newest architecture, joint audio-video, compact INT8 | ltx2 |
| LTX-2.3 | Mature 22B audio-video and control workflows | ltx2 |
| LTX-2 | Mature 19B audio-video path and 24 GB offload | ltx2 |
| LTX 0.9.x | Legacy silent text-to-video checkpoints | ltx-video |
Current generations: LTX-2.5, LTX-2.3, and LTX-2
LTX-2 is Lightricks' joint audio-video family. In mold it is exposed as a separate ltx2 family from the older ltx-video checkpoints, with defaults aimed at synchronized MP4 output and the upstream two-stage / distilled pipelines.
Current status
LTX-2 now runs through mold's in-tree Rust runtime. CUDA and Apple Metal are performance-qualified backends; CPU remains a correctness-oriented path. Metal uses BF16 transformer compute, fused SDPA, streamed FP8 widening, and temporal VAE chunks; the measured Apple Silicon campaign and checkpoint-backed renders cover the 19B (LTX-2) and 22B (LTX-2.3) distilled FP8 tiers. Expect Metal to be slower than a comparable CUDA card; the streamed FP8 path trades speed for fitting a 19B-22B model in unified memory. The native CUDA workflow matrix is validated across 19B/22B text+audio-video, image-to-video, audio-to-video, keyframe, retake, lip dub, public IC-LoRA, spatial upscale (x1.5 / x2 where published), and temporal upscale (x2).
LTX-2.5 adds a 22B split-pack architecture with a Gemma 4 Unified encoder, separate audio and video VAEs, duration prediction, and latent upscalers. Mold defaults bare LTX-2.5 names to the compact distilled INT8 ConvRot + convolutional-VAE pack on every host. That exact-weight route is Metal-qualified; the approximately 71 GB BF16 pack remains downloadable but operator-deferred, and CUDA has a separate completed qualification campaign on NVIDIA hosts.
Implementation provenance
The LTX-2 runtime is a pure-Rust port of Lightricks/LTX-2 (the reference for every pipeline, sampler, guidance, and conditioning question). Its video transformer and video VAE were adapted from mold's legacy LTX-Video model, which was ported from FerrisMind/candle-video (Copyright 2025 FerrisMind, Apache License 2.0), so those two files retain Apache-2.0 portions; see the repository's THIRD_PARTY_NOTICES.md.
Supported Models
| Model | Path | Notes |
|---|---|---|
ltx-2-19b-dev:fp8 | Two-stage | Highest-quality published 19B FP8 checkpoint |
ltx-2-19b-distilled:fp8 | Distilled | Fastest 19B path, recommended default |
ltx-2.3-22b-dev:fp8 | Two-stage | High-quality 22B FP8 checkpoint |
ltx-2.3-22b-distilled:fp8 | Distilled | Fastest 22B path |
ltx-2.3-22b-dev:bf16 | Two-stage | Full-quality, trainable 22B reference weights |
ltx-2.3-22b-distilled:bf16 | Distilled | Full-precision eight-step 22B checkpoint |
ltx-2.5-22b-dev:int8-conv | Two-stage | Compact 22B dev split pack |
ltx-2.5-22b-distilled:int8-conv | Distilled | Recommended compact LTX-2.5 Metal default |
ltx-2.5-22b-dev:bf16-conv | Two-stage | Full-precision Conv-VAE split pack; deferred |
ltx-2.5-22b-distilled:bf16-conv | Distilled | Full-precision Conv-VAE pack; deferred |
ltx-2.5-22b-dev:bf16 | Two-stage | Diffusion-VAE reference pack; deferred |
ltx-2.5-22b-distilled:bf16 | Distilled | Diffusion-VAE reference; deferred |
ltx-2.5-22b-distilled:q3-k-s | Distilled | 11.78 GiB GGUF transformer, smallest tier |
ltx-2.5-22b-distilled:q3 | Distilled | Q3_K_M GGUF transformer |
ltx-2.5-22b-distilled:q4-k-s | Distilled | 14.27 GiB GGUF transformer |
ltx-2.5-22b-distilled:q4 | Distilled | Q4_K_M GGUF transformer, fits 24 GB resident |
ltx-2.5-22b-distilled:q5 | Distilled | Q5_K_M GGUF transformer |
ltx-2.5-22b-distilled:q6 | Distilled | Q6_K GGUF transformer |
ltx-2.5-22b-distilled:q8 | Distilled | Q8_0 GGUF transformer, largest tier |
Bare ltx-2.3-22b-dev and ltx-2.3-22b-distilled names continue to select FP8. Choose :bf16 explicitly for the upstream reference precision used for training and quality evaluation. Each BF16 checkpoint is about 46.1 GB (43.0 GiB); a 48 GB+ CUDA card is the practical target for resident weights. On smaller CUDA cards, mold's native LTX-2 runtime adaptively streams transformer blocks from host memory, trading speed and substantial system RAM for lower VRAM use; see Memory on 24 GB cards. The shared gated Gemma encoder and optional upscaler/LoRA assets add to download and disk requirements.
Bare ltx-2.5-22b-dev and ltx-2.5-22b-distilled names select :int8-conv. The compact distilled split pack is roughly 40 GB on disk (37.2 GiB); all selected files are pinned by SHA-256 and retained under MOLD_HOME. The BF16 split pack is roughly 71 GB. Every LTX-2.5 variant is gated by the upstream LTX-2 Community License, so accept the repository terms and configure a Hugging Face token before pulling.
The GGUF transformer files come from the public Abiray derivative at a pinned revision and reuse the official gated companion pack. Mold validates their GGUF v3 metadata, A/V tensors, shapes, and supported dtypes, and runs them natively: block linears stay quantized at rest and dequantize per forward on CUDA by default (MOLD_LTX2_QMATMUL=1 opts into candle's quantized fast path; Metal keeps QMatMul), so the smaller tiers sit fully resident where the BF16 packs stream — Q4_K_M fits a 24 GB card. :q3 and :q4 mean K_M; K_S uses explicit tags. LoRAs apply as a parallel low-rank branch; full-weight .diff deltas are refused on GGUF tiers.
On Apple Metal, the transformer residency planner preserves a live macOS unified-memory safety floor. It keeps only the blocks that fit and streams the remainder one tensor at a time from the GGUF file with bounded command-buffer fences. If the minimum streaming working set would cross that floor, Mold refuses before transformer allocation. Q3_K_M, Q4_K_M, and Q6_K are hardware-qualified on a 48 GiB Apple M4 Max at 512x512, 9 frames, and 8 steps; matched fixed-seed visual inspection confirmed prompt fidelity. Q3_K_M also completed a 97-frame MP4. The K_S, Q5_K_M, and Q8_0 tiers are not claimed by that Metal qualification campaign.
LTX-2.5 Metal quick start
export MOLD_HOME=/Volumes/ExternalStorage/mold2
mold pull ltx-2.5-22b-distilled:int8-conv
mold run ltx-2.5-22b-distilled:int8-conv \
"a brass automaton drummer performing in gentle rain" \
--width 256 --height 256 --frames 9 --fps 24 --steps 1 --guidance 1The small dimensions and one step above are a smoke test, not recommended quality settings. Downloaded models and completed clips remain in MOLD_HOME; mold does not require moving them into the source checkout.
Implemented Request Surface
- Text-to-audio+video with synchronized MP4 output
- Text-to-audio (audio only, no video) via
--pipeline t2a - First-frame image-to-video via
--image, with an optional prompt - Audio-to-video via
--audio-file - Keyframe interpolation via repeatable
--keyframe - Retake / partial regeneration via
--video+--retake - Lip dub / re-voicing via
--pipeline lip-dub+--ic-lora-control lipdub - IC-LoRA and stacked LoRAs via repeatable
--lora - Official IC-LoRA reference controls via
--ic-lora-control - Camera-control preset names for the published LTX-2 19B camera LoRAs
- Spatial upscale
x2across the family andx1.5forltx-2.3-* - Temporal upscale
x2
Native Parity Matrix
The in-tree test matrix in crates/mold-inference/src/ltx2/runtime.rs keeps the supported native planning surface explicit without requiring full weights. It covers the real-runtime route for these published workflow combinations:
| Workflow | 19B | 22B / LTX-2.3 | Coverage |
|---|---|---|---|
| Text-to-audio+video | Yes | Yes | Planning test + manual CUDA smoke |
| Text-to-audio (audio only) | Yes | Yes | Block-parity + planning tests + manual CUDA |
| First-frame image-to-video | Yes | Yes | Planning test |
| Audio-to-video | Yes | Yes | Planning test |
| Keyframe interpolation | Yes | Yes | Planning test |
| Retake / partial regeneration | Yes | Yes | Planning test |
| Official IC-LoRA controls | Union, Pose, Detailer | Union, Motion Track | Registry, planning, and request-contract tests |
| Two-stage dev checkpoint | Yes | Yes | Planning test |
| Two-stage HQ | Not published as the default 19B path | Yes | Planning test |
Spatial upscale x2 | Yes | Yes | Planning test |
Spatial upscale x1.5 | Not published | Yes | Planning test |
Temporal upscale x2 | Yes | Yes | Planning test |
The fixed-seed CUDA reference case is tracked in the matrix with the 22B distilled docs-gallery seed (424303). Full numeric comparisons still require installed gated weights, CUDA, and checked-in reference artifacts; the unit matrix therefore validates routing and configuration, while manual parity runs should compare generated contact sheets or clips from that fixed seed.
Current Constraints
LTX-2.5 text-to-audio+video and silent text-to-video are qualified on Apple Metal with the distilled INT8 ConvRot + Conv-VAE pack. Image conditioning, automatic duration, and the published spatial/temporal upscalers are wired to the 2.5 split-pack contract and covered by deterministic planning tests.
mold run --predict-durationlets a qualified LTX-2.5 duration head choose a 1-20 second clip; it omitsframesfrom the request and conflicts with--framesand--duration./api/models[].supports_duration_predictionadvertises which checkpoints ship the head.LTX-2.5 BF16 execution is operator-deferred on Metal. The assets remain downloadable and checksum-qualified; mold fails closed instead of claiming a completed BF16 runtime qualification.
LTX-2.5 CUDA qualification is maintained separately from the Apple Metal campaign and has completed on dedicated NVIDIA hosts.
LTX-2.5 IC-LoRA, retake, lip dub, and HDR/EXR are deferred until their 2.5 adapter contracts are validated. Mold will not silently apply LTX-2.3 control weights to a 2.5 request.
Default output is
mp4for this family.gif,apng, andwebpare also supported, but they are treated as silent exports.x2spatial upscaling is wired across the family.x1.5is wired forltx-2.3-*by resolving the published upstream asset on demand.x2temporal upscaling is wired through the native LTX-2 runtime.Camera-control preset aliases are currently published for LTX-2 19B only. For LTX-2.3, pass an explicit
.safetensorspath.Built-in reference controls require an effective distilled checkpoint. Mold rejects dev or architecture-unknown catalog checkpoints before starting a download. Raw custom IC-LoRAs remain available through
--pipeline ic-lora --lora /path/custom.safetensors.Lip dub takes its length and frame rate from the reference clip;
--framesand--fpsare overridden, and mold says so when it does. The reference must carry an audio track, because its speech is what the dub imitates; a silent reference is rejected up front rather than after the checkpoint has loaded. Both axes must be multiples of 64 because the pipeline always renders in two stages. The frame count is rounded down onto the8k+1grid, so a 100-frame reference renders 97 frames.Guide video formats are adapter-specific: Union consumes an already preprocessed Canny, depth, or pose video; Motion Track consumes colored trajectory overlays; Pose consumes a rendered pose video; Detailer consumes the ordinary source clip. Preprocessing, attention masks, and multiple reference videos are not performed by Mold.
The Gemma text encoder source is gated on Hugging Face, so you must have access approved before
mold pullwill complete.When you send source media through
mold serve, the built-in request body limit is64 MiB, which covers common inline retake and audio-to-video requests.Trusted server deployments can use
audio_file_pathandsource_video_pathinstead of inline base64 for larger local media. Configuremedia_rootsorMOLD_MEDIA_ROOTS; mold canonicalizes the target and rejects missing files, directories, traversal, or symlink escapes outside the allow roots.On CUDA, explicit LTX-2 unload drops the retained native runtime, safely synchronizes pending work, and samples the actual free VRAM without invalidating the process-owned primary context. To manually verify OOM recovery, run a GPU-resident LTX-2 request, force unload by switching models or using the server unload/admin path, then confirm the next LTX-2 request logs a fresh runtime load rather than reusing stale allocations.
On 24 GB Ada GPUs such as the RTX 4090, mold keeps the native runtime on the compatible
fp8-castpath rather than Hopper-onlyfp8-scaled-mm.
HDR output
The HDR IC-LoRA re-grades a reference video into ARRI LogC3, which is a log signal; an ordinary 8-bit export throws away the range the adapter exists to produce. Ask for an EXR sequence alongside the video:
mold run ltx-2.3-22b-distilled:fp8 "a neon alley at dusk" \
--pipeline ic-lora --ic-lora-control hdr \
--video reference.mp4 \
--hdr-exr-dir ./shot_exrOne frame_00000.exr per frame, scene-referred linear, sRGB/Rec.709 primaries with a D65 white point. Add --hdr-exr-full-float for 32-bit samples instead of the 16-bit default.
The HDR adapter ships pre-computed text embeddings beside its weights, and mold uses them the way upstream does: they replace prompt encoding rather than supplementing it. The adapter was trained against that one fixed scene context, so a prompt of your own would be out of distribution. Mold loads the companion and skips the Gemma encode entirely, which also makes an HDR render noticeably faster; about 120 s instead of 180 s for a 25-frame 704x448 clip on a 4090. Your prompt text is ignored for this control. That is upstream's design, not a limitation of the port.
EXR export also works with auto-chaining: a frame count above the model's per-clip cap is split into stitched clips, and the sidecar's frame numbering is global across the stitched timeline; each stage writes only the frames it delivers, skipping the motion-tail overlap the stitch drops, so a 121-frame render yields exactly frame_00000.exr through frame_00120.exr with no duplicates or holes. Each stage regrades its own temporal window of the reference video, and the final stage is sized to the exact remainder so nothing renders past the reference's end. Three constraints come with this: chained EXR export runs locally only (--local; a remote server cannot write the sidecar to your machine), the reference video must cover the full requested duration at the render's frame rate, and only Smooth and Cut transitions are supported (a Fade's blended frames exist in no stage's linear tensor, so mold refuses rather than writing a sequence that disagrees with the video).
The EXR sequence is a sidecar, not the gallery artifact: a sequence is many files and gigabytes, so the ordinary tonemapped video is still written and is what appears in the Library. Note that LogC3's toe decodes pure black slightly below zero (about -0.0173). That is faithful to the transfer function and is written verbatim, so a compositor sees the same values upstream produces.
Resolution
LTX-2 renders on a 32-pixel grid, under two independent limits: a total-pixel budget and a per-axis span. The span is the one that decides how far the resolution ladder goes. The checkpoints normalize RoPE pixel positions by 2048px, so a longer edge is outside the trained range even when the frame's total area is small; 3200x512 is 1.64 MP and still out of distribution.
Both limits are per model, because they depend on how the checkpoint renders:
| Checkpoint | Long edge | Total pixels |
|---|---|---|
Renders in one pass (single-file cv: / hf: builds) | 2048px | 1920x1088 (2.1 MP) |
| Ships the spatial upsampler (every manifest LTX-2) | 4096px | 4096x2176 (8.9 MP) |
A checkpoint that ships the spatial upsampler does not denoise the requested shape. It renders stage 1 at half the target, upsamples that latent x2 with the learned upsampler, then refines the result with a stage-2 pass over latent tiles each brought back inside the trained span. That composition is what lets the output exceed a span the transformer never saw, and it is also where the ladder stops. 4096px is exactly the widest target whose halved stage 1 still lands at 2048px; mold applies one spatial rung, so there is no second halving to rescue anything wider.
IC-LoRA reference controls need a 128-pixel canvas
The published ref0.5 control adapters — Union and Motion Track — condition on the guide video at half the conditioned stage's resolution, and that half still has to be a whole number of the video VAE's 32-pixel latent cells. On a composing checkpoint the conditioned stage is already half the output, so both axes of the render must be multiples of 128. The tier default of 1216x704 is not: its stage-1 latent grid is 19x11, which would need a reference of 9.5 x 5.5 cells.
mold snaps such a render down onto the nearest usable canvas and says so (1216x704 renders at 1152x640), so the documented command works with no --width/--height. Name a multiple of 128 on both axes to choose the canvas yourself. Every other adapter, including the camera-control presets and your own LoRAs, is unaffected — only an adapter whose safetensors metadata declares reference_downscale_factor greater than 1 changes the grid.
Nothing is composed by hand: pick the output size and mold runs the composition. /api/models carries the per-model max_pixels, max_axis_pixels, dimension_alignment, and recommended_dimensions so clients do not hardcode any of it, and a checkpoint that cannot compose is never offered a rung it would reject.
Bigger is not automatically better. A single-pass render at 1080p on the 19B checkpoint can show edge artifacts, since that is well above the resolution it was trained at; 1216x704 remains the quality sweet spot.
The 4096px figure belongs to the x2 rung, which is what the pipeline applies by default. --spatial-upscale x1.5 only divides by 1.5, so its stage 1 is larger for the same output: a 3840px frame would render stage 1 at 2560px, past the span. x1.5 therefore reaches 3072px on the long edge, and mold refuses the combination rather than rendering it; stage 2 tiles the refinement, never stage 1. Choosing a single-pass pipeline explicitly (--pipeline one-stage, retake, lip dub) drops the ceiling back to 2048px for the same reason.
The output ladder
Every rung is a multiple of 64, so the halved stage-1 shape still lands on the VAE's 32-pixel latent grid; upstream's own divisor = 64 if is_two_stage rule.
| Rung | Output | Stage 1 | Stage-2 tiles |
|---|---|---|---|
| 720p HD | 1280x704 | 640x352 | 1 |
| 1080p Full HD | 1920x1088 | 960x544 | 1 |
| 1440p QHD | 2560x1408 | 1280x704 | 2 (2x1) |
| 4K UHD | 3840x2112 | 1920x1056 | 4 (2x2) |
4K UHD is 3840x2112, not 3840x2160, because 2160 is not a multiple of 64 and mold rejects an unrenderable shape rather than quietly resizing it. Of the two 64-aligned neighbours, 2112 is the one that works: 3840x2176 generates correctly and then fails at save time, because the bundled OpenH264 encoder refuses anything past 3840x2160 and MP4 is this family's default container. Rounding down is also what upstream's own align_resolution does in CENTER_CROP mode.
The generation ceiling is higher than the ladder: an axis is admitted up to 4096px, which is where the halved stage 1 leaves the trained span. Between 3840 and 4096 the render succeeds and only the H.264 export fails, so those shapes are admitted rather than blocked, but no preset offers one, because the default output would not be writable.
Portrait is the same rung transposed; 2112x3840 composes and costs exactly what 3840x2112 does.
What this costs, measured
Measured on a single RTX 4090 (24 GB), ltx-2-19b-distilled:fp8, 25 frames at 24 fps, silent, seed 424303:
| Output | Result | Wall time | Peak VRAM |
|---|---|---|---|
| 1920x1088 (1080p) | rendered | 372 s | 18.4 GB |
| 2560x1408 (1440p) | rendered | 299 s | 18.1 GB |
| 3840x2176 (4K-class) | OOM in VAE decode | 478 s | 22.8 GB |
3840x2176 with --spatial-tile 768 | generated, failed at H.264 export | 488 s | 18.2 GB |
3840x2112 with --spatial-tile 768 | rendered (4K UHD rung) | 474 s | 18.2 GB |
Two things are worth reading off that table. Peak VRAM barely moves between 1080p and 1440p; the composition is what bounds it, since every stage-2 tile is denoised at a shape inside the trained span and the residency planner simply streams one more transformer block (38/10 resident/streamed at 1080p, 37/11 at 1440p, 36/12 at 4K). And the default 1280px tile is the thing that does not fit at 4K: the diffusion completes either way, but the VAE decode needs the smaller tile.
4K needs --spatial-tile 768 on a 24 GB card.
With the default auto tiling, 4K reaches the VAE decode and fails there with an out-of-memory error naming the phase and the numbers. It does not silently render something smaller. Pass --spatial-tile 768 (upstream's own advice for lower-VRAM GPUs) and the whole render completes at 18.2 GB.
These are single-configuration measurements at 25 frames, not a support matrix. Activation cost scales with frame count, and upstream's own table (for a different pipeline; HDR IC-LoRA, 161 frames, 22B) puts 4K at 48–80 GB, so do not read the numbers above as a promise for a long clip.
For reference, upstream's published figures (hdr_ic_lora.py:780-786):
| Output | 80 GB (H100) | 48 GB (A6000) |
|---|---|---|
| 1280x720 | 161+ frames | 161+ frames |
| 1920x1080 | 161+ frames | 161+ frames |
| 2048x1080 | 161+ frames | 161+ frames |
| 2560x1440 | 161+ frames | 137 frames |
| 3840x2160 | 121 frames | 49 frames |
| 4096x2160 | 105 frames | 49 frames |
Note that the module its --help points at for per-configuration estimates, ltx_pipelines.utils.vram_budget, is not published in the repository; the table is the only figure upstream provides.
Spatial tiling (--spatial-tile)
Past 2048px on an axis, stage-2 refinement runs over overlapping latent tiles instead of the whole frame. Each tile is denoised at a shape inside the trained span, with its RoPE positions renormalized so the tile looks like a sequence starting at zero and its own noise drawn from seed + tile_index, and the results are recombined with a separable trapezoidal window. The VAE decode is tiled the same way when a single frame is too large to decode in one pass. This is upstream's technique, from hdr_ic_lora.py.
--spatial-tile (or MOLD_LTX2_SPATIAL_TILE, which mold serve also reads) controls it:
| Value | Effect |
|---|---|
auto (default) | Tile only past the 2048px trained span, and only decode-tile when the decode would not otherwise fit. |
off | Never tile. A render past the trained span is refused rather than quietly degraded. |
<px> | Force tiles of at most <px> on each spatial axis, with a 256px overlap. Multiples of 32, at least 64. |
<px>:<overlap> | As above with an explicit overlap, also a multiple of 32 and smaller than the tile. |
auto engages exactly at the 2048px span and not one pixel earlier, so every resolution up to and including 1080p renders as it always has. off past the span is an error, not a warning: the failure mode there is a finished video with degraded large-scale structure, which nobody would notice was wrong. Forcing a tile size is mainly a way to compare a tiled render against an untiled one at a resolution that needs neither.
Two things a tiled refinement gives up. Tiles are refined independently, so a structure crossing a seam is resolved by two passes that cannot see each other. Wider overlaps hide more of this. A tiled stage 2 also refines video only, carrying stage 1's audio track through unrefined. This is upstream's own behaviour (each tile runs "a tile-sized ModalitySpec for video only (audio is omitted entirely for HDR)") and the reason holds independently: a spatial tile carries no statement about an audio track, so refining one once per tile would denoise the same track once per tile with no defensible way to recombine the results.
Image-to-video conditioning matches upstream
The still you pass with --image is not fed to the VAE untouched. Matching the official pipeline, mold decodes it with EXIF orientation applied and any embedded ICC profile converted to sRGB, round-trips it through a one-frame H.264/YUV420 compression at the checkpoint generation's training level (LTX-2 and LTX-2.3 were trained against CRF-33 conditioning; mold's bundled encoder expresses this as a constant-quantizer-33 frame and records openh264-cqp33 in the saved metadata), and then fill-resizes and center-crops to the render canvas; the source is never stretched to a mismatched aspect ratio. The round-trip is deliberate: the conditioner was trained on compressed video frames, and a pristine still sits outside that distribution. A checkpoint whose generation mold cannot identify refuses image conditioning with an actionable error instead of guessing; plain text-to-video on the same checkpoint keeps working.
--strength for LTX-2 is source strength: 1.0 pins the opening frame exactly, lower values allow more change. (SD-family img2img uses the same flag with the opposite denoise convention; the value is passed through unchanged either way.) The default is 0.75.
The prompt is optional for image-to-video
LTX-2 accepts an empty prompt, but only when the request already carries something to animate: a source image, keyframes, a source video, or an --extend continuation. Mold's legacy ltx-video engine is text-to-video only and therefore still requires a prompt:
# Animate a still with no prompt at all
mold run ltx-2-19b-distilled:fp8 --image portrait.png --frames 97 --format mp4This is not a mold extension. The Gemma tokenizer pads to a fixed 1,024-token context and the embeddings connector replaces every padded position with learned register embeddings, so the transformer always sees a full context; "" is a trained input upstream ships itself.
Two things worth being blunt about:
- It saves no memory. The prompt context is a fixed
[1, 1024, 4096]tensor whose size does not depend on how many tokens you typed. Leaving the prompt blank will not make a shape fit that otherwise does not. - Expect near-static output. With nothing describing the motion, the model tends toward a blink or micro-motion. If you want the subject to do something, say so.
Everything else keeps the prompt required: text-to-video with no conditioning, an audio-only --pipeline t2a render (it reads no pixels, so an attached still conditions nothing), and every image family (FLUX, Flux.2, SD1.5/SDXL/SD3.5, Qwen-Image, Z-Image, Wuerstchen) even when you pass --image. A blank prompt also disables prompt expansion for that run (mold will not let the expander invent the prompt that then gets recorded in your metadata) and is not written to prompt history.
The rule is not LTX-2's alone. Wan and MiniMax H3 answer the same way on any tier that takes conditioning, for the same reason: the attached media already decides the render. The justification differs only in the encoder — LTX-2's register embeddings make "" a trained context, while Wan's umT5 still emits its end-of-sequence token for an empty string — and the result is identical.
Web, desktop, and iPhone Create all enable Generate once a source image is attached to a compatible model and say the same thing in the prompt placeholder; sequence clips may be left undescribed under the same rule. On Discord, /generate's prompt option is optional when you attach visual conditioning: a source image, a retake source video, or keyframe images.
Memory on 24 GB cards
The 19B and 22B checkpoints are far larger than a consumer card, so the native runtime plans residency rather than assuming it. Two mechanisms do the work:
- Admission reads the checkpoint's own safetensors header and reconstructs the plan the engine will build (per-block sizes, the non-block transformer weights that streaming never offloads, the bundled video VAE, a token-based activation budget for the exact render shape, runtime headroom, and a fragmentation margin) before anything is loaded. Each chain stage is priced at its own shape, so stage 1 of a two-stage distilled render is charged for its half-resolution render, not the final one.
- Adaptive residency then keeps as many transformer blocks GPU-resident as that budget allows and streams the rest from host memory. When the request came through
mold serve, the planner is bound by the scheduler's admitted peak (min(grant, usable free VRAM)) instead of expanding to fill whatever the card happens to have free.
A shape that cannot run is therefore rejected before the two-minute load. The rejection names the per-device shortfall and, for LTX-2, resolution/frame combinations that do fit on that card, for example:
no device has enough effective VRAM capacity for a safe execution plan:
cuda:0 needs ~26.4 GB of ~23.0 GB usable (needs ~26.4 GB on a 23.0 GB card;
1024x1024 at 65 frames, or 896x896 at 97 frames fits)A predicted peak that no device in the pool could ever hold fails immediately instead of waiting forever for pressure that will never clear. A CUDA OOM message carries the same "this shape … fits" advice.
If CUDA still runs out of memory, the denoise stage retries at a reduced budget, the OOM cooldown is keyed on (model, shape, GPU) so a single-GPU host stops re-admitting the identical failing shape, and one conservative retry at a smaller grant is offered per shape. A fatal CUDA fault (illegal address, uncorrectable ECC, launch failure) is never retried; the worker is quarantined and the process stops, as everywhere else in mold.
Practical guidance for a 24 GB card: ltx-2-19b-distilled:fp8 is the intended path, and 1024x1024 x 97 frames is close to the ceiling. Lower the resolution before the frame count if you need headroom; attention cost grows with the square of the token count, and tokens scale with area × latent frames.
Examples
# Fast default: text to synchronized MP4
mold run ltx-2-19b-distilled:fp8 \
"cinematic close-up of rain on a neon taxi window" \
--frames 97 \
--format mp4
# Audio-to-video
mold run ltx-2-19b-distilled:fp8 \
"paper cutout forest reacting to a violin solo" \
--audio-file ./solo.wav \
--format mp4
# Keyframe interpolation
mold run ltx-2-19b-distilled:fp8 \
"a drone shot over volcanic cliffs" \
--pipeline keyframe \
--frames 97 \
--keyframe 0:./start.png \
--keyframe 96:./end.png
# Camera-control preset
mold run ltx-2-19b-distilled:fp8 \
"a lantern-lit cave entrance" \
--camera-control dolly-in \
--format mp4
# Official Union control. The guide must already be a frame-aligned
# Canny, depth, or pose video; Mold does not preprocess it.
mold run ltx-2-19b-distilled:fp8 \
"a dancer follows the guide" \
--ic-lora-control union \
--video ./canny-guide.mp4 \
--format mp4
# LTX-2.3 Motion Track consumes a video with colored trajectory overlays.
mold run ltx-2.3-22b-distilled:fp8 \
"the drone follows the marked trajectory" \
--ic-lora-control motion-track \
--video ./trajectory-overlay.mp4 \
--format mp4
# Retake a source clip over a time range
mold run ltx-2-19b-distilled:fp8 \
"replace the actor with a chrome mannequin" \
--pipeline retake \
--video ./source.mp4 \
--retake 1.5:3.5 \
--format mp4
# Lip dub: re-voice a clip of someone speaking. The reference video supplies
# the frame count, the frame rate, and the voice; the prompt supplies the new
# line. Width and height must be multiples of 64.
mold run ltx-2.3-22b-distilled:fp8 \
"she says: the harbour freezes over every winter" \
--ic-lora-control lipdub \
--video ./speaker.mp4 \
--width 704 --height 448 \
--format mp4
# Spatial upscale on a published LTX-2.3 asset
mold run ltx-2.3-22b-distilled:fp8 \
"red sports car in rain, cinematic reflections" \
--spatial-upscale x1.5 \
--format mp4Text-to-audio
--pipeline t2a renders sound with no video at all: speech, ambience, or music straight from a prompt. It is upstream's T2AOneStagePipeline.
mold run ltx-2.3-22b-dev:fp8 \
"heavy rain on a tin roof, distant thunder" \
--pipeline t2a \
--frames 121 --fps 24 \
--output rain.wavThings worth knowing:
- Duration comes from
--frames/--fps, the same pair a video render uses: 121 frames at 24 fps is 5.04 seconds. There is no separate duration flag, because the model's temporal budget is expressed in the video clock either way. - The output is a 16-bit PCM stereo WAV at the vocoder's own rate: 24 kHz, or 48 kHz on checkpoints that ship the bandwidth-extension stage.
--formatdefaults towavfor this pipeline and rejects every other value;wavlikewise requires--pipeline t2a. - It needs a checkpoint with audio. A video-only LTX-2 export has no audio VAE or vocoder, and the request is refused before any weights load.
- Steps default to the non-distilled schedule: 40 on LTX-2 19B, 30 on LTX-2.3 22B. The family's usual 8-step default is tuned for the distilled video ladder and produces hiss here, so a smaller
--stepsis raised to the preset default and the run says so. A larger value is used as given. - No conditioning inputs.
--image,--video,--audio-file,--keyframe,--retake, the upscalers, and--upscaleare all rejected rather than silently ignored. - No auto-chaining. A long video request is split into clips because one GPU can only hold so many video latents; audio has neither clips nor that ceiling, so a large
--framesstays a single request. --modality-scalemust stay1.0. Cross-modal guidance steers the audio↔video attention, and there is no video branch here.--batch Nrenders N takes, each written as it lands under its own index (take-0.wav,take-1.wav, …) so a later take failing cannot discard the ones already rendered.
Audio prints land in the gallery like any other output, with a rendered waveform as the tile. Web, desktop, and the CLI all play or save them; the Library's kind filter gains an Audio chip.
Audio-only generation loads just the audio_* half of the checkpoint; about a quarter of the per-block parameters, with both cross-modal attentions gone; so it fits comfortably on a 24 GB card without block streaming.
Advanced guidance controls
LTX-2's multimodal guider takes more than the base guidance scale. Each pipeline ships tuned constants for spatiotemporal guidance (STG), CFG-rescale, audio/video cross-modality guidance, and a guidance skip stride; the flags below override one constant each for a single request. Anything you leave unset keeps the pipeline's own value, so an unflagged render is bit-for-bit what it was before these flags existed.
| Flag | Default | What it does |
|---|---|---|
--stg-scale | 1.0 (two-stage, keyframe, a2-vid) · 0 (two-stage HQ) | Strength of the perturbed-attention pass. Higher adds motion structure and detail; too high destabilizes motion. |
--stg-blocks | 29 on LTX-2 19B · 28 on LTX-2.3 22B | Which transformer blocks the perturbed pass skips. Earlier blocks perturb harder. Comma-separated, up to 8. |
--rescale-scale | 0.7 (two-stage, keyframe, a2-vid) · 0.45/1.0 (HQ) | CFG-rescale between 0 and 1. Raise it when strong guidance washes out contrast. |
--modality-scale | 3.0 | Audio ↔ video cross-modality guidance. 1.0 turns the isolated-modality pass off. |
--guidance-skip-step | 0 (every step) | With n, guidance is applied every n + 1 steps and the conditional prediction is taken otherwise. |
# Softer STG on an earlier block, with a stronger rescale
mold run ltx-2-19b-distilled:fp8 \
"handheld shot through a night market" \
--pipeline two-stage \
--stg-scale 0.6 --stg-blocks 20,29 --rescale-scale 0.9 \
--format mp4Three limits are worth knowing before you reach for these:
- Only pipelines that run the multimodal guider read them. That is
two-stage,two-stage-hq,keyframe,a2-vid, andt2a. Thedistilled,one-stage,ic-lora, andretakepipelines pin guidance to their own path and the overrides are inert there.t2aadditionally rejects a--modality-scaleother than1.0, since it has no video branch. - They never switch a guider on.
a2-vidruns audio positive-only by design; an override tunes the video guider and leaves the audio guider off rather than buying an extra transformer pass you did not ask for. - Sequences ignore them. Chain stages render through their own pipeline constants, so
mold runwarns and continues when a guidance flag meets a chained request.
Enabling STG or cross-modality guidance where the pipeline had it off adds a forward pass per denoise step: expect a slower render and more VRAM.
Chained video output
The LTX-2 distilled pipeline maxes out at 97 pixel frames per clip (13 latent frames after the VAE's 8× temporal compression; 8 × 12 + 1 = 97 satisfies the 8k+1 frame-grid constraint). For anything longer, mold renders a chain: the request is split into N sub-clips, each generated back-to-back, and stitched into a single MP4 at the end. mold keeps the last few frames of clip N's final latents in memory and threads them directly into clip N+1's conditioning, skipping a VAE encode/decode round-trip so the continuation stays visually coherent.
mold run routes automatically: when --frames is ≤ 97 you stay on the single-clip path; above 97 the request is rewritten into a chain and submitted as a durable chain job (POST /api/chain-jobs), whose stage progress the CLI follows over GET /api/chain-jobs/{id}/events. Chaining supports the LTX-2 generation pipelines (one-stage, distilled, two-stage, and two-stage-hq), legacy LTX Video as independent clips, and Wan with checkpoint-dependent seams. Only the audio-only pipeline (t2a) is never chained — its frames is a duration, not a render shape. Chained IC-LoRA is supported for the HDR control (see HDR output); the other specialized conditioning inputs (keyframes, --audio-file, --retake, lip dub) are not carried on the chain wire, so keep those renders inside one clip. See the Wan page for its seam behavior. Image-family models reject --frames past their single-request ceiling with an actionable error rather than silently over-producing. /api/models advertises supports_sequence per model.
97 is a routing default, not the model's ceiling
LTX-2's real single-request limit is a 20-second runtime budget: 481 frames at 24 fps (see Frame ceiling below). 97 is simply the clip size that fits comfortably on one consumer GPU, so auto-chaining uses it. Raise --clip-frames to render one long coherent clip instead of a stitched sequence: --frames 241 --clip-frames 241 gives a single 10-second shot with no seams, at the cost of far more VRAM and time.
$ mold run ltx-2-19b-distilled:fp8 "a cat walking through autumn leaves" \
--image cat.png --frames 400
→ Chain mode: 400 frames → 5 stages × 97 frames (tail 17)
Chain [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 417/417 frames (stages 5)
Stage 1 [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 8/8 steps
Stage 2 [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 8/8 steps
Stage 3 [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 8/8 steps
Stage 4 [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 8/8 steps
Stage 5 [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 8/8 steps
✓ Saved: mold-ltx-2-19b-distilled-<ts>.mp4 (400 frames, 1216x704, 24 fps)
✓ Done: ltx-2-19b-distilled:fp8 in 226.8s (400 frames, seed: 42)Motion-tail carryover
--motion-tail N (default 17) controls how many trailing pixel frames of each clip are reused as latent-space conditioning for the next. Instead of decoding the prior clip's last frame back to RGB and re-encoding it through the VAE as a new source_image, mold narrows the final denoise tensor along its time axis and patchifies those latent tokens directly into the next stage's StageVideoConditioning, so the handoff never leaves latent space. At stitch time, every stage after the first drops its leading N output frames because those are the overlap region shared with the prior clip.
--motion-tail 0: hard concatenation, no overlap. Visible seams are common at clip boundaries; useful when you want discrete shots.--motion-tail 17: the default: three latent frames of carryover (one causal plus two continuation) after the VAE's 8× temporal compression, enough temporal context to continue motion, object identity, and lighting across the seam.- Higher values buy more seam-smoothing at the cost of fewer fresh pixel frames per clip. Must stay strictly below
--clip-frames.
Flags
| Flag | Default | Description |
|---|---|---|
--frames N | model default | Total stitched length. Above --clip-frames, auto-chains. |
--clip-frames N | 97 | Per-clip length. Must be 8k+1; clamped to the model's real budget with a warning. |
--motion-tail N | 17 | Pixel-frame overlap between clips. 0 disables carryover. |
Continuing an existing video
--extend continues a clip you already have instead of starting a new one:
$ mold run ltx-2-19b-distilled:fp8 "the car rounds the headland into fog" \
--extend coast.mp4 --frames 97 --extend-overlap 17
✓ Saved: mold-ltx-2-19b-distilled-<ts>.mp4 (321 frames, 704x480, 24 fps)The delivered file is the original followed by the new footage. --frames is the length of the rendered continuation, and its leading --extend-overlap frames re-render the source tail as motion context; those are dropped from the result, so the run appends frames - overlap new frames.
| Flag | Default | Description |
|---|---|---|
--extend PATH | -- | Video to continue. On LTX-2 every checkpoint continues; Wan continues from an image-conditioned checkpoint. No other family has a continuation path. |
--extend-overlap N | 17 | Pixel frames of the source tail used as motion context. On LTX-2, must be 8k+1 and < --frames. The default is per family; see Wan, whose carryover is one frame. |
Constraints, all enforced before any GPU work:
- The continuation must render at the source clip's resolution and frame rate. Mold rejects a mismatch rather than rescaling mid-video.
--extendcannot be combined with--image,--video, or--keyframe. Each of those claims authority over the same opening frames.- The overlap must sit on the
8k+1grid so the carried frames re-encode cleanly through the video VAE, and must be strictly below--framesso the continuation adds at least one new frame.
Under the hood this is the same motion-tail handoff a sequence uses between clips; the carryover simply comes from a file instead of the previous stage. To chain several continuations, extend the result again.
Frame ceiling
LTX-2's single-request ceiling is a duration, not a frame count. The checkpoints ship pos_embed_max_pos = 20, and the temporal RoPE axis is normalized in seconds; the pixel-frame coordinate is divided by fps before max_pos normalization. So the budget is 20 seconds of runtime:
max_frames = min(20 * fps + 4, 604) snapped down onto the 8k+1 grid| fps | Ceiling | Runtime |
|---|---|---|
| 6 | 121 frames | ~20 s |
| 12 | 241 frames | ~20 s |
| 24 | 481 frames | ~20 s |
| 30 | 601 frames | ~20 s |
The snap matters: 20 * 24 + 4 is 484, which is off the 8k+1 grid the validator enforces, so the requestable ceiling at 24 fps is 481.
GET /api/models advertises max_frames at the model's own default_fps, plus max_runtime_seconds so clients can recompute it when the user changes fps. --temporal-upscale x2 does not extend the budget: it halves the stage-1 frame count and the stage-1 fps, so stage 1 renders the same runtime at half the frame rate.
Whether a long single clip actually fits is a separate question from whether the model allows it; attention cost grows with the square of the token count, so a 481-frame render at 1216x704 needs far more VRAM than most cards have. The validator permits it; auto-chaining stays at 97-frame clips by default.
The final clip is sized so the stitched video lands exactly on total_frames whenever the frame grid allows it; a total the grid cannot express is rounded up by at most one grid step and disclosed before rendering. The user-anchored starting image at the head always stays intact.
v1 constraints
- Video families only. Every LTX-2 video pipeline chains; only the audio-only
t2apipeline is declined outright, and the keyframe, A2V, retake, and lip-dub conditioning inputs are not carried on the chain wire (chained IC-LoRA is supported for the HDR control); LTX-Video concatenates independent clips; Wan chains per checkpoint (see Wan sequences). Image-family models reject--framesabove their single-clip budget. - Single GPU per chain. Every stage runs on the GPU the engine was loaded onto; multi-GPU stage fan-out is a v2 movie-maker feature.
- Resumable. A failed stage settles the durable chain job as
failed; its artifacts are retained and the job can be resumed withmold jobs resume <id>orPOST /api/chain-jobs/{id}/resume. Auto-chained one-shots use the same durable restart path: restart parks them with their completed clips and source media intact, then an explicit resume continues. - Multiple CLI authoring modes. A large
--framesrequest still replicates the main prompt across stages, butmold run --prompt ... --prompt ...builds one stage per prompt andmold run --script shot.tomlsends the canonicalmold.chain.v1script with per-stage prompts, source images, frame counts, and transitions.
The rest of the LTX-2 surface; --image, --audio-file, --lora, --camera-control, --spatial-upscale, --temporal-upscale, and so on; applies to chain renders the same way it applies to single-clip renders. The exception is the advanced guidance overrides above: chain stages keep their pipeline's guider constants, and mold run says so rather than pretending the flags landed. An --image supplied on the CLI lands on stages[0] and is carried forward by the motion-tail latents from there.
Example Clips
Here are a few longer LTX-2 examples rendered with mold. The docs page embeds lightweight webm previews so the examples load quickly in the browser.
ltx-2.5-22b-distilled:q6: 121 frames, 768x512, 24 fps, seed 83007
A single continuous presenter shot with generated speech, lip synchronization, and room ambience. “With Mold, your ideas render right here.”
ltx-2.5-22b-distilled:q6: 97 frames, 640x384, 12 fps, seed 83003
A glass terrarium breathing with tiny plant motion, delicate water sounds, and a restrained indoor soundscape.
ltx-2-19b-distilled:fp8: 97 frames, 640x384, 12 fps
Storm-lashed lighthouse at dusk, gliding coastal pass, thunder, rain, wind, and surf.
ltx-2-19b-distilled:fp8: 97 frames, 640x384, 12 fps
Subway-tunnel drummer performance, orbiting concert camera, percussion, reverb, and distant train rumble.
ltx-2.3-22b-distilled:fp8: 97 frames, 640x384, 12 fps
Red seaplane over an Arctic fjord at sunrise, wingtip bank, spray off the floats, propeller engine, wind, and water hiss.
Notes
--audioand--no-audiocontrol whether the returned MP4 keeps the audio track. If you explicitly choosegif,apng, orwebp, mold exports a silent animation.--video-onlyskips the LTX-2 audio branch entirely. It is output-changing (the branch feeds the video stream, so this is not the same as--no-audio), conflicts with--audioand--audio-file, and is refused for a--framesvalue that auto-chains, because the sequence wire does not carry it.--lorais repeatable for this family. The single legacylorarequest field is still populated for backward compatibility, but the LTX-2 runtime uses the stackedloraslist.
Legacy LTX Video 0.9.x
The original LTX Video checkpoints use a DiT architecture with T5-XXL text encoding and a 3D causal video VAE. They generate silent clips from text and remain available for compatibility, but new users should start with LTX-2.5 or LTX-2.3 for synchronized audio-video and the broader conditioning surface. The former LTX Video 0.9.x route redirects to this section so existing bookmarks continue to work.
ltx-video-0.9.6-distilled:bf16: 8 steps, 33 frames, seed 1234
Northern lights over a frozen Icelandic lake, reflected in the ice.
ltx-video-0.9.6-distilled:bf16: 8 steps, 33 frames, seed 707
A bioluminescent jellyfish pulsing through deep blue water.
Legacy variants
| Model | Steps | Approx total pull | Notes |
|---|---|---|---|
ltx-video-0.9.6:bf16 | 40 | ~17.4 GB | Higher-quality 2B path, 30 FPS defaults |
ltx-video-0.9.6-distilled:bf16 | 8 | ~17.4 GB | Fast default single-pass path |
ltx-video-0.9.8-2b-distilled:bf16 | 7+3 | ~17.8 GB | 0.9.8 checkpoint plus spatial upscaler asset |
ltx-video-0.9.8-13b-dev:bf16 | 30 | ~38.5 GB | Highest-quality 13B multiscale dev path; 40 GB-class GPU, no offload |
ltx-video-0.9.8-13b-distilled:bf16 | 7+3 | ~38.5 GB | Faster 13B checkpoint; 40 GB-class GPU, no offload |
13B BF16 tiers need a 40 GB-class GPU
The legacy 13B checkpoints keep the transformer resident and have no block offload path. On a 24 GB card, use an LTX-2 generation or ltx-video-0.9.8-2b-distilled:bf16 instead.
Legacy defaults and constraints
- Default model:
ltx-video-0.9.6-distilled:bf16 - Resolution: 1216x704; both axes must be multiples of 32
- Frames: 25 by default and always
8n+1 - FPS: 30
- Steps: 8 on 0.9.6 distilled, 40 on 0.9.6, and 7+3 on 0.9.8 distilled
- Output: MP4 by default; GIF, WebP, and APNG are silent alternatives
The sequential pipeline loads the shared T5-XXL encoder, the LTX Video transformer, and the causal video VAE one at a time to keep peak memory manageable. The 2B variants fit comfortably on a 24 GB GPU; the 13B variants do not.
Mold's legacy engine does not implement upstream LTX-Video image conditioning. It rejects source images instead of silently ignoring them; use LTX-2.3 or LTX-2.5 to animate a still. It also cannot carry context between independently rendered clips. Legacy one-shots therefore remain one denoise instead of being automatically split at the 97-frame LTX-2 routing default; the engine accepts up to 257 frames, subject to available GPU memory. Explicitly authored multi-scene sequences remain available and label those seams Join. A manually submitted ephemeral legacy chain is refused at server admission rather than returning the same deterministic clip repeatedly.
# Fast legacy path
mold run ltx-video-0.9.6-distilled:bf16 \
"A cat walking across a sunlit windowsill" --frames 25
# Legacy 0.9.8 multiscale refinement
mold run ltx-video-0.9.8-2b-distilled:bf16 \
"a humanoid robot walking" --frames 49- Developer: Lightricks
- License: LTXV Open Weights License (custom, revenue-gated at $10M)
- Weights: Lightricks/LTX-Video
- Implementation provenance: mold's legacy transformer, VAE, and scheduler were ported from FerrisMind/candle-video, itself a Rust port of Hugging Face diffusers. The Apache-2.0 portions are recorded in
THIRD_PARTY_NOTICES.md.
