fix(setup): install mlx-lm and mlx-audio in setup-python on Apple Silicon (#892)

* fix(setup): install mlx-lm and mlx-audio in setup-python on Apple Silicon

The dev setup installed requirements-mlx.txt but not mlx-audio/mlx-lm
themselves, so POST /transcribe failed on a fresh Apple Silicon setup
with "No module named 'mlx_audio'" (then "No module named 'mlx_lm'").
The release workflow already installs both with --no-deps (they declare
transformers>=5.x, conflicting with our <=4.57.x cap); mirror that in
the setup-python recipe with the same pins.

Co-Authored-By: Claude Fable 5 <[email protected]>

* test: add MLX smoke test for the --no-deps mlx-audio/mlx-lm install

mlx-audio and mlx-lm are installed --no-deps, so a missing transitive
dependency only surfaces at import time. Add a pytest-discoverable
smoke test (skipped off Apple Silicon) covering the exact entry points
the backend uses: mlx_audio.tts.load, mlx_audio.stt.load (which also
exercises the miniaudio dep from issue #505), mlx_lm.load/generate,
and a basic mlx.core op.

Co-Authored-By: Claude Fable 5 <[email protected]>

---------

Co-authored-by: Claude Fable 5 <[email protected]>
This commit is contained in:
Gregoire Moreels
2026-07-20 22:27:01 -07:00
committed by Jamie Pine
co-authored by Claude Fable 5
parent 7d4844fb10
commit cc9c905b55
3 changed files with 63 additions and 1 deletions
+2 -1
View File
@@ -16,7 +16,8 @@ miniaudio>=1.59
# mlx_audio.stt.load) works fine on transformers 4.57.x in practice.
#
# Install it via `pip install --no-deps mlx-audio==0.4.1` after this file
# (see .github/workflows/release.yml). Most other mlx-audio runtime deps
# (see .github/workflows/release.yml and the setup-python recipe in the
# justfile). Most other mlx-audio runtime deps
# (huggingface_hub, librosa, mlx-lm, numba, numpy, protobuf, pyloudnorm,
# sounddevice, tqdm) are already in requirements.txt or pulled in by
# other engines.
+55
View File
@@ -0,0 +1,55 @@
"""
Smoke test for the MLX backend dependencies on Apple Silicon.
Guards the `--no-deps` install of mlx-audio/mlx-lm done by `just setup-python`
and release.yml: those packages skip their declared dependencies (transformers
>=5.x conflict), so a missing transitive dep only surfaces at import time.
This test fails fast if the MLX STT/TTS entry points the backend uses stop
importing (e.g. the `miniaudio` regression from issue #505).
Usage:
python -m pytest backend/tests/test_mlx_smoke.py -v
"""
import platform
import sys
import pytest
pytestmark = pytest.mark.skipif(
not (sys.platform == "darwin" and platform.machine() == "arm64"),
reason="MLX packages are only installed on Apple Silicon macOS",
)
def test_mlx_core_runs():
"""The MLX runtime itself works (Metal array op)."""
import mlx.core as mx
assert mx.array([1, 2]).sum().item() == 3
def test_mlx_audio_tts_entry_point():
"""`from mlx_audio.tts import load` — used by MLXBackend.load_model_async."""
from mlx_audio.tts import load
assert callable(load)
def test_mlx_audio_stt_entry_point():
"""`from mlx_audio.stt import load` — used by the Whisper MLX STT path.
Importing mlx_audio.stt also pulls in miniaudio, so this catches the
ModuleNotFoundError from issue #505 on fresh installs.
"""
from mlx_audio.stt import load
assert callable(load)
def test_mlx_lm_entry_points():
"""`mlx_lm.load` / `mlx_lm.generate` — used by qwen_llm_backend."""
from mlx_lm import generate, load
assert callable(load)
assert callable(generate)
+6
View File
@@ -72,6 +72,12 @@ setup-python:
if [ "$(uname -m)" = "arm64" ] && [ "$(uname)" = "Darwin" ]; then
echo "Detected Apple Silicon — installing MLX dependencies..."
{{ pip }} install -r {{ backend_dir }}/requirements-mlx.txt
# mlx-lm and mlx-audio declare transformers>=5.x, which conflicts with
# our transformers<=4.57.x cap, so install them --no-deps (their other
# runtime deps are covered by requirements.txt / requirements-mlx.txt —
# see the note in requirements-mlx.txt and .github/workflows/release.yml)
{{ pip }} install --no-deps mlx-lm==0.31.1
{{ pip }} install --no-deps mlx-audio==0.4.1
fi
{{ pip }} install git+https://github.com/QwenLM/Qwen3-TTS.git
{{ pip }} install pyinstaller ruff pytest pytest-asyncio -q