Metal and CUDA setup

NCM-MLX uses MLX 0.32.3 on Apple Silicon through Metal and on NVIDIA GPUs through MLX's Linux CUDA backend. Training and evaluation have run on an Apple M5 Pro, NVIDIA RTX 3080 and NVIDIA A40. This is evidence for those configurations, rather than a claim that every supported MLX device has been tested. The experiment log records hardware with each result.

Python 3.11 or later is declared; the reproducible development environment pins Python 3.12.14. Ordinary Linux CI installs no MLX and tests the portable configuration, tokenizer, data, scoring, process-control and remote-runner components. GPU execution and CPU exactness tests require MLX and are skipped when it is absent. Windows and Intel Mac GPU execution are unsupported.

Apple Silicon and Metal

Use native ARM64 Python on macOS 14 or later. A Python process running through Rosetta is unsuitable. Install uv and clone the repository, then:

uv sync --locked --python 3.12
uv run python -m ncm_mlx smoke
uv run pytest -q

The platform marker installs MLX automatically on macOS ARM64. Alternatively, mise install && mise run setup selects the pinned Python version. mise run smoke and mise run test use that environment.

NVIDIA CUDA on Linux

The CUDA 12 backend needs an NVIDIA GPU with compute capability at least 7.5, driver at least 550.54.14 and a Linux distribution with glibc at least 2.35. The MLX installation guide documents upstream requirements. This repository pins CUDA runtime and CCCL headers to the 12.9 series to match the locked NVRTC runtime compiler.

uv sync --locked --python 3.12 --group cuda
scripts/check_gpu.sh
export CUDA_HOME="$PWD/.venv/cuda-home"
uv run python -m ncm_mlx smoke

scripts/check_gpu.sh checks the GPU, driver and glibc, installs the locked CUDA environment, assembles matching headers under .venv/cuda-home, runs the tests, and times short Sudoku training steps. Run it only on an idle host where this work is authorized; it is an accelerator workload, rather than a read-only health probe. scripts/run_experiment.sh discovers this header directory automatically. Direct CLI invocations need the CUDA_HOME export in each shell.

The cuda dependency group is opt-in because the NVIDIA libraries are large. uv sync --locked on Linux alone installs portable dependencies, without a GPU backend. pip install . has the same limitation on Linux; use the checked-out, locked CUDA workflow above. CUDA support does not imply binary compatibility with upstream PyTorch checkpoints or identical floating-point results across backends.

Portable development without a GPU

uv sync --locked --python 3.12
uv run ruff check .
uv run pytest -q
uv run python scripts/validate_repository.py
uv build

On Linux without the CUDA group these commands exercise the portable suite and packaging. Training, sampling, evaluation and benchmarking require an installed MLX GPU backend; the CLI checks that a GPU is selected. Exactness tests explicitly use MLX's CPU device, while GPU comparisons allow floating-point tolerance.

See reproducibility, benchmarks and remote execution for workloads and measurement conditions.