Skip to content

[Roadmap] Apple Device Support (2026 Q2) #19137

Description

@jonahbernard

As of February 21, 2026 (date of initial creation of this roadmap), SGLang has no support for Apple Silicon.

We are excited to announce the initial roadmap for adding Apple Silicon support. We ask for contributors, of all levels of familiarity with SGLang and Apple devices, to pick up tasks on this roadmap and help us run SGLang on Apple Silicon (M-series).

Please comment below to pick up tasks that interest you, and we will assign them to you. Please join the mlx-backend Slack channel as well (via the SGLang Slack workspace).

Installation Instructions

Here are some quick instructions to set up SGLang on your Mac. Currently, SGLang must be built from source to work on your Mac.

Beware: the Mac version of SGLang is currently verified to work only with Python 3.11 and is known to have issues with other Python versions.

Beware 2: make sure the mlx and mlx-lm packages are installed with the LATEST version after you run uv pip install -e "python[all_mps]". They were only added as dependencies in this PR: #22162

# Install ffmpeg
brew install ffmpeg

# Install uv
brew install uv

# Clone the repository
git clone https://github.com/sgl-project/sglang.git
cd sglang

# Create and activate a virtual environment
uv venv -p 3.11 my-venv
source my-venv/bin/activate

# Install the Python packages
uv pip install --upgrade pip
rm -f python/pyproject.toml && mv python/pyproject_other.toml python/pyproject.toml
uv pip install -e "python[all_mps]"

Basic Server Launch Instructions

Once you have built SGLang from source using the above instructions, you can launch a basic server using this command:

SGLANG_USE_MLX=1 python -m sglang.launch_server \
  --model-path Qwen/Qwen3-0.6B \
  --port 43440

Now, send a request to that server via this curl command from another shell:

curl http://localhost:43440/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen/Qwen3-0.6B",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "Tell me a short joke."}
    ],
    "max_tokens": 10
  }'

Profiling Instructions

When contributing PRs, it is important to profile your changes to make sure they work as intended. There are 4 different ways to profile SGLang at 4 different levels of the stack.

| Tool                       | HTTP Server                                   | Scheduler                               | Use Case                                                                   |
| -------------------------- | --------------------------------------------- | --------------------------------------- | -------------------------------------------------------------------------- |
| `bench_serving`            | Yes (async HTTP client to a running server)   | Yes (indirectly, via server)            | Realistic online serving benchmarks with latency metrics (TTFT, TPOT, ITL) |
| `bench_one_batch_server`   | Yes (sends HTTP requests to a running server) | Yes (indirectly, via server)            | End-to-end single-batch latency including HTTP and scheduler overhead      |
| `bench_offline_throughput` | No                                            | Yes (directly uses `Engine` in-process) | Maximum throughput measurement without HTTP overhead                       |
| `bench_one_batch`          | No                                            | No (directly calls `ModelRunner`)       | Kernel-level latency profiling of a single static batch              

(taken from benchmark_and_profiling.md, read that for more comprehensive information)

Note: MLX and MLX-LM must be updated to the LATEST version to correctly profile the SGLang Apple Silicon backend. If MLX and MLX-LM are not updated, you may end up with very noisy traces.

There are two types of traces: Metal-only and system-wide.

Metal-only profiling

bench_one_batch.py directly runs the prefill and decode phases:

# this is a summary of the bench_one_batch.py file
start_profile
model_runner.extend(...)
stop_profile

start_profile
model_runner.decode(...)
stop_profile

Because bench_one_batch.py directly calls the extend and decode functions, it cannot be used to profile the server or scheduler.

To use bench_one_batch.py to profile on Apple Silicon and get a Metal-only trace, use this command:

SGLANG_TORCH_PROFILER_DIR=./profiler_output_baseline MTL_CAPTURE_ENABLED=1 SGLANG_USE_MLX=1 python -m sglang.bench_one_batch \
  --model-path Qwen/Qwen3-0.6B \
  --trust-remote-code \
  --disable-radix-cache \
  --disable-cuda-graph \
  --tp-size 1 \
  --batch-size 1 \
  --input-len 60 \
  --output-len 10 \
  --port 43440 \
  --profile \
  --profile-start-step 0 \
  --profile-steps 10

