CLI Reference¶
mlxcel exposes nineteen subcommands. run and generate produce model output; generate-image renders images; embed creates dense or multi-vector representations; rerank scores query-document pairs; detect finds objects; predict writes dense maps and keypoints; tag and extract run fixed-label token classification and request-time span extraction; inspect sizes memory before loading; serve starts the HTTP server; list, arch, download, and rm manage or inspect model availability; tune profiles and caches kernel launch configurations; split-mtp writes a standalone MTP drafter out of a raw GLM-4.7-Flash checkpoint; and prepare-external-ple and prepare-expert-stream build the on-disk structures that qwen4_exp reads outside its MLX parameters. generate has the gen alias; list has the ls alias; arch has the supported alias.
Table of Contents¶
- Environment Variables
- mlxcel run
- mlxcel generate
- Model Options
- Generation Options
- KV Cache Options
- Sampling Options
- Prompt Lookup Options
- Diffusion Options
- Pipeline Parallel Options
- Tensor Parallel Options
- Model Surgery Options
- Language Bias Options
- Examples
- mlxcel inspect
- mlxcel detect
- mlxcel predict
- mlxcel generate-image
- mlxcel embed
- mlxcel rerank
- mlxcel tag
- mlxcel extract
- mlxcel serve
- Network and Auth
- Concurrency and Batching
- Embedding and Reranking Workers
- Speculative Decoding
- Endpoint Toggles
- Model Resolution and Store
- Router Mode
- WebUI
- LoRA Adapters
- Structured Output Defaults
- Default Sampling Parameters
- Distributed Inference
- Examples
- mlxcel list
- mlxcel arch
- mlxcel download
- mlxcel rm
- mlxcel tune
- mlxcel split-mtp
- mlxcel prepare-external-ple
- mlxcel prepare-expert-stream
Environment Variables¶
These variables are read at startup before any flags are processed.
| Variable | Default | Description |
|---|---|---|
MLXCEL_DEVICE | gpu | Runtime device. Valid values: gpu, metal, cpu. |
MLXCEL_WIRED_LIMIT | max GPU memory | GPU wired memory limit. Unset or max pins up to the GPU maximum; 0 or none sets no limit; a value like 96GB sets an explicit limit (supports GB, MB, or raw bytes). |
MLXCEL_MEMORY_LIMIT | - | Soft allocator memory cap. Nonzero values are used as the available-memory budget by mlxcel inspect, --estimate-memory, and MLX runtime setup. |
MLXCEL_HEADROOM_FACTOR | 1.20 | Allocator-overhead multiplier on weights + KV used by the unified memory estimator. The activation reserve (MLXCEL_ACTIVATION_MULT) is a separate term it does not scale. Positive values <= 1.0 disable the headroom term; invalid or non-positive values warn and fall back to the default. |
MLXCEL_CACHE_DIR | $HOME/.cache/mlxcel | Root for the default model store ($MLXCEL_CACHE_DIR/models/<owner>/<name>) and other mlxcel disk caches. |
MLXCEL_MODELS_DIR | - | Override the model-store root directly. Repo-id downloads and lookups use $MLXCEL_MODELS_DIR/<owner>/<name> with no extra models/ component. Overridden by --models-dir. |
MLXCEL_DEFAULT_ORG | mlx-community | Default HuggingFace owner used when a model argument has no slash, for example Qwen3-4B-4bit -> mlx-community/Qwen3-4B-4bit. |
MLXCEL_WEIGHT_MATERIALIZATION | eager | eager reads and uploads a generation model's checkpoint tensors before Model loaded is reported; lazy materializes each tensor on first use. See Performance Tuning. |
MLXCEL_EXTRA_CA_CERTS | - | PEM bundle of extra CAs trusted for model downloads and remote media fetches, on top of the operating system trust store. |
MLXCEL_SURGERY | - | Default YAML file for runtime model surgery when --surgery is not provided. Applies to generate and serve. |
Setting MLXCEL_WIRED_LIMIT=max can improve throughput for large models but risks out-of-memory conditions if the model and working tensors together exceed physical memory.
mlxcel run¶
Runs a model with an ollama-style positional model argument. Without -p/--prompt, it opens the interactive multi-turn chat REPL. With -p, it performs one generation and exits. When the model argument is omitted, it uses the default mlx-community/gemma-4-e2b-it-4bit.
MODEL_OR_REPO_ID accepts the same resolver inputs as generate -m: an existing local path, a HuggingFace owner/name repo-id, or a bare name resolved as ${MLXCEL_DEFAULT_ORG:-mlx-community}/<name>. Repo-id misses are downloaded into the mlxcel model store and reused from any directory.
| Flag / Argument | Default | Description |
|---|---|---|
[MODEL_OR_REPO_ID] | mlx-community/gemma-4-e2b-it-4bit | Local path, HuggingFace repo-id, or bare model name. |
--models-dir <PATH> | MLXCEL_MODELS_DIR / cache root | Override the model-store root for repo-id resolution and auto-downloads. |
--revision <REV> | main | Repository branch, tag, or commit used for repo-id resolution. |
--adapter <PATH> | - | Path to a LoRA adapter directory. |
-p, --prompt <TEXT> | - | One-shot prompt. If omitted, open the interactive REPL. |
--draft-model <PATH_OR_REPO_ID> | - | Speculative drafter checkpoint, a path or an owner/name repo id resolved like -m: a DFlash drafter, an MTP head, or an ordinary smaller model that drafts on its own KV caches. Served through the server's speculative dispatch the same way mlxcel serve --draft-model serves it. |
--draft-kind <dflash\|mtp\|full-model> | auto | Drafter kind when the checkpoint does not declare one: gemma4_assistant, gemma4_unified_assistant, and qwen3_5_mtp are mtp, a DFlash-family directory is dflash, and any other readable model directory is full-model. Also read from LLAMA_ARG_DRAFT_KIND / MLXCEL_DRAFT_KIND. |
--draft-block-size <N> | resolved at startup | Speculative block size, resolved the same way as on the server. |
Examples:
# Interactive chat, auto-downloading on first use.
mlxcel run Qwen3.5-0.8B-4bit
# One-shot generation.
mlxcel run Qwen3.5-0.8B-4bit -p "Hello" -n 100
# Override the default owner used by bare names.
MLXCEL_DEFAULT_ORG=my-org mlxcel run My-Model-4bit
How run executes¶
run and its REPL are clients of the mlxcel-server model worker, started inside the same process with one slot (--parallel 1, --max-batch-size 1) and no HTTP listener. Each turn goes through the /v1/chat/completions request path, which renders the chat template, splits reasoning from content, parses tool calls, and applies stop strings. For the same request, mlxcel run -p and mlxcel-server produce the same tokens; under MLXCEL_SDPA_DETERMINISTIC=1, run -p --temp 0 and the server give identical greedy output. See Token-exactness between the CLI and the server.
run -p prints only the reply (not the prompt), followed by a [Generated N tokens ...] summary line and, when a drafter is active, a [Speculative ...] acceptance line. The prompt cache is off for run -p and on for the REPL, where each conversation carries its own prompt_cache_key so a follow-up turn prefills only the new messages.
Checkpoints that ship no chat template are rendered with the server's generic chat format, and run prints a notice that the checkpoint is likely a base model. --no-chat-template sends the raw text through the /v1/completions path instead.
A few one-shot modes that the chat server does not serve run on the generate flow instead: block-diffusion, Florence-2, Nemotron-Parse, and Nemotron VoiceChat checkpoints, and the --output-audio, --layout-detections, --audio, --video, --profile, --estimate-memory, and --recommend-quant flags. --no-chat-template combined with --image also stays on generate. --image otherwise goes through the server like a chat client's image_url part.
Flag groups on run¶
run accepts the generate generation, media, KV cache, diffusion, and sampling options, plus the server sampling options below and the speculative flags in the table above. It does not take the pipeline-parallel, tensor-parallel, language-bias, model-surgery, or prompt-lookup groups. Use mlxcel run --help as the exhaustive flag list.
Each sampling flag maps onto the mlxcel-server option of the same name. A flag left unset keeps the server default, with one exception: the base sampler stays greedy unless the checkpoint's generation_config.json sets a temperature. --repeat-last-n and --dry-penalty-last-n are forwarded only when given, so an unset run uses the server's 64-token windows (inert unless a penalty is active), while generate uses -1 (full history).
| Server Sampling Option | Default | Description |
|---|---|---|
--frequency-penalty <N> | 0.0 | Frequency penalty. 0.0 disables it. |
--presence-penalty <N> | 0.0 | Presence penalty. 0.0 disables it. |
--xtc-probability <N> | 0.0 | XTC removal probability. 0.0 disables XTC. |
--xtc-threshold <N> | server default | XTC probability threshold. Values above 0.5 make XTC inert. |
--mirostat <N> | 0 | 0 disabled, 1 Mirostat, 2 Mirostat 2.0. |
--mirostat-lr <N> | server default | Mirostat learning rate (eta). |
--mirostat-ent <N> | server default | Mirostat target entropy (tau). |
--dynatemp-range <N> | 0.0 | Dynamic temperature range. 0.0 disables it. |
--dynatemp-exp <N> | server default | Dynamic temperature exponent. |
--dry-sequence-breaker <STRING> | "\n", ":", "\"", "*" | Comma-separated DRY sequence breakers. none sets no breakers. |
--stop <STRING> | - | Stop generating when the reply produces this string. Repeatable; sent as the request's stop field. |
Interactive commands¶
| Input | Effect |
|---|---|
/bye | Exit the chat. |
/clear | Start a new conversation. The transcript is emptied and the next turn uses a new prompt_cache_key, so nothing cached for the old conversation is adopted again. |
/image <path> | Attach an image to the next message (vision models). |
/?, /help | Show the command list. |
""" ... """ | Send a multiline block as one message. |
| Ctrl-C | While a reply streams, cancel that reply and return to the prompt; the interrupted exchange is dropped from the transcript. A second Ctrl-C while the reply is still stopping quits. At the prompt, Ctrl-C cancels the current line. |
The whole transcript, images included, is sent again on every turn. /image and --image therefore refuse an image that would push the conversation over the server's per-request image cap (16 by default); /clear resets the count. In raw mode (--no-chat-template) turns carry no media: the REPL refuses /image and ignores --image with a notice.
mlxcel generate¶
mlxcel generate [OPTIONS] --model <PATH_OR_REPO_ID> [--prompt <TEXT>]
mlxcel gen [OPTIONS] --model <PATH_OR_REPO_ID> [--prompt <TEXT>] # alias
Loads a model, applies a prompt when provided, streams generated tokens to stdout, and prints a summary line. When --prompt is omitted, generate drops into the same interactive multi-turn REPL used by mlxcel run.
generate -p is the raw-completion client. It decodes on the engine's direct client (mlxcel_core::engine::DirectEngine) with the same sampler, finish step, and B=1 lookahead pipeline as the server's single-sequence row; MLXCEL_FORCE_SYNC disables that pipeline. Chat prompts are rendered from the checkpoint's template the way the server renders them. Under --profile, the [TTFT] line reports sample=0 because the sampler build is counted inside eval.
Model Options¶
| Flag | Default | Description |
|---|---|---|
-m, --model <PATH_OR_REPO_ID> | required | Existing local model directory, HuggingFace owner/name repo-id, or bare model name. Repo-id misses are auto-downloaded into the mlxcel store. |
--models-dir <PATH> | MLXCEL_MODELS_DIR / cache root | Override the model-store root used for repo-id lookup and auto-download. No effect when --model is already an existing local path. |
--revision <REV> | main | Repository revision (branch, tag, or commit hash) used when -m/--model is a repo-id. The mlxcel store is not revision-namespaced, so a repo already present there is refused rather than answered with an unknown revision; give each revision its own --models-dir. Not valid when -m/--model is an existing local path. |
--adapter <PATH> | - | Path to a LoRA adapter directory. See LoRA Adapters. |
--surgery <FILE> | MLXCEL_SURGERY | YAML file for load-time model surgery. See Runtime Model Surgery. |
--draft-model <PATH_OR_REPO_ID> | - | Drafter checkpoint, a path or an owner/name repo id resolved like -m. Drives the MTP round loop for an MTP drafter, the DFlash round loop for a Laguna DFlash drafter on a Laguna target, or the token-only full-model loop for an ordinary smaller checkpoint. Conflicts with --prompt-lookup. See Speculative Decoding. |
--draft-kind <dflash\|mtp\|full-model> | auto / none | Drafter kind. Unset auto-detects from the drafter directory: mtp for gemma4_assistant, gemma4_unified_assistant, and qwen3_5_mtp, dflash for a DFlash-family directory, and full-model for any other readable model directory. mtp drives the offline MTP round loop for supported Gemma 4/Unified, Qwen 3.5/Qwen3.8-family, and GLM-4.7-Flash (glm4_moe_lite) pairs on text-only prompts; a non-MTP target or a multimodal request returns a clear error. dflash runs offline only for a Laguna target with its Laguna DFlash drafter, greedy only, behind the same exactness probe the server uses; other DFlash pairings run on the server. full-model runs an ordinary smaller checkpoint that shares the target's tokenizer and drafts from its own KV caches; it is refused for a target or drafter a trim cannot roll back, for a draft vocabulary larger than the target's, and for a DFlash directory. prompt-lookup is not accepted here; the parse error points to --prompt-lookup. |
--draft-block-size <N> | resolved at startup | MTP, DFlash, or full-model block size for the offline round loops, resolved the same way as on the server (4 for mtp and full-model, 16 for dflash when nothing narrower is declared or measured). |
Draft model loop
An ordinary causal-LM drafter runs as a full-model drafter on the engine's token-only verify loop, the same loop prompt lookup uses, so --draft-block-size is the one width knob for every drafter kind. mlxcel generate has no --num-draft-tokens flag.
Generation Options¶
| Flag | Default | Description |
|---|---|---|
-p, --prompt <TEXT> | - | The input prompt. Chat template formatting is applied automatically unless --no-chat-template is set. If omitted, enter the interactive REPL. |
--image <PATH>... | - | One or more image file paths for vision-language models. Accepts multiple paths separated by spaces. |
--image-soft-tokens <N> | checkpoint setting, typically 280 | Gemma 4 only. Per-image vision budget: 70, 140, 280, 560, or 1120. Larger values retain a denser patch grid and consume more context. |
--layout-detections <PATH> | - | Falcon-OCR only. Region detections in the JSON shape emitted by mlxcel detect --format json; each textual region is cropped and OCRed in list order. This path ignores --prompt. |
--audio <PATH> | - | Audio file path for audio-capable models (for example Gemma 4 with an audio tower). gemma4_unified checkpoints also accept it together with --video. Nemotron VoiceChat checkpoints require it: the WAV is the user's side of the duplex timeline and -p is the system prompt. |
--video <PATH>... | - | One or more video file paths. Families with a native video path (Gemma 4, Gemma 4 Unified, Inkling, Kimi-VL, and the Qwen-VL families) consume the clip through their own temporal processor; every other checkpoint with a vision tower receives the sampled frames as ordered images. gemma4_unified also accepts --video together with --audio. Requires ffmpeg on PATH. |
--fps <FLOAT> | 2.0 | Target sampling FPS for --video frame extraction. |
--video-max-frames <N> | 16 (MLXCEL_VIDEO_MAX_FRAMES) | Frames kept when --video is sent as ordered images because the checkpoint has no native video path. The clip is decoded at --fps and evenly subsampled to this count, always keeping the first and last frame. Values below 2 are raised to 2. Native video families ignore it. See Video on a model with no native video path. |
--output-audio <PATH> | - | Write synthesized speech as mono PCM16 WAV. Qwen3-Omni: after text-only generation, lazily load the talker and code2wav stack and write 24 kHz audio; cannot be combined with image, input audio, or video. Nemotron VoiceChat: write 22.05 kHz assistant speech for the whole --audio timeline. |
--extra-decoding-seconds <SECONDS> | 3.0 | Nemotron VoiceChat only. Seconds of silence appended to the --audio input so the model can finish answering after the user stops speaking. |
--stream | false | Nemotron VoiceChat only. Drive the cache-aware online session in 80 ms frames instead of the offline timeline, printing text and transcript deltas as each frame produces them. With --profile, print per-stage latency and the real-time factor. |
--max-streaming-seconds <SECONDS> | - | Nemotron VoiceChat --stream only. Stop with an error once the session has consumed this many seconds of audio. |
--speaker <NAME> | ethan | Qwen3-Omni talker voice: ethan, chelsie, or aiden. |
-n, --max-tokens <N> | -1 | Maximum tokens. -1 continues until EOS or the remaining context window is full. |
--profile | false | Enable profiling mode. Prints prompt/generated token counts, prefill timing, and decode timing instead of only the brief summary line. |
--no-chat-template | false | Skip automatic chat template application. The prompt is passed to the tokenizer verbatim. Useful when you have already formatted the prompt yourself. |
--show-reasoning | false | Print the reasoning channel for capable checkpoints. Reasoning is suppressed by default and raw channel markers are never printed. |
--recommend-quant | false | Print a hardware-aware quantization recommendation for the selected model, including M5 Neural Accelerator notes. |
--estimate-memory | false | Run the unified memory preflight before model load. Aborts when estimated total memory exceeds the available budget. |
--force, --no-memory-check | false | Downgrade an over-budget --estimate-memory result to a warning and continue. No effect unless --estimate-memory is set. |
KV Cache Options¶
| Flag | Default | Description |
|---|---|---|
--cache-type-k <TYPE>, --cache-type-v <TYPE> | fp16 | Independent K/V modes: fp16, int8, fp16+turbo4, fp16+turbo3, turbo4, or turbo4-delegated. If only one side is given, the other stays fp16. These flags override --kv-cache-mode. |
--kv-cache-mode <MODE> | fp16 | Legacy shorthand that sets both sides. Prefer the split flags. |
--turbo-boundary-v <COUNT> | MLXCEL_KV_BOUNDARY_V_LAYERS / 2 | Keep the first and last COUNT V layers in FP16 under Turbo modes. The count is clamped to half the layer count. |
See TurboQuant KV Cache for compatibility and quality guidance.
Sampling Options¶
These flags control how the next token is chosen from the model's probability distribution.
| Flag | Default | Description |
|---|---|---|
-t, --temp <FLOAT> | 0.0 | Sampling temperature. 0.0 selects the highest-probability token (greedy decoding). Higher values increase randomness. |
--top-p <FLOAT> | 1.0 | Nucleus sampling threshold. Tokens whose cumulative probability exceeds this value are excluded. 1.0 disables nucleus sampling. |
--top-k <K> | 0 | Top-K sampling limit. Only the K most likely tokens are considered. 0 disables top-K, and a value at or above the vocabulary size behaves like 0. |
--min-p <FLOAT> | 0.0 | Min-P threshold. Tokens with probability below min_p * max_token_prob are excluded. 0.0 disables min-P. |
--repetition-penalty <FLOAT> | 1.0 | Repetition penalty multiplier applied to tokens that have already appeared. 1.0 means no penalty; values above 1.0 discourage repetition. |
--dry-multiplier <FLOAT> | 0.0 | DRY (Don't Repeat Yourself) penalty multiplier. 0.0 disables DRY. |
--dry-base <FLOAT> | 1.75 | Exponential base for DRY penalty scaling. |
--dry-allowed-length <N> | 2 | Minimum match length before the DRY penalty applies. |
--dry-penalty-last-n <N> | -1 | DRY lookback window in tokens. -1 uses the full generation history; 0 disables DRY. |
--seed <N> | unset (nondeterministic) | Seed for MLX's global RNG. Makes sampled generation reproducible, including the random canvas noise of block-diffusion models. |
--repeat-last-n <N> | -1 | Lookback window in tokens for the repetition penalty. -1 uses the full generation history; 0 disables the window. |
--top-n-sigma <FLOAT>, --top-nsigma <FLOAT> | 0.0 | Top-n-sigma logit filter: keeps only tokens whose raw logit lies within N standard deviations of the row maximum. 0.0 disables it. Stable at high temperature and invariant to the temperature value itself. |
--typical-p <FLOAT>, --typical <FLOAT> | 1.0 | Locally typical sampling: keeps tokens whose surprisal is closest to the row entropy until P probability mass accumulates. 1.0 disables it. |
--p-less | false | Hyperparameter-free p-less truncation: keep tokens whose probability under the temperature-scaled distribution is at least sum(p^2). The most likely token always survives, and greedy requests skip the filter. Also accepted by mlxcel run. |
Prompt Lookup Options¶
Prompt lookup is drafter-free n-gram speculation: each round proposes the tokens that followed an earlier occurrence of the sequence's last few tokens and verifies them in one target forward. It pays off on replies that copy the prompt (edits, rewrites, reformatting); on other replies the proposals are shortened or paused so decoding stays near plain speed. Acceptance is sampler-match, which is lossless for a one-hot proposal; greedy output can differ from plain decoding only at logit near-ties. See Speculative Decoding for the server form (--draft-kind prompt-lookup).
| Flag | Default | Description |
|---|---|---|
--prompt-lookup | false | Enable prompt-lookup speculation. Conflicts with --draft-model. |
--prompt-lookup-ngram-max <N> | 3 | Longest suffix n-gram matched against the context. At most 16. |
--prompt-lookup-ngram-min <N> | 2 | Shortest suffix n-gram matched against the context. |
--prompt-lookup-max-draft <N> | 7 | Maximum tokens proposed per round; the verify block is one wider (8 by default). At most 64. |
--prompt-lookup-no-adaptive | false | Propose the maximum every round instead of shortening or pausing proposals that stop landing (for A/B measurement). |
--prompt-lookup-policy <auto\|graded\|gated> | auto | How proposals are shortened and resumed. graded follows recent acceptance and probes again after a short pause (tuned on Apple Silicon); gated uses narrow or full blocks and resumes only after a looked-up proposal comes true unverified (tuned on CUDA); auto selects gated on CUDA builds and graded elsewhere. |
The tuning flags require --prompt-lookup. mlxcel generate --draft-kind prompt-lookup is a parse error that points to --prompt-lookup. A --prompt-lookup run is refused for interactive chat (no -p), image, audio, or video input, pipeline parallelism, and target models whose state a cache trim cannot roll back: recurrent and hybrid models, and models that own their attention caches (Qwen 3.5, Gemma 3 and 4, Llama 4). The first run warms every verify width before the timed generation. On a GB10, edit-style replies measured 1.10x to 1.94x faster than plain decoding, while free prose stays at about 0.98x to 1.00x with the gated policy.
Diffusion Options¶
These flags control block-diffusion generation and only affect diffusion models such as DiffusionGemma; autoregressive models ignore them. See Block Diffusion for the generation mechanism and tuning guidance.
| Flag | Default | Description |
|---|---|---|
--max-denoising-steps <N> | checkpoint generation_config (typically 48) | Maximum denoising iterations per canvas block. Lower values trade quality for speed. |
--diffusion-sampler <entropy-bound\|confidence-threshold> | entropy-bound | Per-step token acceptance strategy. |
--diffusion-threshold <FLOAT> | 0.9 | Confidence threshold for the confidence-threshold sampler. |
--diffusion-min-canvas-length <N> | 64 | Shortest canvas allocated for the generation tail. |
--diffusion-max-canvas-length <N> | model canvas_length (typically 256) | Cap on the per-block canvas length. |
--diffusion-full-canvas | false | Always allocate the model's full canvas_length per block. |
Pipeline Parallel Options¶
These flags enable the in-process pipeline path for mlxcel generate.
| Flag | Default | Description |
|---|---|---|
--pp-size <N> | 1 | Number of pipeline stages. Values <= 1 keep the standard single-model path. |
--pp-layers <RANGES> | - | Manual stage partition, for example 0-15,16-31. When omitted, the model-aware partitioner chooses stage ranges for the requested stage count. |
--pp-micro-batch-size <N> | 1 | Number of micro-batches to run through the in-process worker loop. |
Current CLI pipeline notes:
- The path is available to the stage-executor families listed in Pipeline Parallelism, not only Llama.
- It is text-only and does not support speculative decoding or VLM inputs. One load-time adapter can be fused stage-locally on the current Llama stage executor; other families fail explicitly.
- In-process CLI PP×TP composition is supported for eligible dense runtimes, but TP×LoRA is not. Remote pipeline serving has stricter limits and currently rejects adapters and TP composition.
Tensor Parallel Options¶
These flags enable the current in-process tensor-parallel runtime for supported dense text model families.
| Flag | Default | Description |
|---|---|---|
--tp-size <N> | 1 | Number of tensor-parallel ranks. Must be a power of two. Values > 1 shard supported dense text models across in-process ranks. |
--tp-moe-mode <MODE> | expert_parallel | MoE expert sharding mode: expert_parallel or within_expert. Current production TP support is focused on dense runtimes. |
--tp-embedding-mode <MODE> | replicated | Embedding sharding mode. Current runtime requires replicated. |
--tp-lm-head-mode <MODE> | replicated | LM head sharding mode. Current runtime requires replicated. |
Supported tp_size > 1 families are dense Llama, Qwen2/2.5, Qwen3, Qwen3.5 text, Gemma 3 text, Gemma 4 text, ERNIE 4.5, and Hunyuan v1 Dense. LoRA adapters are not supported with TP.
Model Surgery Options¶
Runtime model surgery applies a YAML-defined weight transform while the checkpoint is loaded. Use it when you need temporary, reproducible weight adjustments without editing the model files on disk. See Runtime Model Surgery for the operation schema and limitations.
| Flag | Default | Description |
|---|---|---|
--surgery <FILE> | MLXCEL_SURGERY | Apply a load-time surgery pipeline. Operations run in YAML order and loading fails if a rule cannot be applied safely. |
Language Bias Options¶
mlxcel generate and both server entry points expose language-bias controls for suppressing or encouraging scripts at sampling time. See Language Bias for operational guidance.
| Flag | Default | Description |
|---|---|---|
--lang-bias <ENTRIES> | - | Comma-separated entries such as ja=-inf,zh=-10,ko=+5.0. |
--lang-bias-config <PATH> | - | YAML configuration file for language bias. CLI values take precedence. |
--lang-bias-policy <POLICY> | conservative | Token inclusion policy: conservative or strict. |
--lang-bias-include-special | false | Include special tokens in language sets. |
--lang-bias-include-numeric | false | Include numeric tokens in language sets. |
--lang-bias-include-punctuation | false | Include punctuation-only tokens in language sets. |
--lang-bias-include-byte-fragments | false | Include byte-fragment tokens using the UTF-8 start-byte classifier. |
--lang-bias-rebuild-cache | false | Rebuild the tokenizer script cache before running. |
Generate Examples¶
Basic text generation with greedy decoding:
# Bare name resolves to mlx-community/Qwen2.5-7B-Instruct-4bit.
mlxcel generate \
--model Qwen2.5-7B-Instruct-4bit \
--prompt "Explain the difference between a mutex and a semaphore." \
--max-tokens 300
Interactive chat from generate:
Gemma 4 with a larger vision-token budget:
mlxcel generate -m ./models/gemma-4-e2b-it-4bit \
--image page.png --image-soft-tokens 560 \
-p "Read the small text in this page."
Falcon-OCR region-wise OCR:
mlxcel detect -m ./models/docling-layout -i page.png --format json > regions.json
mlxcel generate -m ./models/falcon-ocr --image page.png --layout-detections regions.json
Qwen3-Omni speech output:
mlxcel generate -m ./models/qwen3-omni \
-p "Give a short welcome." --output-audio welcome.wav --speaker chelsie
Creative writing with higher temperature and nucleus sampling:
mlxcel generate \
--model ./models/Llama-3.1-8B-Instruct \
--prompt "Write the opening paragraph of a science fiction novel." \
--max-tokens 200 \
--temp 0.8 \
--top-p 0.95
Using a LoRA adapter:
mlxcel generate \
--model ./models/Mistral-7B-v0.3 \
--adapter ./adapters/mistral-sql-lora \
--prompt "Write a SQL query to find the top 10 customers by revenue." \
--max-tokens 150
Applying runtime model surgery:
mlxcel generate \
--model ./models/Qwen2.5-7B-Instruct \
--surgery ./surgery.yaml \
--prompt "Summarize the deployment checklist." \
--max-tokens 150
Vision-language model with an image:
mlxcel generate \
--model ./models/Qwen2.5-VL-7B-Instruct \
--image ./photos/diagram.png \
--prompt "Describe what you see in this image." \
--max-tokens 200
Gemma 4 video input:
mlxcel generate \
--model ./models/gemma-4-vl \
--video ./demo.mp4 \
--fps 2.0 \
--prompt "Summarize the visible events in this clip." \
--max-tokens 200
Video decoding uses ffmpeg; install it and ensure it is on PATH before using --video.
Multiple images are supported by repeating the --image flag:
mlxcel generate \
--model ./models/Qwen2.5-VL-7B-Instruct \
--image ./before.png --image ./after.png \
--prompt "What changed between these two images?" \
--max-tokens 200
Full-model speculation (an ordinary smaller checkpoint as the drafter):
mlxcel generate \
--model ./models/Llama-3.1-70B-4bit \
--draft-model ./models/Llama-3.2-1B \
--draft-kind full-model \
--prompt "Summarize the key ideas in the Rust ownership model." \
--max-tokens 400
--draft-kind full-model runs a smaller checkpoint that shares the target's tokenizer from its own KV caches, and the engine's token-only verify loop decides every position. Any readable model directory that is neither MTP nor DFlash is auto-detected as full-model. --draft-kind dflash runs offline only for a Laguna target paired with its Laguna DFlash drafter; the Qwen 3.5, LFM2 DSpark, and Muse Glimmer DFlash pairings run in server mode. --draft-kind mtp is supported for qualified Gemma 4/Unified, Qwen 3.5/Qwen3.8-family, and GLM-4.7-Flash text-only pairs.
Known issue: temperature 0 output
At temperature 0, a block verification path (--prompt-lookup or a full-model draft model) can leave the plain-decode token stream, so its output is not guaranteed to match a run without speculation (#2778). The root cause is not known. Compare against a plain run before relying on byte-identical output.
Prompt-lookup speculation for an edit-style request (no drafter):
mlxcel generate \
--model mlx-community/Qwen3-1.7B-4bit \
--prompt-lookup \
--prompt "Fix the typos in this paragraph and return it unchanged otherwise: ..." \
--max-tokens 400
Nemotron VoiceChat offline turn (speech in, speech out):
mlxcel generate -m models/NemotronLabs-VoiceChat-11B-4bit \
--audio question.wav --output-audio response.wav \
-p "Be concise and answer in one sentence."
This prints [user] <transcript>, the assistant text, and [function] <text> when the function channel produced any, and writes response.wav (22050 Hz mono PCM16). -n is ignored because the output length equals the input timeline, --seed (default 0 for this family) makes the speech reproducible, and --image and --video are rejected. Add --stream --profile to run the online session and print per-stage latency and the real-time factor. Interactive generate without --audio refuses the checkpoint. See Nemotron VoiceChat Realtime API for the server form.
Memory preflight before loading a model:
mlxcel generate \
--model ./models/Qwen2.5-7B-Instruct \
--prompt "Summarize the deployment plan." \
--max-tokens 1024 \
--estimate-memory
The preflight uses the rendered prompt token count plus --max-tokens, then compares exact weights, KV cache, and runtime headroom against available memory. See Memory Estimation for details and override guidance.
Profiling mode to measure performance:
mlxcel generate \
--model ./models/Gemma-3-4B-Instruct \
--prompt "What is photosynthesis?" \
--max-tokens 200 \
--profile
Output with --profile includes a breakdown of timing steps:
[Profile Results]
Prompt tokens: 12
Generated tokens: 148
Prefill: 84.3 ms (142.3 tok/s)
Decode: 3241.7 ms (45.6 tok/s)
Without --profile, a brief summary is printed:
Disabling the chat template for raw prompt injection:
mlxcel generate \
--model ./models/Qwen2.5-7B-Instruct \
--prompt "<|im_start|>user\nHello<|im_end|>\n<|im_start|>assistant\n" \
--no-chat-template \
--max-tokens 50
Single-machine pipeline generate on a supported text model:
mlxcel generate \
--model ./models/llama-3.2-1b-4bit \
--prompt "Hello" \
--max-tokens 64 \
--temp 0 \
--no-chat-template \
--pp-size 2
mlxcel inspect¶
Prints a pre-load memory breakdown for a model and exits without loading it. The output includes weights, KV cache, runtime headroom, total bytes, available bytes, and whether the configuration is expected to fit. This is the same estimator used by --estimate-memory and --recommend-quant; see Memory Estimation.
| Flag | Default | Description |
|---|---|---|
-m, --model <PATH_OR_REPO_ID> | required | Existing local model directory, HuggingFace owner/name repo-id, or bare model name. Repo-id misses are auto-downloaded into the mlxcel store before inspection. |
--models-dir <PATH> | MLXCEL_MODELS_DIR / cache root | Override the model-store root for resolution/download. |
--revision <REV> | main | Repository branch, tag, or commit for repo-id inspection. |
-n, --max-tokens <N> | 8192 | Context length used for the KV-cache estimate. |
--batch <N> | 1 | Batch size used for the KV-cache estimate. Use this to model concurrent server slots. |
--quant <default\|fp16\|int8\|int4> | default | Label the intended weight mode in the output. The weight total still comes from the checkpoint metadata. |
--json | disabled | Emit one JSON object with raw byte fields instead of the text banner. Cache hits write only JSON to stdout; resolution or estimator errors still go to stderr and exit nonzero. |
--kv-cache-mode <MODE> | fp16 | Legacy shorthand for K/V cache mode. int8 halves the KV-cache byte width in the estimate. |
--cache-type-k <TYPE> / --cache-type-v <TYPE> | fp16 | Split K/V cache mode flags shared with generate and server mode. These take precedence over --kv-cache-mode. |
--turbo-boundary-v <COUNT> | MLXCEL_KV_BOUNDARY_V_LAYERS / 2 | Boundary V layers retained at higher precision for Turbo cache estimates. |
Examples:
mlxcel inspect -m ./models/Qwen2.5-7B-Instruct-4bit
mlxcel inspect -m ./models/Qwen2.5-7B-Instruct-4bit --max-tokens 32768
mlxcel inspect -m ./models/Qwen2.5-7B-Instruct-4bit --batch 4 --kv-cache-mode int8
mlxcel inspect --json -m mlx-community/Qwen3-4B-4bit | python3 -m json.tool
The JSON form is intended for recipe builders and schedulers that need hardware-fit inputs. It reports mlxcel_version, model, model_type, family, inputs, weights_bytes, weights_source, kv_bytes_per_token, kv_bytes_total, kv_detail, per_slot_overhead_bytes, activation_bytes, backend_inflight_bytes (non-zero only on ROCm builds, where it is part of headroom_bytes), headroom_bytes, headroom_factor, budget_bytes, total_bytes, and fits. Values the estimator cannot supply are null, not guessed.
mlxcel detect¶
Runs object detection on an image and prints bounding boxes in original-image pixel coordinates. Detection models output boxes (l, t, r, b) with a class label and confidence rather than a token stream, so this is a separate command from generate/serve.
The command loads RT-DETRv2, PP-DocLayoutV3, YOLO11, or RF-DETR checkpoints from a directory containing config.json and model.safetensors. Pre-converted MLX checkpoints (e.g. mlx-community/docling-layout-heron-mlx-bf16) and raw HuggingFace checkpoints are accepted; HF weights are translated to MLX layout at load time.
| Flag | Default | Description |
|---|---|---|
-m, --model <PATH> | required | Detection model directory. |
-i, --image <PATH> | required | Path to the input image (PNG, JPEG, etc.). |
-t, --threshold <FLOAT> | detector default | Confidence threshold in [0, 1]; detections below it are dropped. The default is 0.3 for RT-DETRv2 and PP-DocLayoutV3, 0.5 for RF-DETR, and 0.05 for YOLO11. |
--size <PIXELS> | native resolution | Longest side before inference. YOLO11 only; detectors with a fixed input size ignore it with a warning. |
--iou <FLOAT> | 0.1 | NMS IoU threshold in [0, 1]. YOLO11 only, at most 300 boxes. |
--masks-dir <DIR> | unset | Write one binary instance-mask PNG per detection. RF-DETR segmentation checkpoints only. |
--format <text\|json> | text | Output format. text prints an aligned table; json prints a machine-readable object. |
Class names are resolved from the checkpoint's config.json::id2label, or from config.json's class list for YOLO11; when absent, the numeric class id is shown. PP-DocLayoutV3 detections also carry the model's global reading order.
Examples:
# Document-layout detection on a page image (17-class docling model).
mlxcel detect -m ./models/docling-layout-heron-mlx-bf16 -i page.png
# Higher threshold, JSON output for downstream tooling.
mlxcel detect -m ./models/rt-detr-v2 -i photo.jpg --threshold 0.5 --format json
# OmniParser v2 icon detection with a longest-side resize.
mlxcel detect -m axiom-of-choice/OmniParser-v2-icon-detect -i ui.png --size 1280 --format json
JSON output schema:
{
"image": "page.png",
"threshold": 0.3,
"detections": [
{ "label": "section_header", "label_id": 7, "confidence": 0.89,
"box": { "l": 390.3, "t": 21.7, "r": 738.5, "b": 41.4 } }
]
}
mlxcel predict¶
Writes dense task outputs for checkpoints that return more than boxes: depth, surface normals, segmentation, point maps, keypoints, per-instance masks, meshes, and Gaussian splats. Every run writes result.safetensors and meta.json into the output directory, plus task-specific files such as keypoints.json, depth.png, normal.png, segmentation.png, instances.json, and masks/.
# Image-encoder features from DINOv2.
mlxcel predict -m ./models/dinov2-small -i input.png -o features --task features
# Pose from Sapiens2 with an explicit box.
mlxcel predict -m ./models/sapiens2-pose -i person.png -o pose \
--opts '{"boxes":[[140,90,920,700]],"flip_test":true}'
# Depth over a video.
mlxcel predict -m ./models/video-depth -v clip.mp4 -o depth --max-frames 32
Exactly one of --image and --video is required, and --output is required. --task may be omitted when the selected family declares a default for that input. --prompt repeats, --boxes accepts pixel x1,y1,x2,y2 boxes (repeat the flag or separate boxes with ;), --mask and --pointmap supply SAM 3D Objects inputs, --max-frames and --target-fps control video sampling, and --opts carries model-specific options as a JSON object.
The supported families, their tasks, and the output contract are in Dense Prediction and Vision Tasks.
mlxcel generate-image¶
Generates an image from a prompt, or edits one or more reference images, with a diffusion checkpoint in Diffusers layout. The seed is always printed; with -n greater than one, image i uses seed seed + i (except FLUX.2 generation, which draws one noise batch) and is written as <stem>-01.png, <stem>-02.png, and so on.
mlxcel generate-image -m ./models/flux2-klein -p "a watercolor fox"
mlxcel generate-image -m ./models/flux2-klein -p "a fox" --size 768x512 --seed 7 -n 2 -o fox.png
mlxcel generate-image -m ./models/flux2-klein --task edit --image fox.png -p "make it night"
Key flags: --task generate|edit (default generate), --image (repeatable, required for edit and rejected for generate), --size WxH (default 512x512), --negative-prompt, --steps, --guidance, --seed, -n (1 to 10), -o/--output (default outputs/image-<seed>.png), and --gen-kwargs for model-specific options as JSON.
The families, their defaults, and the /v1/images routes are in Image Generation.
mlxcel tag¶
Runs a fixed-label BIO or BIOES token classifier over the text and prints the tagged spans with Unicode character offsets plus a redacted copy. - as the text argument reads it from stdin. --argmax forces per-token decoding on a checkpoint that defaults to a constrained Viterbi decoder, --replacement sets the redaction string, --keep lists labels that stay in the redacted text, and --operating-point selects a calibration point on a Viterbi-decoded checkpoint.
mlxcel tag -m nativ-community/rampart-mlx-fp16 --keep CITY,STATE,ZIP_CODE \
"I'm Sarah Connor, 1984 Cyberdyne Ave, Los Angeles CA 90012, sarah@sky.net"
mlxcel extract¶
mlxcel extract -m <PATH_OR_REPO_ID> (--labels <L1,L2> | --labels-json <JSON> | --classify <JSON>) <TEXT>
Extracts spans for labels chosen per request from a span-extraction checkpoint, or classifies the text. --include-confidence and --include-spans add each span's score and offsets; --threshold (default 0.5) sets the minimum entity score and the default multi-label threshold; --max-len and --word-splitter whitespace|char apply to GLiNER2.5.
mlxcel extract -m fastino/gliner2.5-small-v1 --labels company,person,location \
--include-confidence --include-spans "Apple hired Sam in New York."
Both commands, their supported families, and their output shapes are in Token Classification and Span Extraction.
mlxcel embed¶
Loads an embedding checkpoint and prints one vector per input. With two or more inputs, it also prints a cosine-similarity matrix for dense vectors or a MaxSim matrix for late-interaction vectors. The command uses the same detector, loader, pooling, normalization, length limits, and micro-batching as the server.
| Flag | Default | Description |
|---|---|---|
-m, --model <MODEL_OR_REPO_ID> | required | Local checkpoint, HuggingFace repo-id, or resolvable bare name. |
-p, --prompt <TEXT> | - | Text to embed; repeat for several inputs. A whitespace-only prompt is refused, as rerank -d refuses a whitespace-only document. |
--image <FILE> | - | Image input for a supported multimodal embedder; repeat as needed. |
--instruction <TEXT> | - | Family-specific query instruction. |
--dimensions <N> | native width | Keep the first N components and normalize again when enabled. |
--pooling <mean\|cls\|last> | checkpoint/family | Override dense pooling. |
--embd-normalize <N> | checkpoint | -1 none, 0 max-absolute int16, 1 L1, 2 L2, p > 2 p-norm. |
--max-length <N> | derived | Lower the checkpoint-derived token limit. |
--batch-size <N> | 16 | Text inputs per forward pass. |
--models-dir <PATH> | model-store root | Override repo-id resolution. |
--json | false | Print one object with embeddings, shapes, token count, and similarities. |
mlxcel embed -m nomic-ai/modernbert-embed-base \
-p "search_query: What is vector search?" \
-p "search_document: Vector search retrieves nearby embeddings."
mlxcel rerank¶
Scores every document against one query, then prints request-order scores and the final ranking. It supports cross-encoder, Qwen3 generative, and Qwen3-VL multimodal rerankers.
| Flag | Default | Description |
|---|---|---|
-m, --model <MODEL_OR_REPO_ID> | required | Reranker checkpoint. |
-q, --query <TEXT> | - | Query text. An image-only query can use --query-image. |
-d, --document <TEXT> | - | Candidate document; repeat for several. |
--query-image <FILE> | - | Image attached to the query for a multimodal reranker. |
--image <FILE> | - | Image candidate; repeat as needed and receive results after text documents. |
--instruction <TEXT> | kind default | Task instruction for generative rerankers; classifiers reject it. |
--top-n <N> | all | Print only the highest-ranked N documents in the ranking. |
--max-length <N> | derived | Lower the per-pair token limit. |
--batch-size <N> | kind default | Pairs per forward pass. |
--models-dir <PATH> | model-store root | Override repo-id resolution. |
--json | false | Print scores, ranking, kind, and token count as one object. |
mlxcel rerank -m BAAI/bge-reranker-v2-m3 \
-q "What is vector search?" \
-d "Vector search retrieves nearby embeddings." \
-d "A compiler translates source code." \
--top-n 1
See Embeddings and Reranking for prefixes, model families, and scoring semantics.
mlxcel serve¶
Starts a persistent HTTP server compatible with the OpenAI API and llama.cpp server API. The server loads the model once and keeps it resident in memory, handling multiple requests through continuous batching.
Several flags accept environment variables for deployment scenarios where command-line arguments are inconvenient.
Network and Auth¶
| Flag | Env | Default | Description |
|---|---|---|---|
-m, --model <PATH_OR_REPO_ID> | LLAMA_ARG_MODEL | required outside router mode | Existing local model directory, HuggingFace owner/name repo-id, or bare model name resolved through MLXCEL_DEFAULT_ORG. Omit it with --models-dir, --models-preset, or --webui to start the router without a model. |
--models-dir <PATH> | LLAMA_ARG_MODELS_DIR | disabled | Directory of models the router discovers and serves. Cannot be combined with a model argument; to set the model-store root use --model-store-root or MLXCEL_MODELS_DIR. |
--revision <REV> | - | main | Repository revision (branch, tag, or commit hash) used when -m/--model is a repo-id. Resolves the HuggingFace cache snapshot for that revision and fetches it on a miss. The mlxcel store is not revision-namespaced, so a repo already present there is refused rather than answered with an unknown revision; give each revision its own --models-dir. Not valid when -m/--model is an existing local path. |
--adapter <PATH>, --lora <PATH> | - | - | Load one or more LoRA adapter directories with the served model, as a comma-separated list. Adapters stay unfused with a live scale unless --lora-fuse is set. --lora is the llama-server-compatible alias. See LoRA Adapters. |
--surgery <FILE> | MLXCEL_SURGERY | - | YAML file for load-time model surgery. See Runtime Model Surgery. |
--host <ADDR> | LLAMA_ARG_HOST | 127.0.0.1 | Host address to bind to. Use 0.0.0.0 to accept connections from all interfaces. A value ending in .sock is served as a Unix domain socket at that path. |
--port <N> | LLAMA_ARG_PORT | 8080 | TCP port to listen on. 0 binds an ephemeral port chosen by the kernel. Ignored when --host ends in .sock. |
--api-key <KEY> | LLAMA_API_KEY | - | API key for bearer token authentication. When set, all endpoints except /health and / require Authorization: Bearer <KEY>. |
--api-key-file <PATH> | - | - | Path to a file containing the API key. Mutually exclusive with --api-key; the file contents are trimmed of whitespace. |
--allowed-origins <ORIGINS> | MLXCEL_ALLOWED_ORIGINS | permissive | Comma-separated exact CORS origins. Unset reflects any origin; set this on browser-reachable production listeners. |
-a, --alias <NAME> | LLAMA_ARG_ALIAS | - | Model alias returned in API responses instead of the directory name. |
--api-prefix <PATH> | LLAMA_ARG_API_PREFIX | "" | Prefix path the server serves from, without the trailing slash. --api-prefix /llama moves every route under /llama, so /v1/chat/completions becomes /llama/v1/chat/completions. Matching llama-server b10621, the public health endpoints are recognized by their unprefixed paths, so /llama/health requires authentication when an API key is configured. Values containing { or } are refused. |
--cors-origins <LIST> | LLAMA_ARG_CORS_ORIGINS | * | Allowed CORS origins, emitted verbatim as Access-Control-Allow-Origin, except * (which echoes the request Origin while --cors-credentials is on) and localhost (which echoes only for localhost, 127.0.0.1, or ::1). For per-origin matching against a list use the mlxcel-native --allowed-origins; the two are mutually exclusive. |
--cors-headers <LIST> | LLAMA_ARG_CORS_HEADERS | * | Comma-separated allowed headers, sent as Access-Control-Allow-Headers on a preflight. |
--cors-methods <LIST> | LLAMA_ARG_CORS_METHODS | GET,POST,OPTIONS | Comma-separated allowed methods, sent as Access-Control-Allow-Methods on a preflight. |
--cors-credentials / --no-cors-credentials | LLAMA_ARG_CORS_CREDENTIALS | enabled | Allow credentials for CORS. With this on and --cors-origins *, the Origin header is echoed back and credentials are always allowed, matching llama-server b10621. |
--ssl-cert-file <PATH> | LLAMA_ARG_SSL_CERT_FILE | - | PEM-encoded certificate. Serves HTTPS instead of HTTP; must be given with --ssl-key-file. |
--ssl-key-file <PATH> | LLAMA_ARG_SSL_KEY_FILE | - | PEM-encoded private key; must be given with --ssl-cert-file. |
--threads-http <N> | LLAMA_ARG_THREADS_HTTP | -1 | Sizes the Tokio runtime's HTTP worker threads. -1 uses llama-server b10621's formula, max(--parallel + 4, cores - 1). |
--reuse-port | LLAMA_ARG_REUSE_PORT | off | Allow multiple sockets to bind the same port (SO_REUSEPORT). |
--sse-ping-interval <SECS> | LLAMA_ARG_SSE_PING_INTERVAL | 30 | Interval between SSE comment pings emitted while a stream stays silent, which is what keeps a reverse proxy from dropping a long prefill. -1 disables. |
Concurrency and Batching¶
| Flag | Env | Default | Description |
|---|---|---|---|
--n-parallel <N>, --parallel <N> | LLAMA_ARG_N_PARALLEL | 4 | Number of parallel request slots. This is the baseline for --max-batch-size when that flag is not set explicitly and the default divisor for an explicit --ctx-size. |
--max-batch-size <N> | - | n_parallel | Maximum number of sequences in the active decode batch. Increasing this value allows more concurrent decode steps but uses more memory; when set, it divides an explicit --ctx-size. |
--max-queue-depth <N> | - | 32 | Maximum number of requests waiting in the prefill queue. When the queue is full the server returns HTTP 503. |
--prefill-chunk-size <N> | MLXCEL_PREFILL_CHUNK | 2048 with no live decode, 512 with one | Tokens per prefill chunk. Long prompts are split into chunks of this size; decode steps are interleaved between chunks to avoid latency spikes for active sequences. When unset, the chunk is 2048 while no other sequence is decoding and 512 while a decode batch is live. An explicit value (from this flag, -b, or MLXCEL_PREFILL_CHUNK) pins both states. Set to 0 to disable chunking. |
--prefill-grant-interval <N> | MLXCEL_PREFILL_GRANT_INTERVAL | 16 | Decode ticks a parked prefill yields before one guaranteed prefill tick. Lower values improve TTFT at the cost of decode ITL; 0 disables the grant. |
-b, --batch-size <N> | LLAMA_ARG_BATCH | 2048 with no live decode, 512 with one | llama-server alias for --prefill-chunk-size; an explicit value pins both states. When both flags are provided with different values, --prefill-chunk-size takes precedence and a warning is logged. |
--ubatch-size <N> | LLAMA_ARG_UBATCH | - | llama-server physical micro-batch setting. Ignored on Apple Silicon unified memory. |
--max-batch-prefill <N> | - | 4 | Maximum number of queued requests to combine into a single batched prefill pass. |
--max-batch-prefill-tokens <N> | MLXCEL_MAX_BATCH_PREFILL_TOKENS | derived | Caps padded tokens in one batched prefill to bound the quadratic FP32 mask. When unset it is 2 * max_batch_prefill * min(prefill_chunk_size, 512) (4096 at the defaults). 0 disables the cap. |
--enable-preemption | - | false | Allow preemptive eviction of lower-priority sequences when the batch is full. |
--preemption-policy <POLICY> | - | longest-first | Controls which sequence is evicted when preemption fires. longest-first evicts the sequence with the most generated tokens; lowest-priority evicts the lowest-priority sequence. |
--no-batch | - | false | Disable the batch scheduler entirely and use a legacy sequential worker. Requests are processed one at a time in FIFO order and keep the full explicit --ctx-size. |
--ctx-size <N> | LLAMA_ARG_CTX_SIZE | 0 | Context budget. 0 uses the model's default context length; an explicit value is shared across active slots. |
-n, --n-predict <N>, --predict <N> | LLAMA_ARG_N_PREDICT | -1 | Default maximum tokens to generate per request when it omits max_tokens. --predict is a compatibility alias. Follows llama.cpp: -1 resolves to the effective per-slot context window (the divided --ctx-size when set, otherwise the model's max_position_embeddings), falling back to 4096 only when neither is available. A non-negative value is taken verbatim. |
--timeout <SECS> | LLAMA_ARG_TIMEOUT | 3600 | HTTP socket read/write timeout in seconds, matching llama-server b10621. It bounds how long one socket read or write may block and does not cancel a slow generation; use --decode-timeout for that. |
--decode-timeout <SECS> | MLXCEL_DECODE_TIMEOUT | 600 | Per-request decode watchdog: cancels a request whose generation stops producing tokens. Setting --timeout without this logs a migration warning at startup. 0 falls back to the built-in 300-second guard with a warning. |
--max-kv-size <N> | LLAMA_ARG_MAX_KV_SIZE | 0 | Cap plain, non-sliding KV caches to N tokens per sequence. 0 leaves them unbounded. Sliding-window models keep their model-specific window. |
--decode-storage-backend <auto\|dense\|paged> | MLXCEL_SERVER_DECODE_STORAGE | auto | Select the continuous-batching decode storage backend. |
--kv-cache-budget <BYTES\|auto\|none> | MLXCEL_KV_CACHE_BUDGET | auto | Block budget for the unified paged KV cache pool. auto derives the cap from the memory estimate, a byte count sets it explicitly, and none/0 leaves the pool unbounded. Applies to pool-backed FP16 models under --decode-storage-backend paged. |
--kv-admission-watermark <FRACTION> | MLXCEL_KV_ADMISSION_WATERMARK | 0.01 | Share of the paged KV block budget, in 0.0..=0.5, that a prefill admission keeps free while rows are decoding. Admission waits until the free blocks cover the request plus this share, evicting cold prompt-cache prefixes (and, for a higher-priority request, preempting strictly lower-priority rows) to make room. A request that fits the budget is never refused. 0 disables it; ignored without a block budget. See Decode headroom under a tight budget. |
--kv-bits <BITS> | LLAMA_ARG_KV_BITS | 0 | Continuous-batching KV quantization: 8 with uniform, or 4 with turboquant; 0 disables it. |
--kv-group-size <N> | LLAMA_ARG_KV_GROUP_SIZE | 64 | Uniform-quantization channel group size; must divide V head_dim. |
--kv-quant-scheme <uniform\|turboquant> | LLAMA_ARG_KV_QUANT_SCHEME | uniform | Batched KV quantization scheme. Uniform 4-bit is rejected; use TurboQuant for 4-bit. |
--kv-skip-last-layer <BOOL> | LLAMA_ARG_KV_SKIP_LAST_LAYER | true | Keep the last transformer layer unquantized to preserve quality. |
--turbo-boundary-v <COUNT> | MLXCEL_KV_BOUNDARY_V_LAYERS | 2 | Keep first/last V boundary layers in FP16 under Turbo modes. |
--vision-cache-size <N> | - | 20 | Maximum number of cached post-projection image features per loaded VLM. Multi-turn conversations that revisit the same image reuse cached features and skip the vision tower + multimodal embedder on subsequent turns. Set to 0 to disable. Currently wired into Gemma 4 VLM, Qwen 2.5-VL, and Qwen 3-VL; other families fall back to the uncached path. See Vision Feature Cache. |
--media-path <DIR> | - | unset | Root that local media files are read from. Without it, a file:// media URL is refused. With it, a request's path resolves relative to the root first, and an absolute path is accepted only when it names a file inside the root. See Media inputs. |
--max-image-payload-size <BYTES> | LLAMA_ARG_MAX_IMAGE_PAYLOAD_SIZE | 67108864 | Maximum encoded bytes per image. |
--max-images <N> | LLAMA_ARG_MAX_IMAGES | 16 | Maximum image count per request. Frames sent through the video-to-images fallback count against it. |
--video-max-frames <N> | MLXCEL_VIDEO_MAX_FRAMES | 16 | Frames kept when a video_url block is sent to a checkpoint with no native video path as ordered images. Values below 2 are raised to 2. |
--video-fps <FLOAT> | MLXCEL_VIDEO_FPS | 2.0 | Sampling rate for that fallback when the request's video_url.fps is absent. |
--max-image-width <PX>, --max-image-height <PX> | LLAMA_ARG_MAX_IMAGE_WIDTH, LLAMA_ARG_MAX_IMAGE_HEIGHT | 16384 | Maximum decoded image dimensions. |
--max-image-decode-alloc-bytes <BYTES> | LLAMA_ARG_MAX_IMAGE_DECODE_ALLOC_BYTES | 536870912 | Decoder allocation budget for one image. |
--estimate-memory | - | false | Run the unified memory preflight before the server loads the model. Aborts when estimated total memory exceeds the available budget. |
--force, --no-memory-check | - | false | Downgrade an over-budget memory preflight result to a warning and continue. No effect unless --estimate-memory is set. |
When --ctx-size C is nonzero, mlxcel follows llama.cpp server semantics: the value is a total server context budget. The effective per-slot context window is floor(C / active_slots), where active_slots is --max-batch-size when set, otherwise --n-parallel; --no-batch uses one slot. /health.context_size, /slots[].context_size, and memory preflight report and use the effective per-slot value. Startup rejects explicit budgets that leave a slot below 512 tokens.
Audio Workers¶
| Flag | Env | Default | Description |
|---|---|---|---|
--audio-queue-depth <N> | MLXCEL_AUDIO_QUEUE_DEPTH | 8 | Bounded waiting queue behind the single audio worker. A full queue returns 503. |
--audio-request-timeout-secs <N> | MLXCEL_AUDIO_REQUEST_TIMEOUT_SECS | 120 | Caller wait limit. Expiry returns 504 but does not cancel work already running. |
See OpenAI Audio API for Whisper and Kokoro setup.
Embedding and Reranking Workers¶
| Flag | Env | Default | Description |
|---|---|---|---|
--embedding-model <PATH_OR_REPO_ID> | LLAMA_ARG_EMBEDDING_MODEL, MLXCEL_EMBEDDING_MODEL | - | Load one embedding checkpoint beside the primary model. |
--reranker-model <PATH_OR_REPO_ID> | LLAMA_ARG_RERANKER_MODEL, MLXCEL_RERANKER_MODEL | - | Load one reranker beside the primary model; required to select generative rerankers. |
--embedding-batch-size <N> | MLXCEL_EMBEDDING_BATCH_SIZE | 16 | Text inputs per embedding forward pass. |
--embedding-max-length <N> | MLXCEL_EMBEDDING_MAX_LENGTH | derived | Lower the embedding token limit derived from the checkpoint. |
--embedding-queue-depth <N> | MLXCEL_EMBEDDING_QUEUE_DEPTH | 8 | Bound on each embedding and reranking worker queue. |
--embedding-request-timeout-secs <N> | MLXCEL_EMBEDDING_REQUEST_TIMEOUT_SECS | 120 | Reply timeout used by both worker types. |
--rerank-batch-size <N> | MLXCEL_RERANK_BATCH_SIZE | 0 | Kind default: 8 pairs for text or 2 for multimodal. |
--pooling <mean\|cls\|last\|rank> | - | checkpoint/family | Override pooling, or use rank to select reranking mode. none is refused. |
--embd-normalize <N> | - | checkpoint | Override embedding normalization. |
--embedding, --embeddings | - | false | Select embedding-only compatibility mode and require an embedding provider. |
--rerank, --reranking | - | false | Select reranking-only compatibility mode and require a reranker provider. |
An embedding or sequence-classifier checkpoint in -m starts that specialized worker without chat. A chat model in -m can run with both secondary providers. A generative reranker-only server names the same checkpoint in -m and --reranker-model; this does not load two copies. One process supports at most one embedding provider and one reranker provider. See Embedding and Reranking APIs.
Speculative Decoding (serve)¶
| Flag | Env | Default | Description |
|---|---|---|---|
--draft-model <PATH_OR_REPO_ID> | - | - | Drafter checkpoint, a path or an owner/name repo id resolved like -m. Both binaries accept --draft-model and --model-draft; mlxcel serve displays the former and standalone mlxcel-server the latter as primary. A drafter whose config.json is missing or malformed fails startup with the config error. |
--draft-max <N> | LLAMA_ARG_SPEC_DRAFT_N_MAX (LLAMA_ARG_DRAFT_MAX as fallback) | 16 | Accepted for llama-server compatibility; also spelled --draft, --spec-draft-n-max, and --draft-n. The value is reported as n_max in /props. It does not set the proposal width, which comes from --draft-block-size. |
--draft-kind <dflash\|mtp\|full-model\|prompt-lookup> | LLAMA_ARG_DRAFT_KIND, MLXCEL_DRAFT_KIND | auto | Force the drafter kind. prompt-lookup takes no drafter checkpoint (a --draft-model with it fails startup) and runs n-gram verify rounds for eligible requests inside the batch scheduler; see Prompt Lookup. full-model runs an ordinary smaller checkpoint from its own KV caches on the same token-only verify loop, under the same --prompt-lookup-max-batch gate. If omitted, the server auto-detects from the drafter config.json::model_type (gemma4_assistant, gemma4_unified_assistant, qwen3_5_mtp, and glm4_moe_lite_mtp map to mtp; a DFlash-family directory maps to dflash; any other readable model directory maps to full-model, which covers the Qwen 3.5, LFM2 DSpark, and Laguna DFlash drafters only when they are given explicitly). |
--draft-block-size <N> | LLAMA_ARG_DRAFT_BLOCK_SIZE, MLXCEL_DRAFT_BLOCK_SIZE | resolved at startup | DFlash, MTP, or full-model block size. When unset, the width comes from the drafter checkpoint's own declared width, then a measured per-device default, then 4 for MTP and full-model and 16 for DFlash. With --draft-kind prompt-lookup it sets the largest proposal (default 7). See Draft block width. |
--prompt-lookup-max-batch <N> | - | 2 | Largest active decode batch at which a prompt-lookup row runs its own verify round. On ticks with more rows, every row takes the plain batched step. Must be at least 1. |
Diffusion Options (serve)¶
These flags tune block-diffusion generation when the served model is a diffusion model such as DiffusionGemma. Autoregressive models ignore them. See Block Diffusion.
| Flag | Default | Description |
|---|---|---|
--max-denoising-steps <N> | checkpoint generation_config (typically 48) | Maximum denoising iterations per canvas block. |
--diffusion-sampler <entropy-bound\|confidence-threshold> | entropy-bound | Per-step token acceptance strategy. |
--diffusion-threshold <FLOAT> | 0.9 | Confidence threshold for the confidence-threshold sampler; validated to [0, 1] at startup. |
Image Model (serve)¶
| Flag | Env | Default | Description |
|---|---|---|---|
--image-model <PATH_OR_REPO_ID> | MLXCEL_IMAGE_MODEL | - | Load an image-generation checkpoint beside the chat model and mount POST /v1/images/generations and POST /v1/images/edits. Requests run one at a time. Startup fails when the checkpoint is not a supported image family. See Image Generation. |
Chat Template¶
| Flag | Default | Description |
|---|---|---|
--chat-template <TEMPLATE> | - | Override the chat template with a Jinja2 template string. |
--chat-template-file <PATH> | - | Load the chat template override from a file. |
--chat-template-kwargs <JSON> | - | Server-default Jinja kwargs. Per-request chat_template_kwargs values merge over matching keys. |
--reasoning-budget <N> | -1 | Qwen3-family thinking-token budget: -1 unrestricted, 0 end immediately, positive values cap thinking. Request values override it. |
Endpoint Toggles¶
| Flag | Default | Description |
|---|---|---|
--slots / --no-slots | enabled | Enable or disable the /slots endpoint showing per-slot status. |
--props | disabled | Enable the /props endpoint returning server properties. |
--metrics | disabled | Enable the /metrics endpoint for Prometheus-compatible metrics. |
--warmup / --no-warmup | enabled | Run a one-token warmup pass after model load to initialize Metal compilation. |
--settings | disabled | Enable the authenticated GET/PATCH /v1/settings endpoints. |
--slot-save-path <PATH> | disabled | Directory used to save and restore slot KV cache through POST /slots/:id_slot. |
--sleep-idle-seconds <SECS> | -1 | Sleep after this many idle seconds, freeing the model until the next request wakes it. -1 disables sleeping. |
Model Resolution and Store¶
| Flag | Env | Default | Description |
|---|---|---|---|
--hf-repo <OWNER/NAME> | - | - | HuggingFace repository to serve, in the llama-server spelling. Resolved exactly like the same value passed to -m: reused from ./models/, the HuggingFace cache, or the mlxcel store, and downloaded into the mlxcel store on a miss. Takes precedence over -m when both are given, matching llama-server. |
--hf-token <TOKEN> | HF_TOKEN, HUGGING_FACE_HUB_TOKEN | - | Access token used when downloading a repository. The flag takes precedence over both environment variables. The value is never rendered in --help, logged, or written to disk. |
--model-store-root <PATH> | MLXCEL_MODELS_DIR | - | Directory that directly holds snapshots, so a repo-id resolves to and downloads at <PATH>/<owner>/<name> with no extra models/ level. Overrides the environment variable and has no effect when the model argument is already a local path. |
--offline | LLAMA_ARG_OFFLINE | off | Resolve models from local caches only and never download. A repository identifier absent from ./models/, the HuggingFace cache, and the mlxcel store becomes an error instead of a download. |
--hf-file, --model-url, and --docker-repo are parsed for llama-server CLI compatibility but rejected at startup. --hf-file selects one GGUF file inside a repository while MLX loads a whole SafeTensors snapshot, --model-url resolves by URL while mlxcel resolves by repository identifier, and Docker Hub model repositories distribute GGUF artifacts.
Router Mode¶
These flags apply when the server hosts more than one model.
| Flag | Default | Description |
|---|---|---|
--models-max <N> | 4 | Maximum number of models held in memory at once. 0 means unlimited. |
--models-preset <PATH> | disabled | INI file describing model presets the router can serve. |
--models-autoload / --no-models-autoload | enabled | Load a model on first request instead of requiring an explicit load. |
--tags <LIST> | - | Comma-separated model tags. Informational only; they are not used for routing. |
WebUI¶
| Flag | Env | Default | Description |
|---|---|---|---|
--webui, --ui | LLAMA_ARG_UI | off | Serve the bundled administrative WebUI at {api_prefix}/webui/. Without a model argument the server starts model-free in router mode with autoload off. Requires a binary built with the webui Cargo feature, which is on by default. The flag is hidden from --help. |
--no-webui, --no-ui | LLAMA_ARG_UI=0 | - | Explicitly disable the WebUI. |
See WebUI for the security rules and the screens. The llama-server options that configure its own browser UI (--ui-config, --ui-config-file, --path, --tools, --tools-runtime, --mcp-servers-config, --mcp-servers-json, --ui-mcp-proxy, --agent) are refused at startup.
LoRA Adapters (serve)¶
| Flag | Default | Description |
|---|---|---|
--lora-scaled <FNAME:SCALE,...> | - | Load LoRA adapters with per-adapter scaling, as comma-separated path:scale pairs. |
--lora-fuse | off | Fuse LoRA adapters into the base weights at load. This is mlxcel-native and costs nothing at decode time, but runtime scale changes and per-request adapter selection are refused afterwards. |
--lora-init-without-apply | off | Load adapters without applying them, so they can be applied later through POST /lora-adapters. |
Structured Output Defaults¶
Server-wide constraints applied when a request does not carry its own. A request that specifies its own grammar or schema overrides these.
| Flag | Default | Description |
|---|---|---|
--grammar <TEXT> | - | BNF-like grammar constraining every generation. |
--grammar-file <PATH> | - | Read the grammar from a file. |
--json-schema <JSON> | - | JSON Schema constraining every generation, for example {} for any JSON object. For schemas carrying external $refs, convert to a grammar and use --grammar instead. |
--json-schema-file <PATH> | - | Read the JSON Schema from a file. |
Responses API Stores¶
These flags control the in-memory stores used by /v1/responses.
| Flag | Env | Default | Description |
|---|---|---|---|
--responses-store-max-entries <N> | LLAMA_ARG_RESPONSES_STORE_MAX_ENTRIES | 1024 | Maximum stored response objects. 0 disables persistence. |
--responses-store-ttl-secs <SECS> | LLAMA_ARG_RESPONSES_STORE_TTL_SECS | 3600 | Response-store TTL. 0 disables TTL eviction. |
--conversation-store-max-entries <N> | LLAMA_ARG_CONVERSATION_STORE_MAX_ENTRIES | 256 | Maximum stored Responses API conversation transcripts. |
--conversation-store-ttl-secs <SECS> | LLAMA_ARG_CONVERSATION_STORE_TTL_SECS | 3600 | Conversation-store TTL. 0 disables TTL eviction. |
Prompt Cache and APC¶
Prompt-prefix KV caching is enabled by default. These flags tune cache capacity and the default-on APC block-hash layer. See Prompt Cache for behavior, metrics, and troubleshooting details.
| Flag | Env | Default | Description |
|---|---|---|---|
--prompt-cache-enabled[=BOOL] | MLXCEL_PROMPT_CACHE_ENABLED, fallback LLAMA_ARG_CACHE_REUSE | true | Enable or disable cross-request prompt-prefix KV reuse. |
--no-prompt-cache | - | false | Explicit shorthand for --prompt-cache-enabled=false; overrides cache environment settings. |
--prompt-cache-capacity-bytes <BYTES> | MLXCEL_PROMPT_CACHE_CAPACITY_BYTES | 2147483648 | Total prompt-cache byte budget. |
--prompt-cache-max-entries <N> | MLXCEL_PROMPT_CACHE_MAX_ENTRIES | 1024 | Maximum live prompt-cache entries. |
--prompt-cache-ttl <SECONDS> | MLXCEL_PROMPT_CACHE_TTL | 3600 | TTL since the last successful lookup. |
--prompt-cache-min-prefix <N> | MLXCEL_PROMPT_CACHE_MIN_PREFIX | 32 | Minimum token prefix length eligible for caching. |
--prompt-cache-snapshot-capacity-bytes <BYTES> | MLXCEL_PROMPT_CACHE_SNAPSHOT_CAPACITY_BYTES | 536870912 | Exact-prefix snapshot budget for recurrent and linear-attention families. |
--prompt-cache-snapshot-max-entries <N> | MLXCEL_PROMPT_CACHE_SNAPSHOT_MAX_ENTRIES | 4096 | Maximum live snapshots. |
--prompt-cache-snapshot-ttl <SECONDS> | MLXCEL_PROMPT_CACHE_SNAPSHOT_TTL | 7200 | Snapshot TTL. |
--apc-enabled[=BOOL] | APC_ENABLED | true | Enable APC block-granularity hash chains on top of the prompt cache. Automatically disabled for hybrid SSM/attention models. |
--apc-block-size <N> | APC_BLOCK_SIZE | 16 | Tokens per APC block. |
--apc-num-blocks <N> | APC_NUM_BLOCKS | derived | Maximum APC block entries to track. |
--apc-hash <sha256\|blake3> | APC_HASH | sha256 | Block hash algorithm. SHA-256 is the default for wire compatibility; BLAKE3 is faster but not wire-compatible. |
--enable-vlm-prefix-cache | MLXCEL_ENABLE_VLM_PREFIX_CACHE | false | Experimental. Lets multimodal chat requests adopt and donate KV prefixes, so multi-turn conversations over the same image skip the shared prefill. Text-only behavior is unchanged. |
Default Sampling Parameters¶
These flags set server-wide defaults used when a request does not specify its own sampling parameters. Individual requests can override all of these values.
| Flag | Env | Default |
|---|---|---|
--temp <FLOAT> | - | 0.8 |
--top-k <K> | LLAMA_ARG_TOP_K | 40 |
--top-p <FLOAT> | - | 0.9 |
--min-p <FLOAT> | - | 0.1 |
-s, --seed <N> | - | -1 (random) |
--repeat-last-n <N> | - | 64 |
--repeat-penalty <FLOAT> | - | 1.0 |
--presence-penalty <FLOAT> | - | 0.0 |
--frequency-penalty <FLOAT> | - | 0.0 |
--dry-multiplier <FLOAT> | - | 0.0 |
--dry-base <FLOAT> | - | 1.75 |
--dry-allowed-length <N> | - | 2 |
--dry-penalty-last-n <N> | - | 64 (0 disables DRY; negative values are rejected) |
--dry-sequence-breaker <LIST> | - | - |
--dry-sequence-breakers <LIST> | - | visible alias of the singular spelling |
--typical <FLOAT> | - | 1.0 (disabled) |
--top-nsigma <FLOAT> | - | -1.0 (disabled) |
--xtc-probability <FLOAT> | - | 0.0 (disabled) |
--xtc-threshold <FLOAT> | - | 0.1 |
--dynatemp-range <FLOAT> | - | 0.0 (disabled) |
--dynatemp-exp <FLOAT> | - | 1.0 |
--mirostat <N> | - | 0 (disabled) |
--mirostat-lr <FLOAT> | - | 0.1 |
--mirostat-ent <FLOAT> | - | 5.0 |
--adaptive-target <FLOAT> | - | -1.0 (disabled) |
--adaptive-decay <FLOAT> | - | 0.9 |
--ignore-eos | - | off |
--logit-bias <TOKEN(+/-)BIAS> | - | - |
--reverse-prompt <STRING> | - | - |
--samplers <LIST> | - | - |
--sampler-seq <CHARS> | - | - |
--adaptive-target and --adaptive-decay drive adaptive-p, which runs only when the sampler list names adaptive_p, as in b10621. --ignore-eos suppresses end-of-generation tokens so generation runs to the token budget or a stop string. --logit-bias biases a token id in every request (TOKEN_ID(+/-)BIAS, for example 15043+1) and is repeatable. --reverse-prompt adds a server-wide stop string merged into every request's stop set and is repeatable. --samplers and --sampler-seq (the single-character b10621 form) are accepted, but mlxcel's chain order is fixed to b10621's default and any other order is rejected at startup.
Distributed Inference¶
| Flag | Default | Description |
|---|---|---|
--distributed-config <PATH> | - | Path to a TOML cluster configuration file. |
--node-role <ROLE> | - | Role this node plays: prefill, decode, router, pipeline_stage, tensor_parallel_rank, pipeline_tensor_parallel, or hybrid. router starts the model-free disaggregated-serving HTTP front; pipeline_tensor_parallel is the 2D (pp_stage, tp_rank) mesh role. |
--node-id <ID> | - | Unique identifier for this node in the cluster. |
--peers <ADDR,...> | - | Comma-separated list of peer addresses for static discovery. |
--serving-bind <ADDR> | - | This node's own bind address for the disaggregated serving-role transport. Required for prefill and decode roles; the router also binds here to receive result frames. See Disaggregated Inference. |
--prefill-peers <ADDR,...> | - | Prefill-node serving addresses the router forwards tokenized requests to. |
--decode-peers <ADDR,...> | - | Decode-node serving addresses a prefill node hands KV caches off to. The router also registers them for result demultiplexing. |
--pp-layers <RANGES> | - | Manual pipeline-parallel layer partition, e.g. 0-15,16-31. When omitted, layers are auto-partitioned byte-accurately, respecting adjacency constraints for MoE experts and Gemma 4 KV-shared pairs, so manual --pp-layers is rarely necessary even on mixed-memory clusters. |
--pp-micro-batch-size <N> | 1 | Micro-batch size for pipeline parallelism. |
--pp-auto <N> | - | (coordinator) Declare the desired number of pipeline stages. The coordinator discovers peers via --cluster-peers or --cluster-discovery=mdns, plans the partition, emits the cluster TOML, and starts serving. Mutually exclusive with --distributed-config and --pp-layers. See Zero-Config Startup. |
--pp-peer | - | Zero-config pipeline stage. The process listens on --cluster-control-addr for the stage assignment from a --pp-auto coordinator, checks that the coordinator holds the same cluster secret, cluster name, model, and mlxcel version, and serves the assigned stage. --distributed-config and --node-id are not needed. |
--cluster-discovery <static\|mdns> | static | Discovery mechanism. static consumes --cluster-peers verbatim; mdns opts in to LAN peer announcements over UDP broadcast. |
--cluster-discovery-port <PORT> | 49555 | UDP beacon port used with --cluster-discovery=mdns. |
--cluster-name <NAME> | mlxcel-cluster | Cluster name embedded in the emitted TOML and mDNS beacons. |
--cluster-peers <ADDR[,ADDR...]> | - | Static seed peers (host:port) for --pp-auto. |
--cluster-control-addr <host:port> | 127.0.0.1:19000 | Coordinator control-plane address (separate from the HTTP port). |
--cluster-config-out <PATH> | ./.mlxcel/cluster.toml | Output path for the emitted cluster TOML. |
--dry-run | - | Plan the cluster topology, print the summary, emit the TOML, and exit. Non-zero exit on port / peer-count / version conflicts. |
--enable-elastic-pp | false | Enable experimental elastic pipeline-parallel repartitioning. Drains in-flight requests, recomputes the partition plan, and resumes without a full cluster restart. See Elastic repartitioning. |
--elastic-pp-drain-timeout <SECS> | 120 | Maximum seconds to wait for in-flight requests to drain before forcing a rebalance. |
--elastic-pp-pressure-fraction <FLOAT> | 0.92 | Trigger threshold for repartition, expressed as a fraction of KV capacity. |
--elastic-pp-cool-down <SECS> | 30 | Minimum seconds between repartition events. |
--metrics-port <PORT> | - | Enable the /metrics endpoint with PP-specific series (stage utilization, bubble ratio, activation-transfer latency histograms, KV admission rejections, elastic-repartition events). The endpoint is currently multiplexed onto the main HTTP port; a different port emits a warning. |
--debug-pp-trace <PATH> | - | Write a chrome-tracing JSON envelope of scheduler actions to PATH. Flushed on shutdown. |
--tp-size <N> | 1 | Number of tensor-parallel ranks (must be a power of 2). |
--tp-moe-mode <MODE> | expert_parallel | MoE expert sharding: expert_parallel or within_expert. |
--tp-embedding-mode <MODE> | replicated | Embedding sharding: vocab_parallel or replicated (current runtime requires replicated). |
--tp-lm-head-mode <MODE> | replicated | LM head sharding: vocab_parallel or replicated (current runtime requires replicated). |
Current tp_size > 1 runtime notes:
- Supported families: dense Llama, dense Qwen2/2.5, dense Qwen3, dense Qwen3.5 text, Gemma 3 text, Gemma 4 text, ERNIE 4.5, Hunyuan v1 Dense
- The current runtime is in-process multi-rank on one machine
- LoRA adapters are not supported with TP
mlxcel servekeeps continuous batching enabled for all currently supported dense TP runtimes except Gemma 4 E2B-style conservative fallback checkpointsmlxcel servedefaults decode storage toauto; Llama, Qwen 3, Qwen 3.5 text, Gemma 3 text, and Llama 4 workers select paged decode automatically. Families such as ExaOne4, Ministral3, Gemma 4, Qwen3 Next, GPT-OSS, and standard external-KV workers without model-specific paged decode dispatch remain on dense decode until they satisfy the paged-default rollout checklist in Continuous Batching
Example:
mlxcel generate \
--model ./models/ernie-4.5-0.3b-4bit \
--prompt "Write one short sentence about TP." \
--tp-size 2
Remote TCP pipeline-parallel example:
CLUSTER_NAME=studio-pp \
TRANSPORT_BACKEND=tcp \
COORDINATOR_CONTROL_ADDR=192.168.1.22:19000 \
STAGE0_ADDR=192.168.1.22:19001 \
STAGE1_ADDR=192.168.1.24:19001 \
scripts/benchmark_pipeline_remote_rollout.sh write-config \
examples/distributed/generated_pipeline_remote_2node_tcp.toml
# Machine B
mlxcel serve \
--model ./models/llama-3.2-1b-4bit \
--distributed-config examples/distributed/generated_pipeline_remote_2node_tcp.toml \
--node-id stage-1 \
--host 0.0.0.0 \
--port 18081 \
--no-warmup
# Machine A
mlxcel serve \
--model ./models/llama-3.2-1b-4bit \
--distributed-config examples/distributed/generated_pipeline_remote_2node_tcp.toml \
--node-id stage-0 \
--host 0.0.0.0 \
--port 18081 \
--no-warmup
# Machine A coordinator
mlxcel serve \
--model ./models/llama-3.2-1b-4bit \
--alias llama-remote-pp \
--distributed-config examples/distributed/generated_pipeline_remote_2node_tcp.toml \
--node-id coordinator \
--host 0.0.0.0 \
--port 18080 \
--n-parallel 2 \
--max-batch-size 2 \
--pp-micro-batch-size 2 \
--metrics \
--no-warmup
Smoke test:
COORDINATOR_URL=http://192.168.1.22:18080 \
MODEL_ALIAS=llama-remote-pp \
scripts/benchmark_pipeline_remote_rollout.sh smoke
Thunderbolt mode uses the same workflow with:
TRANSPORT_BACKEND=thunderbolt- Thunderbolt Bridge IPs instead of LAN IPs
- the same coordinator/stage split and ports
Example:
CLUSTER_NAME=studio-pp \
TRANSPORT_BACKEND=thunderbolt \
COORDINATOR_CONTROL_ADDR=169.254.20.10:19000 \
STAGE0_ADDR=169.254.20.10:19001 \
STAGE1_ADDR=169.254.20.11:19001 \
scripts/benchmark_pipeline_remote_rollout.sh write-config \
examples/distributed/generated_pipeline_remote_2node_thunderbolt.toml
Logging¶
| Flag | Env | Default | Description |
|---|---|---|---|
-v, --verbose | - | false | Enable debug-level logging. |
--log-disable | - | false | Suppress all log output. |
--log-file <PATH> | LLAMA_LOG_FILE | - | Write logs to a file instead of stderr. |
Serve Examples¶
Minimal server on localhost:
The server starts on 127.0.0.1:8080. Test it with curl:
Chat completion request:
curl -s http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen2.5-7B-Instruct",
"messages": [
{"role": "user", "content": "What is 2 + 2?"}
],
"max_tokens": 50
}'
Server with authentication and public binding:
mlxcel serve \
--model ./models/Llama-3.1-8B-Instruct \
--host 0.0.0.0 \
--port 8080 \
--api-key "my-secret-key"
Authenticated request:
curl -s http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer my-secret-key" \
-H "Content-Type: application/json" \
-d '{"model":"Llama-3.1-8B-Instruct","messages":[{"role":"user","content":"Hello"}]}'
High-concurrency server with batching and metrics:
mlxcel serve \
--model ./models/Qwen2.5-7B-Instruct \
--max-batch-size 8 \
--prefill-chunk-size 512 \
--enable-preemption \
--metrics
An explicit --prefill-chunk-size pins the chunk in both scheduler states; omit it to keep the adaptive default (2048 with no live decode, 512 with one).
Server with DFlash speculative decoding:
mlxcel serve \
--model ./models/qwen3.5-27b-4bit \
--draft-model ./models/Qwen3.5-27B-DFlash \
--draft-kind dflash \
--draft-block-size 16
For the standalone server binary, the primary spelling is --model-draft (--draft-model is also accepted):
mlxcel-server \
--model ./models/qwen3.5-27b-4bit \
--model-draft ./models/Qwen3.5-27B-DFlash \
--draft-kind dflash \
--draft-block-size 16
Unix socket mode (for local IPC):
Using environment variables (deployment pattern):
export LLAMA_ARG_MODEL=./models/Qwen2.5-7B-Instruct
export LLAMA_API_KEY=my-secret-key
export LLAMA_ARG_PORT=9000
mlxcel serve
mlxcel list¶
Lists the models downloaded into the local mlxcel store, one row per snapshot with repo-id, on-disk size, and last-modified time. No model loading occurs. To list the supported model architectures instead, use mlxcel arch.
| Flag | Default | Description |
|---|---|---|
--models-dir <PATH> | MLXCEL_MODELS_DIR / cache root | Model-store root to list instead of the default location. Lists snapshots directly under <PATH>/<owner>/<name>. |
--json | false | Emit a JSON array of {repo_id, size_bytes, path, modified} (modified is Unix epoch seconds, or null). Disables the table, header, and styling. Mutually exclusive with --quiet / --verbose. |
-q, --quiet | false | Print only repo-ids, one per line, so the output pipes cleanly (e.g. mlxcel list -q \| xargs -n1 mlxcel rm). Mutually exclusive with --json / --verbose. |
-v, --verbose | false | Append the absolute on-disk path column back to the default table. Mutually exclusive with --json / --quiet. |
--sort <SORT> | name | Sort order: name (repo-id, default), size (largest on-disk first), or modified (most-recently-modified first; unknown mtimes last). Applies to the table and --json alike. |
mlxcel list # default table, sorted by repo-id
mlxcel list --sort size # largest models first
mlxcel list -q # repo-ids only, pipe-friendly
mlxcel list --json # machine-readable
mlxcel list --models-dir /data/mlxcel-models
mlxcel arch¶
Prints all supported model architectures grouped by category, then exits. With --json, writes the same registry as one machine-readable JSON object for recipe and coverage tooling. No model loading occurs.
Example output (abbreviated):
Supported Model Architectures:
Llama:
- Llama 1/2/3
- Llama 4 (MoE)
Speech-to-text:
- Whisper (encoder-decoder ASR)
Text-to-speech:
- Kokoro (StyleTTS2 + iSTFTNet)
Embedding:
- BERT / MiniLM encoder
- Qwen3-VL-Embedding
Reranker:
- SequenceClassifier
Other VLM:
- Falcon-OCR (early fusion)
- Florence-2 (DaViT + BART seq2seq, task prompts)
...
The JSON form reports mlxcel_version plus one families entry per supported architecture with stable id, display_name, category, model_types, aliases, runtimes, modalities_in, output, backends (Metal, CUDA, and ROCm status; every family's ROCm entry is partial while the backend is experimental), tensor_parallel, pipeline_parallel, drafters, and kv_modes fields. The committed recipes/registry/CURRENT marker points at the matching snapshot under recipes/registry/.
The exact list is generated from ALL_MODEL_TYPES in the running binary. Use mlxcel arch rather than a copied list when checking a deployment. See Supported Models for architecture keys and capability notes.
Model detection is automatic. Generation, embedding, and reranking loaders use model_type together with architecture and checkpoint-layout metadata, so no manual architecture flag is needed.
mlxcel download¶
Downloads a HuggingFace repository snapshot without Python dependencies. By default, the snapshot lands in the global mlxcel store at ${MLXCEL_CACHE_DIR:-$HOME/.cache/mlxcel}/models/<owner>/<name>, and an existing HuggingFace cache copy is reused when possible. The standalone mlxcel-server binary exposes the same download subcommand for deployment images that ship only the server executable; mlxcel-server download --help (also -h and --usage) prints its help.
| Flag | Default | Description |
|---|---|---|
<REPO_ID> | required | HuggingFace repository id, for example mlx-community/Qwen3-4B-4bit. |
--local-dir <PATH> | - | Explicit destination directory. This opts out of the global store and writes the snapshot exactly at PATH. |
--models-dir <PATH> | MLXCEL_MODELS_DIR / cache root | Model-store root under which <owner>/<name> is created. Ignored when --local-dir is supplied. |
--revision <REV> | main | Branch, tag, or commit hash to download. |
--token <TOKEN> | HF_TOKEN, then HUGGING_FACE_HUB_TOKEN, then anonymous | Token for gated or private repositories. |
--force | false | Re-download files even when matching local files already exist. |
Examples:
# Default: global store.
mlxcel download mlx-community/Qwen3-4B-4bit
# Write to an exact directory instead of the store.
mlxcel download mlx-community/Qwen3-4B-4bit --local-dir /tmp/qwen
# Relocate the store root for this command.
mlxcel download mlx-community/Qwen3-4B-4bit --models-dir /data/mlxcel-models
# Gated/private repository.
mlxcel download meta-llama/Llama-3.1-8B-Instruct --token "$HF_TOKEN"
mlxcel rm¶
Removes a downloaded model snapshot from the mlxcel store. It only deletes snapshots under the managed store root; models that exist solely in the read-only HuggingFace cache are reported but never deleted.
| Flag / Argument | Default | Description |
|---|---|---|
<REPO_ID> | required | HuggingFace repository id to remove, for example mlx-community/Qwen3-4B-4bit. |
--models-dir <PATH> | MLXCEL_MODELS_DIR / cache root | Store root to remove from. The deleted path is <PATH>/<owner>/<name>. |
-y, --yes | false | Skip the interactive confirmation prompt. |
--revision <REV> | main | Used only to locate and report a HuggingFace-cache snapshot when no mlxcel-store copy exists. |
Examples:
mlxcel rm mlx-community/Qwen3-4B-4bit
mlxcel rm mlx-community/Qwen3-4B-4bit --yes
mlxcel rm mlx-community/Qwen3-4B-4bit --models-dir /data/mlxcel-models
mlxcel tune¶
Profiles supported kernel launch configurations and writes the fastest stable choices under ${MLXCEL_CACHE_DIR:-$HOME/.cache/mlxcel}/autotune. Tuning is inert until MLXCEL_AUTOTUNE=cache or MLXCEL_AUTOTUNE=1 is set. See Performance Tuning.
| Flag | Default | Description |
|---|---|---|
--op <OP> | all supported | Repeatable operation selector: paged-decode-splits, qmm-tile, or qmv-multirow. The latter two are CUDA-only and unvalidated. |
--dry-run | false | Print the candidate matrix without profiling or writing results. |
-m, --model <PATH> | - | Read head_dim, query heads, and KV heads from config.json; no weights are loaded. |
--head-dim <N> | 128 | Per-head dimension for paged decode. |
--q-heads <N> | 32 | Query-head count. |
--kv-heads <N> | 8 | KV-head count. |
--block-size <N> | 32 | Paged KV block size. |
--batch-sizes <LIST> | 1,2,4,8 | Comma-separated batch sizes. |
--context-lengths <LIST> | 1024,4096,16384 | Comma-separated visible context lengths. |
--warmup <N>, --warmup-ms <MS> | 3, 40 | Minimum warmup repetitions and wall-clock budget. |
--reps <N>, --max-reps <N> | 5, 1000 | Minimum and maximum adaptive timed repetitions. |
--sample-ms <MS> | 250 | Sampling budget per candidate. |
--min-improvement <FLOAT> | 0.02 | Minimum relative win; measured median spread can raise the effective threshold. |
--qmm-tile-cap <N> | 128 | CUDA qmm CTA tile_m ceiling. |
mlxcel tune --dry-run
mlxcel tune --op paged-decode-splits -m ./models/qwen3-4b-4bit
MLXCEL_AUTOTUNE=cache mlxcel serve -m ./models/qwen3-4b-4bit
mlxcel split-mtp¶
Writes the GLM-4.7-Flash next-token-prediction layer out of a raw zai-org/GLM-4.7-Flash checkpoint into a standalone glm4_moe_lite_mtp drafter directory. The community 4-bit conversions drop the model.layers.47.* tensors, so the source must be the raw checkpoint; the tool reads only the shards that the safetensors index names for that layer. The resulting directory pairs with any glm4_moe_lite target of the same geometry through mlxcel generate --draft-model or mlxcel-server --model-draft. The command needs the surgery Cargo feature, which is on by default.
| Flag | Default | Description |
|---|---|---|
-m, --model <PATH> | - | Raw GLM-4.7-Flash checkpoint directory (config.json, shards, and index). A checkpoint whose index names no next-token-prediction layer is refused. |
-o, --output <PATH> | - | Output drafter directory, created if missing. Pointing it at the source directory is refused. |
--block-size <N> | num_nextn_predict_layers + 1 (2) | Verify block size recorded in the drafter config, bonus token included. It becomes the default verify width when the drafter is loaded. At most 16. |
--q-bits <BITS> | bf16 | Affine-quantize every quantizable projection to 2, 3, 4, 5, 6, or 8 bits. The router, norms, and selection bias stay unquantized. |
--q-group-size <N> | 64 | Quantization group size: 32, 64, or 128. Read only with --q-bits. |
--force | false | Overwrite an output directory that already holds a checkpoint. A directory that holds any *.safetensors file other than the drafter's own model.safetensors is still refused, naming the file, because the loader would read it as part of the drafter. |
Bits, group size, and the output path are validated before the output directory is touched.
mlxcel split-mtp -m models/glm-4.7-flash-bf16 -o models/glm-4.7-flash-mtp-4bit --q-bits 4
mlxcel generate -m models/glm-4.7-flash-4bit --draft-model models/glm-4.7-flash-mtp-4bit -p "Hi"
mlxcel prepare-external-ple¶
Builds a qwen4_exp model view whose PLE n-gram table is read from disk through text_config.ple_storage instead of living in the MLX parameters, which takes about 30 GiB out of the load. The command needs no Python and writes the manifest in the mlx-vlm v2 format. Shards are hard-linked, so the output must be on the same filesystem as the source, and names that would escape the source are refused.
| Flag | Default | Description |
|---|---|---|
-m, --model <PATH> | - | Source checkpoint with the n-gram table in its SafeTensors shards. |
-o, --output <PATH> | - | Output directory, created if missing and required to be empty. |
--layout <LAYOUT> | interleaved | interleaved writes a one-record-per-row ple-q4.rows file, about 32 GB for the 320M-row table. ranges writes only a manifest that points at the source shards. |
--cache-rows <N> | 0 | Row-cache hint recorded in the manifest. 0 keeps the MLXCEL_PLE_CACHE_BYTES budget. |
The command prints the target path, row count, table size, and the number of shards linked. On the OptiQ 2-bit checkpoint, loading the resulting view leaves 45.39 GB resident. See External Weight Stores.
mlxcel prepare-expert-stream¶
Writes the contiguous expert file that SSD expert streaming uses automatically when it is present, and verifies it against the checkpoint before reporting. The file goes inside the model directory. The checkpoint must be qwen4_exp. Streaming itself is selected at run time by MLXCEL_EXPERT_STREAM (auto by default) and sized by MLXCEL_EXPERT_ARENA_BYTES; see External Weight Stores.