Instructions to use mlx-community/ltx-2.5-mlx with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use mlx-community/ltx-2.5-mlx with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] hf download mlx-community/ltx-2.5-mlx --local-dir ltx-2.5-mlx
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
LTX-2.5 β MLX conversion (bf16, split components)
MLX-format conversion of Lightricks LTX-2.5
(joint audio+video DiT, 22B) for Apple Silicon, in the per-component split layout consumed by
ltx-2-mlx (branch ltx-2.5).
Status (2026-08-13): the port is COMPLETE on both consumers. Python-MLX (
ltx-2-mlx, branchltx-2.5) and Swift-MLX (ltx-2-mlx-swift) both generate end to end, including the DFR pipeline with temporal rounds. Parity-gated per component against the PyTorch reference: text encoder 49 states (mean cosine 0.999985), DiT forward, sampler, keyframe slots, and the DFR canvas geometry bit-exactly.Still a research port β it is not a supported product, and see Memory below before you plan a run.
β οΈ License β read before use
These weights are Derivatives of LTX-2.5 and are distributed under the
LTX-2.x Community License Agreement (license date 2026-08-11). A complete copy ships in
this repo as LICENSE.md, and the Acceptable Use Policy it incorporates by
reference is snapshotted here as
ltx-acceptable-use-policy-snapshot-2026-08-12.pdf
(the version in effect at your time of use governs β check
Lightricks' current AUP).
Transfer notice (Agreement Β§3.5). Your use of these weights is subject to the LTX-2.x Community License Agreement. If you (aggregated across entities under common control) have annual revenues of US $10,000,000 or more, you are a "Commercial Entity" under the Agreement and must obtain a paid license from Lightricks before any use other than the Agreement's non-commercial-purpose carve-outs (testing, evaluation, non-commercial R&D in non-production environments). Sub-threshold commercial and production use is royalty-free under the Agreement's terms.
Further obligations that travel with these weights include (not exhaustive β read the license): machine-generated content disclosure (Attachment A Β§5), no removal or circumvention of any transparency/provenance features (Β§6), EU AI Act / CA AI Transparency Act responsibilities for providers/deployers (Β§6), and the Attachment A acceptable-use terms.
Modification notice (Agreement Β§3.3)
Every tensor file here is modified from the original Lightricks release: re-serialized to
MLX conventions (channels-last conv layouts, component-split files, renamed keys per the
ltx-2-mlx dialect, fused projections split). No weights were trained, fine-tuned, or
numerically altered beyond layout/serialization transforms. Conversion tooling:
scripts/convert_ltx25.py.
Components
| File | Contents | Params |
|---|---|---|
transformer-distilled.safetensors |
distilled joint-AV DiT (fixed 8-step, CFG=1) | 22B |
transformer-dev.safetensors |
dev (full) joint-AV DiT | 22B |
gemma4-12b-ltx-v1/ |
Lightricks-tuned Gemma-4-unified text encoder, HF layout (loads via mlx-lm) |
12B |
connector.safetensors |
text-embeddings connectors + aggregate projections | β |
vae_encoder.safetensors / vae_decoder.safetensors |
conv video VAE (byte-identical to LTX-2.3's) | 726M |
vae_diffusion_decoder.safetensors |
DiffVAE 1-step x0 video decoder (NA attention) | 417M |
audio_vae.safetensors / vocoder.safetensors |
audio VAE + BigVGAN v2 + BWE (byte-identical to 2.3's) | 182M |
spatial_upscaler_x2_v1_1.safetensors |
Γ2 spatial latent upscaler (byte-identical to 2.3's) | 498M |
temporal_upscaler_x2_v1_0.safetensors |
Γ2 temporal latent upscaler (byte-identical to 2.3's) | 131M |
duration_head.safetensors |
promptβduration predictor (fused MHA split to q/k/v) | 1.9M |
config.json / embedded_config.json |
pipeline + transformer configs | β |
Conversion receipts
- Components LTX-2.5 re-ships byte-identical to LTX-2.3 (conv VAE, audio stack, both
upscalers) were converted from the 2.5 sources and verified bit-identical to the
established
mlx-forge2.3 conversions β validating this converter's conv/layout/rename handling against independent tooling. - DiT template enforced at conversion: 4091 tensors per variant = the 2.3 key template
β 96 video-FF biases (
ff_bias: false) +keyframes_abs_pos_embedding. - Text-encoder parity vs the PyTorch reference (transformers
Gemma4Unified): tokenization identical; all 49 tapped hidden states β₯ 0.9997 cosine; pre-connector projections β₯ 0.99996. - The embedded LTX-2.x license text present in upstream file metadata is preserved.
Memory β read this before planning a run
Measured on Apple Silicon (128 GB unified), 448Γ320Γ9 frames, bf16, via the Swift consumer. Your numbers will differ with resolution and frame count; the structure is what transfers.
| peak | |
|---|---|
| default (text encoder co-resident with the DiT) | 62.40 GB |
| with the DiT evicted around the encode phase | 40.66 GB |
The text encoder is the surprise. gemma4-12b-ltx-v1/ is an unquantized bf16 12B β
23.8 GB on disk, ~24.4 GB resident. LTX-2.3 used a 4-bit Gemma-3 (~7 GB), so anything you
carry over from a 2.3 setup will badly under-estimate 2.5. The DiT itself is a 37.98 GB
resident floor at bf16.
Two levers, and they stack:
- Evict the DiT around the phases that don't need it. β21.74 GB (β34.8%) with output bit-identical and wall-clock within run-to-run noise. This is a scheduling change, not a quality trade β it is on by default in the Swift consumer.
- Quantize the text encoder to int8 (group 64, keeping
embed_tokensin bf16): encoder 24.42 β 14.20 GB, end-to-end 62.40 β 52.18 GB. We measured this as numerically faithful (valid-token cosine 0.999820 against a 0.999879 bf16 floor) and perceptually neutral in a blinded 6-pair operator A/B (3 ties, 2β1, all "very close"). β οΈ int4 was REJECTED β 0.996728 on the same metric, consistent with an independent in-fleet measurement of a different frozen encoder. Note that several third-party MLX packs ship this encoder at 4-bit with no published quality data. No quantized sibling is published here; the recipe is in the consuming repo.
β οΈ If you quantize it yourself: the default mlx_lm.convert -q also quantizes
embed_tokens, which is hidden state 00 and the input to all 48 layers β exclude it. The
mixed_* recipes are worse: with tied embeddings they put the embedding table at 3 bits.
Usage
git clone -b ltx-2.5 https://github.com/xocialize/ltx-2-mlx
cd ltx-2-mlx && uv sync
uv run ltx-2-mlx generate \
--model mlx-community/ltx-2.5-mlx \
--distilled \
--prompt "a red fox standing in deep snow, closeup wildlife photography, golden hour" \
-H 512 -W 768 -f 121 --frame-rate 24 -o fox.mp4
Multishot (LTX-2.5 generated keyframe slots) β --num-generated-keyframes N places N
invented keyframes at evenly spaced interior positions. Note what this does and does not do:
it relaxes the effective temporal compression at those positions (each slot costs a full
latent frame of tokens to buy one pixel frame). In our measurement it did not, on its own,
turn a shot-listed prompt into multiple cut shots β that is the DFR pipeline's job.
DFR (diffusion fidelity rendering) is implemented in both consumers. Its spatial detailing pass was preferred by an operator on 4 of 4 matched pairs for roughly Γ1.2 time. Its temporal rounds are a parity/quality feature, not a speed one: they cost Γ2.767 (1 round) / Γ3.542 (2 rounds), and generating the same deliverable natively at the target frame rate was both ~2.8Γ cheaper and preferred. Use rounds when you want the temporal density, not to save time.
Swift
// https://github.com/xocialize/ltx-2-mlx-swift β MLX-Swift consumer.
// 2.5 is detected from the CHECKPOINT (the in-dir gemma4-12b-ltx-v1/), never a path name,
// so a renamed or relocated copy still resolves correctly.
let pipeline = try await LTX2Pipeline.load(ltxDir: modelDir, gemmaDir: gemma4Dir)
let out = try await pipeline.t2vTwoStage(prompt: prompt, height: 320, width: 448,
numFrames: 25, fps: 24, seed: 4242)
Provenance
Converted from Lightricks/LTX-2.5 (comfy split
pack; connectors sourced from the transformer-file bundle, which is what the reference
runtime loads) and Lightricks/LTX-2.5-Diffusers
(diffusion decoder). All credit for the models to Lightricks β see the
LTX-2 reference implementation and the
LTX-2.5 announcement.
vae_decoder_pruna.safetensors β PrunaAI's lean video decoder (optional)
What it is. PrunaAI/PrunaVAED (revision
4baacd7ef66a6131439542c1f05872afe042e128, last modified 2026-07-29), a pruned, distillation-finetuned drop-in
replacement for the LTX-2 video VAE decoder, converted on 2026-07-31 from its diffusers layout to this repo's
ltx-core flat decoder dialect with
scripts/convert_pruna_vae_decoder.py.
The conversion is a key mapping plus the PyTorchβMLX conv transposition; no tensor values are changed. Only the
decoder is produced: the encoder, the latent format and the per-channel statistics are the stock ones, and the
video VAE is byte-identical across LTX-2.3 and LTX-2.5, so one file serves both. It is not a pure width prune β
two blocks carry a channel-adapter ResBlock (conv_in 512β384 and 384β256, with an affine norm3) that the stock
decoder lacks; the MLX decoder derives every width from the weights and enables those adapters on sight.
Why it is here. Decode is roughly 2Γ faster and the decode activation peak materially smaller, at a decode
that is near-identical but not bit-exact. Measured on a 24 GB M5 Pro at the compact24 tier (receipt AB-R-0561,
ltx-2-mlx-swift): β15.9 % wall-clock per clip at the tier's own envelope with the peak unchanged, and where decode
binds (704Γ512Γ121) a 21.1 β 14.5 GB peak that turns an over-budget, swapping run into one within budget. The
Swift port selects it with LTX2Configuration.vaeDecoderPath or LTX_VAE_DECODER=pruna, and makes it the default
decoder on the low tiers (compact24, balanced32) once promoted.
Licence. PrunaAI publishes PrunaVAED under the LTX-2 licence (license_name: ltx-2, base model
diffusers/LTX-2.3-Diffusers). This converted copy is redistributed under the same LTX-2 Community License
Agreement that governs every other file in this repo, with this section as the modification notice (Agreement
Β§3.3). Mirroring and layout conversion do not alter, relax or re-license anything.
Integrity. vae_decoder_pruna.safetensors β 690,025,680 bytes β SHA-256
891ec5f0680acea9acbdd651c9756a26c5d3298480224356cf5ea86071846f79.
- Downloads last month
- 581
Quantized