Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions .github/workflows/ci-macos-mlx.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: macOS MLX Smoke

on:
pull_request:
branches: [main]
paths:
- ".github/workflows/ci-macos-mlx.yml"
- "fastvideo/mlx_runtime/**"
- "fastvideo/tests/mlx/**"
- "fastvideo/platforms/mps.py"
- "fastvideo/platforms/__init__.py"
- "fastvideo/__init__.py"
- "examples/inference/basic/mlx_*.py"
- "fastvideo/benchmarks/mlx_*.py"
- "pyproject.toml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: macos-mlx-${{ github.ref }}
cancel-in-progress: true

jobs:
mlx-smoke:
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.draft != true
runs-on: macos-15
timeout-minutes: 25
env:
FASTVIDEO_ATTENTION_BACKEND: TORCH_SDPA
TOKENIZERS_PARALLELISM: "false"
MASTER_ADDR: localhost
MASTER_PORT: "29513"
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip

- uses: astral-sh/setup-uv@v3

- name: Install lightweight MLX smoke dependencies
run: |
uv pip install --system \
--index-url https://download.pytorch.org/whl/cpu \
torch==2.11.0 torchvision torchaudio
uv pip install --system \
pytest numpy scipy pillow imageio einops cloudpickle filelock \
PyYAML diffusers huggingface_hub remote-pdb safetensors loguru mlx

- name: Show Apple runtime
run: |
python - <<'PY'
import platform
import mlx.core as mx
import torch

print("machine:", platform.machine())
print("processor:", platform.processor())
print("mlx default device:", mx.default_device())
memory_size = mx.metal.device_info().get("memory_size") if mx.metal.is_available() else "metal unavailable"
print("mlx memory_size:", memory_size)
print("torch:", torch.__version__)
print("torch mps available:", torch.backends.mps.is_available())
PY

- name: Run MLX smoke tests
run: |
python -m pytest \
fastvideo/tests/mlx/test_dmd_sampling.py \
fastvideo/tests/mlx/test_memory_limits.py \
fastvideo/tests/mlx/test_quant_capability.py \
fastvideo/tests/mlx/test_mlx_dit_parity.py \
fastvideo/tests/mlx/test_mlx_compile_parity.py \
fastvideo/tests/mlx/test_mlx_checkpoint.py \
fastvideo/tests/mlx/test_mlx_fastwan_benchmark.py \
fastvideo/tests/mlx/test_taehv_decode.py \
-q

# Same tests on MLX's CPU backend. Hosted macOS runners are scarce and
# slower to schedule; this Linux job gives fast PR signal on the identical
# graph (the parity tests were designed to be backend-agnostic), while the
# macOS job above stays the source of truth for Metal behavior.
mlx-smoke-linux-cpu:
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.draft != true
runs-on: ubuntu-latest
timeout-minutes: 20
env:
FASTVIDEO_ATTENTION_BACKEND: TORCH_SDPA
TOKENIZERS_PARALLELISM: "false"
MASTER_ADDR: localhost
MASTER_PORT: "29513"
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip

- uses: astral-sh/setup-uv@v3

- name: Install lightweight MLX smoke dependencies (CPU backend)
run: |
uv pip install --system \
--index-url https://download.pytorch.org/whl/cpu \
torch==2.11.0 torchvision torchaudio
uv pip install --system \
pytest numpy scipy pillow imageio einops cloudpickle filelock \
PyYAML diffusers huggingface_hub remote-pdb safetensors loguru "mlx[cpu]"

