LTX-2 MLX Model Loader (T2V/I2V)
LTX-2 on a Mac Only Runs If You Load It Like This
- loras
- pipeline
LTX-2.3 is, by mid-2026, arguably the best locally-runnable video model out there - and on an Apple Silicon Mac it's also the model people most often fail to run. The usual failure looks like this: you load the official LTX workflow, point it at ltx-2.3-22b-dev-fp8.safetensors, hit Queue, and ComfyUI sits on "Reconnecting" forever. Nothing errors, nothing renders.
The reason is boring and specific. Every Lightricks fp8 checkpoint needs CUDA. PyTorch's MPS backend has no kernel for the float8_e4m3fn dtype, so those files either refuse to run or fall back to CPU at a crawl - and ComfyUI's memory handling on unified memory makes it crash rather than crawl. This node exists to route around that entirely: it loads LTX-2.3 through MLX, Apple's own array framework, from the dgrauet/ltx-2-mlx port. No PyTorch on the model path, no fp8 kernels, no CUDA.
What it actually does
The loader is a small adapter with one job: build the right pipeline object and hand it downstream.
pipeline_type picks which upstream class you get. two_stage and two_stage_hq are the quality paths - a half-resolution guided denoise followed by a refinement pass. one_stage does the full 30-step guided denoise at full resolution. distilled is the 8-step + 3-step fast path.
The gap between those is not subtle. In the pack author's own benchmark (M4 Max, 64GB, q4 tier, 704x480, 49 frames), distilled generated in 88 seconds, two_stage and two_stage_hq took ~16 minutes each, and one_stage took 41 minutes. So: distilled for iterating, quality tiers for the shot you've already locked in. That's roughly an 11x spread for the same prompt.
The other thing worth knowing is that the pipeline cache holds exactly one pipeline. It's keyed on the resolved model dir, pipeline type, low_ram, and the LoRA list, and it's wiped before a new entry goes in - deliberately, because a 22B model at q8 or q4 doesn't fit in unified memory twice. Loading a different tier, a different pipeline type, or adding a LoRA evicts what was there and pays the load cost again (the author measures model + text encoder load at 24-41 seconds on q4, before you generate a single frame).
The inputs that matter
model_dir- one of three Hugging Face tiers:dgrauet/ltx-2.3-mlx-q8(~21GB, wants 32GB+ RAM),dgrauet/ltx-2.3-mlx-q4(~12GB, 16GB+ withlow_ramon), or the unquantizeddgrauet/ltx-2.3-mlx(~42GB, 64GB+). Start at q4 if your machine is under 64GB.pipeline_type- as above.distilledis the one you'd reach for first.low_ram- turns on block streaming so larger tiers fit on smaller machines, at a speed cost. This is the difference between "runs" and "doesn't" on a 16GB Mac.custom_model_dir- overridesmodel_dirwhen set. A local path or another HF repo id. Useful if you've already got the weights staged on disk and don't want to re-download them into the HF cache.loras- an autogrow input; each slot takes one LoRA from the LTX2MLXLora node.
The output is a single pipeline socket, and it only feeds LTX2MLXGenerate. That type is custom on purpose: it stops you wiring an audio-to-video pipeline into a T2V generate node, which would fail in a much less friendly way.
Installing it
ComfyUI Manager can do it - search the pack title LTX-2 MLX (Apple Silicon) or the repo name comfyui-ltx2-mlx. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/tanis2000/comfyui-ltx2-mlx.git
cd comfyui-ltx2-mlx
pip install -r requirements.txt
That pip step is heavier than it looks. It pulls ltx-core-mlx and ltx-pipelines-mlx directly from git (needs git installed, and they're unpinned refs, so upstream can move under you), plus mlx, soundfile, and huggingface_hub. You need macOS on arm64 and Python 3.11+, and your ComfyUI has to be recent enough to ship comfy_api.latest - this pack is written against the V3 node schema, and io.Autogrow in particular doesn't exist in older builds.
Weights download themselves the first time the loader runs: your chosen LTX-2.3 tier plus upstream's default Gemma 3 12B 4-bit text encoder (a few GB more). Two things make that first run less painful - run hf auth login in a terminal first, because anonymous Hugging Face downloads are throttled hard, and expect the initial load to be a one-time cost you pay again whenever the cache gets evicted.
Where people get burned
The Mac check. The loader calls a platform guard that raises requires Apple Silicon (macOS + arm64) on anything else. It doesn't just check the OS - it checks platform.machine(), so a ComfyUI venv running under Rosetta as x86_64 fails the same way a Linux box does. If you're on an M-series Mac and seeing that error, your Python is the problem, not the node.
The resolution you ask for isn't always the resolution you get. Two-stage pipelines snap their intermediate and output sizes to a multiple of 64; the author's own 704x480 request rendered at 704x448. If the file came back a different size than the widget says, that's why.
Under 64GB of unified memory, enable low_ram before you raise the tier, and keep the frame count modest. The README notes a prior q8 run at 1920x1080 with 8 seconds of video blowing past an 8-hour budget under swap pressure on the same 64GB machine that handles q4 fine.
Finally, be honest about maturity: the pack is alpha, version 0.2.1, mirroring the upstream port. Retake, keyframe interpolation, and IC-LoRA conditioning exist in the upstream CLI but aren't wrapped as nodes yet. Go in expecting to babysit it a little, and you won't be disappointed.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| model_dir | COMBO | 3 options: dgrauet/ltx-2.3-mlx-q8, dgrauet/ltx-2.3-mlx-q4, dgrauet/ltx-2.3-mlx | |
| pipeline_type | COMBO | 4 options: two_stage, two_stage_hq, one_stage, distilled | |
| low_ram | BOOLEAN | false | — |
| custom_model_diropt | STRING | Overrides model_dir if set (local path or HF repo id). | |
| lorasopt | COMFY_AUTOGROW_V3 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| pipeline | LTX2MLX_PIPELINE | — |