Files
Ettore Di Giacinto 21df4a120a feat(mlx): add Apple Silicon video backend
Add a Darwin-only MLX-Video backend for LTX-2 and converted Wan checkpoints, expose it through the existing video API, and wire packaging, discovery, tests, docs, and an example.

Assisted-by: Codex:gpt-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-09-11 21:52:41 +00:00

103 lines
3.3 KiB
Python

# SPDX-License-Identifier: MIT
import os
import sys
def parse_options(options):
parsed = {}
for option in options:
key, separator, value = option.partition(":")
parsed[key] = value if separator else "true"
return parsed
def classify_model(model):
normalized = model.rstrip("/").lower()
name = os.path.basename(normalized)
if "ltx-2" in normalized or "ltx2" in normalized:
return "ltx2"
if "wan2" in name or "wan_2" in name:
return "wan"
return None
def _append(command, flag, value):
if value is not None and value != "":
command.extend([flag, str(value)])
def build_generation_command(
*,
family,
model,
prompt,
destination,
negative_prompt="",
start_image="",
end_image="",
audio="",
width=0,
height=0,
num_frames=0,
fps=0,
seed=0,
steps=0,
cfg_scale=0,
params=None,
):
params = params or {}
if audio:
raise ValueError("audio conditioning is not supported by mlx-video")
if family == "ltx2":
command = [sys.executable, "-m", "mlx_video.models.ltx_2.generate"]
_append(command, "--model-repo", model)
_append(command, "--prompt", prompt)
_append(command, "--output-path", destination)
_append(command, "--negative-prompt", negative_prompt)
_append(command, "--image", start_image)
_append(command, "--end-image", end_image)
_append(command, "--width", width or None)
_append(command, "--height", height or None)
_append(command, "--num-frames", num_frames or None)
_append(command, "--fps", fps or None)
_append(command, "--seed", seed if seed > 0 else None)
_append(command, "--steps", steps or None)
_append(command, "--cfg-scale", cfg_scale or None)
for key, flag in {
"pipeline": "--pipeline",
"tiling": "--tiling",
"image_strength": "--image-strength",
"end_image_strength": "--end-image-strength",
"text_encoder_repo": "--text-encoder-repo",
}.items():
_append(command, flag, params.get(key))
return command
if family == "wan":
if end_image:
raise ValueError("Wan models do not support end_image conditioning")
command = [sys.executable, "-m", "mlx_video.models.wan_2.generate"]
_append(command, "--model-dir", model)
_append(command, "--prompt", prompt)
_append(command, "--output-path", destination)
_append(command, "--negative-prompt", negative_prompt)
_append(command, "--image", start_image)
_append(command, "--width", width or None)
_append(command, "--height", height or None)
_append(command, "--num-frames", num_frames or None)
_append(command, "--seed", seed if seed > 0 else None)
_append(command, "--steps", steps or None)
_append(command, "--guide-scale", cfg_scale or None)
for key, flag in {
"scheduler": "--scheduler",
"shift": "--shift",
"tiling": "--tiling",
"trim_first_frames": "--trim-first-frames",
}.items():
_append(command, flag, params.get(key))
return command
raise ValueError(f"unsupported mlx-video model family: {family}")