- name: Run MLX smoke tests (CPU backend)
run: |
python -m pytest \
fastvideo/tests/mlx/test_dmd_sampling.py \
fastvideo/tests/mlx/test_memory_limits.py \
fastvideo/tests/mlx/test_quant_capability.py \
fastvideo/tests/mlx/test_mlx_dit_parity.py \
fastvideo/tests/mlx/test_mlx_compile_parity.py \
fastvideo/tests/mlx/test_mlx_checkpoint.py \
fastvideo/tests/mlx/test_mlx_fastwan_benchmark.py \
fastvideo/tests/mlx/test_taehv_decode.py \
-q
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ UV_TORCH_BACKEND=cu126 uv pip install fastvideo
Use `UV_TORCH_BACKEND=cu130` on CUDA 13. Apple silicon users should follow the
[MPS installation guide](https://hao-ai-lab.github.io/FastVideo/getting_started/installation/mps/).

> **On an Apple Silicon Mac?** FastVideo runs FastWan text-to-video natively
> through an MLX runtime — a 5-second 480p clip generated locally, no cloud,
> no discrete GPU. Install with `uv pip install -e '.[mlx]'` and follow the
> [Apple Silicon guide](https://hao-ai-lab.github.io/FastVideo/getting_started/installation/mps/).

Please see our [docs](https://hao-ai-lab.github.io/FastVideo/getting_started/installation/) for more detailed installation instructions.

> **On an NVIDIA DGX Spark (GB10 / ARM64 + CUDA 13)?** There's no prebuilt ARM wheel for the FastVideo CUDA kernel, so it's an editable from-source install (`UV_TORCH_BACKEND=cu130 uv pip install -e .`, which compiles that kernel for you) rather than `UV_TORCH_BACKEND=cu130 uv pip install fastvideo`. A compatible prebuilt ARM64 FlashAttention wheel is available separately. Follow the [DGX Spark install guide](https://hao-ai-lab.github.io/FastVideo/getting_started/installation/spark/).
Expand Down
46 changes: 46 additions & 0 deletions docs/design/apple_silicon_fast_mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Fast mode (RIFE) — Apple Silicon

`--fast` makes local generation ~2.7× faster by **generating fewer frames and
interpolating the rest** with an Apple-Silicon-native RIFE model, instead of
denoising every frame. Video-diffusion denoise is dominated by self-attention,
which is O(tokens²); halving the frames cuts the token count ~2× and the denoise
compute ~3.7×, so the wall-clock drops far more than 2×. RIFE (which estimates
its own optical flow — no motion vectors needed) fills the dropped frames back
in for ~1.4 s, and a light unsharp pass counters its softening.

Measured on the 1.3B INT8 QAD model (fox, 480×832×81, M4): generate 41 + RIFE→81
runs in ~35 s of denoise vs ~90 s full, at reconstruction MS-SSIM **0.97**.
Reproduce with `python -m fastvideo.benchmarks.eval_metalfx_rife --mode int8`.

> **Note:** Apple's *MetalFX* frame interpolation is **not** usable here — it
> requires game-engine motion vectors + depth, which diffusion output lacks. We
> use the video-native **`rife-mlx`** model instead (Metal-backed, torch-free).

## Install

```bash
uv pip install -e ".[mlx]" # pulls in rife-mlx (git dependency)
```

## Use

```bash
python examples/inference/basic/mlx_wan_prompt_to_video.py \
--model-root <FastWan2.1-T2V-1.3B-INT8-QAD> \
--prompt "A red fox trotting through a snowy pine forest at golden hour, cinematic" \
--num-frames 81 --fast \
--output-path video_samples/fox_fast.mp4
```

`--num-frames` stays the *target* length; fast mode generates `num_frames /
fast_factor` frames and interpolates up.

| Flag | Default | Meaning |
|---|---|---|
| `--fast` / `--no-fast` | off | enable fast mode |
| `--fast-factor` | 2 | generate 1/factor of the frames (2 = half) |
| `--fast-sharpen` | 0.6 | light unsharp strength to counter RIFE softness (0 disables) |

Fast mode composes with everything else (`--mlx-quantization int8`,
`--mlx-compile`, TAEHV vs `--decode-backend wan-vae`). Keep `--fast-factor` at 2
for quality — larger temporal gaps are where RIFE starts inventing motion.
138 changes: 60 additions & 78 deletions docs/getting_started/installation/mps.md
Original file line number Diff line number Diff line change
@@ -1,103 +1,85 @@
# MPS (Apple Silicon)
# Apple Silicon FastWan

Instructions to install FastVideo for Apple Silicon.
FastWan-QAD-INT8-1.3B is the Apple-native, text-to-video release candidate.
Its DiT denoising loop runs in MLX; prompt encoding and TAEHV decode use
PyTorch MPS. It does not provide image-to-video support.

## Requirements
## Validated configuration

- **OS: macOS 14 or newer**
- **Python: 3.12.4**
The recorded release result is from an Apple M4 Max with 36 GB-class unified
memory (MLX reports 38.65 GB), macOS 14+, Python 3.12, and MLX 0.31.2:
480x832, 81 frames, three-step DMD, INT8 DiT + TAEHV decode in 123.7 seconds
end to end (117.6 seconds denoise; 5.63 GiB MLX peak).

## Set up using Python
This is the only launch-supported hardware configuration. Allocator-cap tests
are useful engineering evidence, not a claim that a physical 16 GB Mac works.

### Create a new Python environment

#### uv
Recommended default: use [uv](https://docs.astral.sh/uv/) for faster and more stable environment setup.

Please follow the [documentation](https://docs.astral.sh/uv/#getting-started) to install `uv`. After installing `uv`, create a new environment using:
## Install from source

```console
# (Recommended) Create a new uv environment. Use `--seed` to install `pip` and `setuptools`.
brew install ffmpeg
git clone https://github.com/hao-ai-lab/FastVideo.git
cd FastVideo
uv venv --python 3.12 --seed
source .venv/bin/activate
uv pip install -e '.[mlx]'
```

#### Conda (alternative)

You can also create a Python environment using [Conda](https://docs.conda.io/projects/conda/en/stable/user-guide/getting-started.html).

##### 1. Install Miniconda (if not already installed)

```bash
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh
bash Miniconda3-latest-MacOSX-arm64.sh
source ~/.zshrc
```

##### 2. Create and activate a Conda environment for FastVideo
The `mlx` extra is pinned to the MLX 0.31.2 compatibility range and only
resolves on Apple Silicon.

```bash
conda create -n fastvideo python=3.12.4 -y
conda activate fastvideo
```

### Dependencies

```
brew install ffmpeg
```
## Generate a video

### Installation
After publication, download the release model and run the one supported
source-tree entrypoint. The script's defaults are the release configuration
(480x832, 81 frames, 3-step DMD, INT8 DiT, compiled forward, bf16 prompt
encode, TAEHV decode), so the minimal command is:

#### With uv (recommended)

```bash
uv pip install fastvideo
```

#### With Conda environment (alternative)

`uv` works inside an active conda env too, so prefer `uv pip` for the actual install:

```bash
uv pip install fastvideo
```console
huggingface-cli download FastVideo/FastWan-QAD-INT8-1.3B-Diffusers \
--local-dir ~/models/FastWan-QAD-INT8-1.3B

python examples/inference/basic/mlx_wan_prompt_to_video.py \
--model-root ~/models/FastWan-QAD-INT8-1.3B \
--mlx-checkpoint ~/models/FastWan-QAD-INT8-1.3B/mlx_dit \
--prompt "A fox runs through a misty pine forest, leaves kicking up behind it." \
--output-path video_samples/fox.mp4
```

### Installation from Source
The release repository must include the hybrid Diffusers components and the
verified `mlx_dit/` directory. TAEHV's checkpoint is SHA-256 verified before
use; its vendored source is MIT-licensed, while FastVideo is Apache-2.0.

#### 1. Clone the FastVideo repository
### Faster repeat runs

```bash
git clone https://github.com/hao-ai-lab/FastVideo.git && cd FastVideo
```

#### 2. Install FastVideo
- `--mlx-checkpoint` (above) loads pre-quantized INT8 weights and skips
requantization: warm reloads take well under a second. Without the release
`mlx_dit/` directory you can create one locally once with
`--save-mlx-checkpoint ~/models/fastwan_mlx_int8`.
- `--prompt-embeds-cache <path>.npy` reuses the UMT5 encode for a repeated
prompt, skipping the text-encoder load entirely.
- The DiT forward is compiled with `mx.compile` by default (bit-identical to
eager, ~1.4x faster denoise in the A/B). Pass `--no-mlx-compile` to force
eager execution when debugging.

Basic installation:

```bash
uv pip install -e .
```
### Quality mode

Alternative with Conda environment:
TAEHV is a tiny distilled decoder: it is the right default for speed and
memory, but the full Wan VAE preserves more fine texture. On Macs with 32 GB+
of unified memory you can trade decode time for fidelity:

```bash
uv pip install -e .
```console
--decode-backend wan-vae # bf16 decode; add --vae-decode-dtype fp16 on
# macOS/torch builds without bf16 MPS support
```

## Development Environment Setup

If you're planning to contribute to FastVideo please see the following page:
[Contributor Guide](../../contributing/overview.md)

## Hardware Requirements

### For Basic Inference

- Mac M1, M2, M3, or M4 (at least 32 GB RAM is preferable for high quality video generation)

## Troubleshooting

If you encounter any issues during installation, please open an issue on our [GitHub repository](https://github.com/hao-ai-lab/FastVideo).

You can also join our [Slack community](https://join.slack.com/t/fastvideo/shared_invite/zt-38u6p1jqe-yDI1QJOCEnbtkLoaI5bjZQ) for additional support.
- VSA is unsupported on MPS: unset `FASTVIDEO_ATTENTION_BACKEND` or set it
to `TORCH_SDPA`.
- If your macOS/torch build rejects bf16 on MPS, pass
`--text-encoder-dtype fp16` (and `--vae-decode-dtype fp16` with the
`wan-vae` backend).
- Do not infer physical-16-GB support from allocator-cap experiments.
- Keep `mlx_dit/` beside the model's `transformer/`, `text_encoder/`,
`tokenizer/`, VAE, and scheduler files.
11 changes: 11 additions & 0 deletions docs/inference/support_matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ pipeline initialization and sampling.
| Matrix Game 3.0 Base Distilled | `FastVideo/Matrix-Game-3.0-Base-Distilled-Diffusers` | 720x1280 | ⭕ | ⭕ | ⭕ | ⭕ | ⭕ |
| GEN3C Cosmos 7B | `FastVideo/GEN3C-Cosmos-7B-Diffusers` | 704px1280p | ❌ | ❌ | ❌ | ⭕ | ⭕ |

## Apple Silicon native runtime

| Release path | Model | Mode | Validated hardware | Status |
| --- | --- | --- | --- | --- |
| MLX FastWan T2V | FastWan-QAD-INT8-1.3B `[release model ID pending]` | 480x832, 81 frames, 3-step DMD, INT8 DiT + TAEHV decode | Apple M4 Max, 36 GB unified-memory class, MLX 0.31.2 | Release candidate; requires release-owner visual sign-off |

This is a text-to-video-only source-install release. It is validated on the
hardware listed above; MLX allocator caps are not evidence of support for a
physical 16 GB Mac. See [Apple Silicon FastWan](../getting_started/installation/mps.md)
for the supported command and release gates.

**Note**: Wan2.2 TI2V 5B has some quality issues when performing I2V generation. We are working on fixing this issue.

***Lucy Edit Dev uses a non-commercial model license. FastVideo support is
Expand Down
Loading
Loading