Skip to main content

mlx-serve

PyPI version Python versions License CI Platform

Local inference server for Apple Silicon that hot-swaps MLX models on demand — text, vision, embeddings, TTS, STT, and decision (Laya) — loading exactly one at a time to stay within unified memory limits.

Client / LiteLLM  -->  mlx-serve (port 8095)  -->  MLX model (one at a time)

Install

pip install mlx-serve[all]

# or pick only what you need:
pip install mlx-serve[text,vision]
pip install mlx-serve[embeddings,tts,stt]
pip install mlx-serve[decision]       # Laya typed decision models

Requires: Apple Silicon Mac (M1+), macOS 13+, Python 3.11+


Quick Start

# 1. Generate a default config
mlx-serve init

# 2. Edit models.yaml to list your models (see docs/configuration.md)

# 3. Start the server
mlx-serve start

# 4. Verify
curl http://localhost:8095/v1/models

Why mlx-serve?

mlx-serve Ollama LM Studio mlx-openai-server
Runtime MLX (native Apple) llama.cpp (Metal) Mixed MLX
Memory model One model, subprocess-isolated One model, in-process GUI-managed In-process
Auto-unload Configurable timeout Yes Manual No
Model types 6 (text, vision, embed, TTS, STT, decision) 1 (text) ~2 ~3
API OpenAI-compatible OpenAI-compatible OpenAI-compatible OpenAI-compatible
Headless / scriptable Yes Yes No (GUI) Yes
Open source MIT MIT No MIT

Key differences:

  • vs Ollama — Ollama uses llama.cpp. mlx-serve uses Apple's native MLX framework, which typically achieves better throughput and memory efficiency on Apple Silicon. mlx-serve is what Ollama would be if it were built natively on MLX.
  • vs LM Studio — Closed source, requires a GUI, cannot be embedded in headless pipelines.
  • vs mlx-openai-server — Runs all models in-process, causing memory fragmentation over long sessions. mlx-serve isolates text/vision models as subprocesses so the OS reclaims all memory cleanly on unload.
  • vs Docker — MLX requires direct Metal GPU access. Docker on Mac runs a Linux VM without Metal. The correct topology: stateless services in Docker, mlx-serve on the Mac host via host.docker.internal.

Features

  • Hot-swap by model name — send a request to any configured model; the server loads it and unloads the previous one automatically
  • OpenAI-compatible API — drop-in with LiteLLM, any OpenAI SDK, or direct HTTP
  • All six MLX model types — text (mlx-lm), vision (mlx-vlm), embeddings (mlx-embeddings), TTS (mlx-audio), STT (mlx-whisper), decision (laya_mlx)
  • Subprocess isolation — text/vision models run as isolated subprocesses; embeddings/TTS/STT run in-process
  • Auto-unload on inactivity — configurable timeout (default 10 min) frees memory when idle
  • Per-request keep_alive — override the idle timeout per request ("keep_alive": "30m", "-1" for permanent, 0 to unload immediately)
  • Prompt caching — max_kv_cache_size per model caps KV cache token capacity for efficient prefix reuse
  • Model management API — preload, force-unload, delete from disk, show detail, pull from HuggingFace
  • Observability — request metrics (TTFT, TPS, latency), memory monitoring, lifecycle event log, dashboard endpoint
  • Optional auth — set MLX_API_KEY to protect all /v1/* endpoints
  • YAML config — add models by editing models.yaml, no code changes needed
  • CLI — mlx-serve init, start, stop, status, logs

Supported Model Types

Type Backend Endpoint Capabilities
text mlx_lm.server subprocess /v1/chat/completions ["completion"]
vision mlx_vlm.server subprocess /v1/chat/completions ["completion", "vision"]
embedding mlx-embeddings in-process /v1/embeddings ["embedding"]
tts mlx-audio in-process /v1/audio/speech ["audio_speech"]
stt mlx-whisper in-process /v1/audio/transcriptions ["audio_transcription"]
decision laya_mlx in-process /v1/systemone ["decision"]

Usage

Chat completion

curl http://localhost:8095/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mlx-qwen2.5-7b",
    "messages": [{"role": "user", "content": "What is Apple Silicon?"}]
  }'

Streaming

curl http://localhost:8095/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mlx-qwen2.5-7b",
    "messages": [{"role": "user", "content": "Count to 5"}],
    "stream": true
  }'

Embeddings

curl http://localhost:8095/v1/embeddings \
  -H "Content-Type: application/json" \
  -d '{"model": "mlx-qwen3-embedding", "input": "Hello world"}'

Text-to-speech

curl http://localhost:8095/v1/audio/speech \
  -H "Content-Type: application/json" \
  -d '{"model": "mlx-chatterbox", "input": "Hello from Apple Silicon."}' \
  --output speech.wav

Speech-to-text

curl http://localhost:8095/v1/audio/transcriptions \
  -F "file=@recording.wav" \
  -F "model=mlx-whisper-turbo"

Typed decisions (Laya)

curl http://localhost:8095/v1/systemone \
  -H "Content-Type: application/json" \
  -d '{
    "model": "laya-en",
    "state": "I was billed twice. Please refund the duplicate.",
    "questions": {
      "department": {
        "type": "choice",
        "instructions": "Which department should handle this?",
        "criteria": ["billing", "technical", "sales"]
      },
      "urgent": {
        "type": "noul",
        "instructions": "Is this urgent?"
      }
    }
  }'

Returns typed answers with probabilities — no token-by-token decoding, no streaming.


LiteLLM Integration

mlx-serve is designed to sit behind LiteLLM in a Docker-on-Mac stack.

# litellm/config.yaml
model_list:
  - model_name: mlx-qwen2.5-7b
    litellm_params:
      model: openai/mlx-qwen2.5-7b
      api_base: http://host.docker.internal:8095/v1
      api_key: none

  - model_name: mlx-qwen3-embedding
    litellm_params:
      model: openai/mlx-qwen3-embedding
      api_base: http://host.docker.internal:8095/v1
      api_key: none

Development

git clone https://github.com/raspoli/mlx-serve.git
cd mlx-serve
make install    # uv sync with all extras
make dev        # start with auto-reload
make test       # run test suite
make lint       # ruff check + format check

See docs/development.md for the full guide.


Documentation

Document Contents
docs/architecture.md System design, module map, state machines, request flows
docs/configuration.md models.yaml complete reference, all settings
docs/api.md All endpoints, request/response schemas, curl examples
docs/development.md Setup, debugging, adding models, contributing

License

MIT

Metadata

Release files for mlx-serve 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mlx-serve 0.3.0
File Size Uploaded
mlx_serve-0.3.0.tar.gz 277.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mlx-serve 0.3.0
File Interpreter ABI Platform
mlx_serve-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 312.1 kB

Release files / mlx_serve-0.3.0.tar.gz

Download URL mlx_serve-0.3.0.tar.gz
Size 277.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0b2280c5c7fea87cc84df302425ebca4242ca281cc29b53e85ecc5b745c2660d
BLAKE2b-256 checksum
How to use checksums
56c2a0dad4e71f2e4f5b4f7f42a5b4bfecc544ddf9567afd4a303faf6fde7b8a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / mlx_serve-0.3.0-py3-none-any.whl

Download URL mlx_serve-0.3.0-py3-none-any.whl
Size 35.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ce6476cc2f373de64f9ec0eaf8262d8f5c2e1fa3d354a6eb24e32802e07b87a3
BLAKE2b-256 checksum
How to use checksums
6c2314de87452210ad86be5466bbde05edc0f7a5de2bb3d43dc63d6a1e1483a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page