mirror of
https://github.com/mudler/LocalAI.git
synced 2026-09-12 22:33:54 -04:00
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>
103 lines
3.3 KiB
Python
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}")
|