Home / Guides / Troubleshooting / Apple
macOS
Written by Jakub Rusinowski · Last updated September 1, 2026
AI educator & workshop leader on local LLM deployment
ERROR: Could not find a version that satisfies the requirement mlx (from versions: none)
ERROR: No matching distribution found for mlx
| If you see | The cause is | Go to |
|---|---|---|
platform.processor() prints i386 on an M-series Mac | You are running an x86 Python under Rosetta 2 | Fix 2: find and replace that Python |
| "No matching distribution found for mlx" | No arm64 wheel matches a non-native interpreter | Fix 1: run the processor check first |
| It installed and runs at roughly CPU speed | The interpreter is native but something else is off, or MLX is not the right tool here | Fix 5: confirm GPU use, then Fix 6 |
which -a python3 shows /usr/local/bin before /opt/homebrew/bin | An Intel Homebrew install is shadowing the arm64 one | Fix 2: /usr/local is Intel, /opt/homebrew is arm |
| A source build fails at CMake or on the SDK | Command Line Tools alone are not enough for a source build | Fix 4: full Xcode, SDK 14+, CMake 3.25+ |
Two different symptoms with one cause between them. Either pip flatly refuses to find a package that definitely exists, or it installs cleanly and then delivers none of the speed MLX is supposed to provide.
pip install mlx reports no matching distribution.MLX requires macOS 14.0 or newer, Apple silicon, and a native arm64 Python 3.10 or later. It publishes arm64 wheels only, because it is a Metal-backed framework and there is nothing meaningful to ship for x86. If your interpreter is an x86 build running under Rosetta 2, pip correctly reports that no distribution matches — the message is accurate and just does not say why. The whole diagnosis is one command: platform.processor() must print arm. On an M-series Mac it prints i386 when the interpreter is x86-under-Rosetta, and that single fact explains both the install failure and, in mixed environments, the performance disappointment.
One command tells you whether you have this problem. It must print arm. If it prints i386 on an M-series Mac, your Python is an x86 build running under Rosetta 2, and everything else follows from that. Nothing below is worth doing until this prints arm.
# zsh
python3 -c "import platform; print(platform.processor())"
# arm -> native, good
# i386 -> x86 Python under Rosetta, this is your problem
uname -m # arm64 on Apple Silicon
sw_vers # MLX needs macOS >= 14.0
python3 --version # MLX needs >= 3.10arm, uname -m prints arm64, macOS is 14 or newer, and Python is 3.10 or newer. All four must hold.python3 -c "import platform; print(platform.processor())"There is usually more than one interpreter on the machine and the wrong one is first on your PATH. which -a python3 lists them all in order; file reports each binary's architecture directly. The location is a strong hint on its own: /opt/homebrew is the arm64 Homebrew prefix and /usr/local is the Intel one, so a python3 resolving under /usr/local on an M-series Mac is almost certainly the culprit.
# zsh — every python3 on PATH, in order
which -a python3
# What architecture is the one you are getting?
file $(which python3)
# ... Mach-O 64-bit executable arm64 <- good
# ... Mach-O 64-bit executable x86_64 <- the problem
# Is your shell itself running under Rosetta?
archfile reports arm64 for the interpreter you are actually using, and arch prints arm64 for the shell.file $(which python3) && archA setting that is easy to forget and impossible to guess: in Finder, select Terminal or iTerm in /Applications/Utilities, press Command-I, and check whether "Open using Rosetta" is ticked. If it is, every process the terminal starts is x86, including a Python that is perfectly native when launched any other way. Untick it, quit the terminal completely, and reopen. People set this once for an old tool and forget it for years.
# zsh — if this prints i386, the shell itself is under Rosetta
arch
sysctl -n sysctl.proc_translated # 1 = running translatedarch prints arm64 and sysctl.proc_translated prints 0 in a freshly opened terminal.arch; sysctl -n sysctl.proc_translatedGet a native interpreter from one of three places: the python.org universal2 installer, Homebrew under /opt/homebrew, or miniforge, which is built for arm64 and is the easiest route if you use conda. Then recreate the virtual environment rather than reusing it — an existing venv records the interpreter that made it and will keep using the x86 one no matter which Python you have installed since. This is the step people skip, and it makes the fix appear not to work.
⚠️ Deleting and recreating a venv discards everything installed in it. Export your requirements first if you have not pinned them anywhere.
# zsh — arm64 Homebrew Python
/opt/homebrew/bin/brew install python@3.12
# Recreate the venv with the NATIVE interpreter — do not reuse the old one
pip freeze > /tmp/requirements.txt
deactivate 2>/dev/null; rm -rf .venv
/opt/homebrew/bin/python3.12 -m venv .venv
source .venv/bin/activate
python -c "import platform; print(platform.processor())" # must print: arm
pip install --upgrade pip
pip install mlx mlx-lmarm, and the install completes rather than reporting no matching distribution.python -c "import mlx.core as mx; print(mx.default_device())"An install that succeeded is not proof that work is landing on the GPU. mx.default_device() should report a GPU device. Run a short generation and watch Activity Monitor → Window → GPU History, or powermetrics with the GPU sampler, and you should see GPU activity rise for the duration. If the device is right and the GPU stays flat, the workload is not reaching Metal.
# zsh — what device does MLX think it has?
python -c "import mlx.core as mx; print(mx.default_device())"
# A short generation to watch
python -m mlx_lm.generate --model mlx-community/Llama-3.2-3B-Instruct-4bit \
--prompt "Write one sentence about the sea." --max-tokens 64
# In a second terminal, watch GPU power while it runs
sudo powermetrics --samplers gpu_power -i 1000 -n 10sudo powermetrics --samplers gpu_power -i 1000 -n 5 | grep -i "GPU Power"Readers arrive assuming MLX is strictly faster than llama.cpp on a Mac, and that is not reliably true across model families. MLX is a good fit when you want to fine-tune on the Mac, work in Python and NumPy-shaped code, or use a model published in MLX format by the community. llama.cpp and Ollama are the better default when you want the widest GGUF selection, a server, or simply the least setup. Benchmark the specific model you care about on both rather than assuming — and if a source build is what stands between you and MLX, note it needs Xcode 15+, macOS SDK 14+, Clang 15+ and CMake 3.25+, and that Command Line Tools alone are not sufficient.
# zsh — the source-build prerequisites, if you need one
xcodebuild -version # Xcode >= 15.0
xcrun --show-sdk-version # SDK >= 14.0
cmake --version # >= 3.25
clang --version # >= 15If MLX runs on the GPU and the Mac still struggles, the constraint is memory or heat rather than the framework. The swapping page covers what actually fits per memory tier; the throttling page covers speed that starts well and halves.
Include this when you report it
python3 -c "import platform; print(platform.processor())"which -a python3 and file $(which python3)sw_vers, python3 --version and archBecause MLX ships arm64 wheels only and your interpreter is not arm64. An x86 Python running under Rosetta 2 matches no distribution, so pip reports none exists. Run python -c "import platform; print(platform.processor())" — it must print arm.
That your Python is an x86 build running under Rosetta 2 on an Apple Silicon Mac. It usually comes from an Intel Homebrew under /usr/local, an Intel-built conda, or a terminal with "Open using Rosetta" ticked in Get Info.
Almost certainly because you reused an existing virtual environment. A venv records the interpreter that created it and keeps using it. Delete the venv and recreate it with the native Python, then check the processor inside the new environment.
macOS 14.0 or newer, Apple silicon, and a native arm64 Python 3.10 or newer. Building from source additionally needs Xcode 15+, macOS SDK 14+, Clang 15+ and CMake 3.25+ — Command Line Tools on their own are not enough for a source build.
Not reliably, and it varies by model family. MLX suits Python workflows, fine-tuning on the Mac, and models published in MLX format. llama.cpp and Ollama suit the widest GGUF selection and the least setup. Benchmark the model you actually use.