← TinyGPT · docs · devlog · roadmap · speedup
source: docs/sessions/2026-06-06-vllm-mlx-investigation.md · view on GitHub ↗

vllm-mlx Investigation

Date: 2026-06-06

Recommendation: partial-proceed. Do not wrap vllm-mlx into tinygpt serve yet. Keep native serve as the default and as the eval/logprob backend. Treat vllm-mlx as a production-chat candidate after an approved local install and benchmark pass.

Sources Checked

1. Maturity

The project is real and active enough to watch:

But it is not mature enough to become the default tinygpt serving backend:

Decision: do not default to it. If used, keep it opt-in and isolated from eval infrastructure.

2. Model Formats

vllm-mlx expects an MLX/HuggingFace-style model identifier or local model directory:

It does not load .tinygpt checkpoints directly.

TinyGPT already has tinygpt to-safetensors, but that currently writes a single model.safetensors with HF-Llama-ish names. That is not yet a complete MLX/HF model directory contract for vllm-mlx because serving needs compatible config.json, tokenizer files, and architecture expectations. TinyGPT’s from-scratch byte-level models also do not map cleanly to an upstream HF model family without a wrapper config.

Decision: a direct .tinygpt -> vllm-mlx adapter is not a small flag. The minimum honest bridge is:

  1. Export weights.
  2. Emit a compatible model directory (config.json, tokenizer, generation config, model.safetensors).
  3. Verify vllm-mlx serve <dir> loads it.

Until that exists, vllm-mlx can serve external MLX/HF models, not arbitrary TinyGPT checkpoints.

3. OpenAI Surface Parity

vllm-mlx documents:

That is good enough for production chat clients.

The critical eval question is logprobs + echo for lm-eval-harness/local-completions. This remains unproven. The server docs and CLI reference checked today document chat/completions and streaming, but do not document the exact completions echo: true plus logprobs behavior that TinyGPT’s native Serve.scoreLogprobs supports for eval scoring.

Decision: keep native serve as the eval backend. Even if vllm-mlx is adopted for production chat, eval code should continue to route through native serve until logprobs + echo is curl-verified.

4. Performance Reality Check

No local benchmark was run in this pass. Installing vllm-mlx and benchmarking it against a checkpoint would require Python package installation, model download/conversion, and sustained inference loops. The repo’s macOS safety rules require explicit approval before that class of workload.

Upstream benchmark data is still useful for triage:

Decision: performance upside is plausible, but not proven for TinyGPT. The next step is an approved local benchmark, not code integration.

Recommendation

Partial-proceed:

  1. Do not modify tinygpt serve yet.
  2. Keep native serve as the default and as the eval backend.
  3. Add a future integration only after a local benchmark answers:
    • Can vllm-mlx load a TinyGPT-exported model directory?
    • Does /v1/completions support echo + logprobs well enough for lm-eval-harness?
    • What are throughput, startup time, and memory deltas on the same Mac and same prompts?
  4. If the local run passes, implement --backend native|vllm-mlx as an explicit opt-in. Do not switch defaults until stability data exists.

Proposed Local Benchmark Plan

Run only with explicit approval:

uv tool install vllm-mlx
vllm-mlx --help

Then use a small external MLX model first:

vllm-mlx serve mlx-community/Qwen3-0.6B-8bit --port 8001 --continuous-batching
vllm-mlx bench-serve --url http://127.0.0.1:8001 --prompts short --concurrency 1,4 --max-tokens 64 --format json

Compare with native serve on an existing TinyGPT checkpoint using the same prompt set and max-token cap. Stop all spawned servers immediately after the run.