This saves a .gputrace file for prefill and a .gputrace file for decode. Double-click either .gputrace file, and it will automatically open in the XCode app.

To use bench_offline_throughput.py to profile the GPU operations on Apple Silicon and get a Metal-only trace, use this command:

SGLANG_TORCH_PROFILER_DIR=. SGLANG_USE_MLX=1 MTL_CAPTURE_ENABLED=1 python3 -m sglang.bench_offline_throughput \
    --model-path Qwen/Qwen2.5-0.5B-Instruct \
    --num-prompts 1 \
    --profile

To use bench_one_batch_server.py to profile the GPU operations on Apple Silicon and get a Metal-only trace, use this command:

SGLANG_TORCH_PROFILER_DIR=. SGLANG_USE_MLX=1 MTL_CAPTURE_ENABLED=1 python3 -m sglang.test.bench_one_batch_server_internal \
    --model Qwen/Qwen2.5-0.5B-Instruct \
    --batch-size 2 \
    --input-len 128 \
    --output-len 16 \
    --profile

To use bench_server.py to profile the GPU operations on Apple Silicon and get a Metal-only trace, use these TWO commands in different terminals:

SGLANG_TORCH_PROFILER_DIR=. SGLANG_USE_MLX=1 MTL_CAPTURE_ENABLED=1 python3 -m sglang.launch_server \
    --model-path Qwen/Qwen2.5-0.5B-Instruct \
    --port 30000
python3 -m sglang.bench_serving \
    --backend sglang \
    --port 30000 \
    --num-prompts 1 \
    --profile

System-wide profiling

To profile the entire system (CPUs, GPU, drivers, etc.), any Python process can be recorded by simply wrapping the process start command in xctrace record --template "Metal System Trace" --launch -- /usr/bin/env. Thus, for example, to profile the entire system during the execution of bench_one_batch.py, this command can be used:

xctrace record --template "Metal System Trace" --launch -- /usr/bin/env SGLANG_USE_MLX=1 $(which python) -m sglang.bench_one_batch \
  --model-path Qwen/Qwen3-0.6B \
  --trust-remote-code \
  --disable-radix-cache \
  --disable-cuda-graph \
  --tp-size 1 \
  --batch-size 1 \
  --input-len 60 \
  --output-len 10 \
  --port 43440 \

This saves a single .trace file that includes prefill and decode. Double-click the .trace file, and it will open in the Instruments app.

Initial Support (Proof-Of-Concept)

Implement Full MLX Backend

MLX runner-stub / framework contract redesign

The MLX backend integrates with the framework through MlxModelRunnerStub, which
re-implements the framework's implicit assumptions about ModelRunner. As SGLang
features and server arguments evolve, the stub silently drifts from framework
behavior — recent instances: #30181, #30389, #30547. Rather than continuing to
extend the stub per feature, re-evaluate the integration design for a more
fundamental solution.

  • Audit the framework↔stub contract: catalog assumptions the stub satisfies,
    misses, or silently diverges on — @noob-se7en
  • Design note with options + trade-offs for a long-term backend contract — @noob-se7en
  • Implementation + migration (following design review) — @noob-se7en

KV Cache

UMA Memory Management

Scheduler

Metal Kernels

To enable blazing fast inference, we need to write custom Metal kernels that are designed for inference instead of relying on MLX's general-purpose "fast" kernels.

Mixture-of-Experts

Model Support

We must rewrite all of the model architecture files in SGLang's main sglang/python/sglang/srt/models folder using the MLX library instead of PyTorch.

Please comment below if there is another model that you want to add support for and I will add it here with your name and PR.

Quantization

Speculative Decoding

Multi-LoRA Serving

We need to enable LoRA inference that is aligned with the method proposed in Punica: Multi-Tenant LoRA Serving. Our goal is to utilize as much of the current SGLang LoRA as possible.

  • TBD

Profiling

CI

Documentation

Bug Fixes & Bug Tracker

This roadmap will change rapidly as we work on the above tasks and encounter obstacles that require new tasks.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions