AFM has two configuration layers. Startup flags establish server policy and load-time resources; each request then chooses sampling, tools, output format, streaming, and token limits. The useful behavior lives in how those layers intersect.
The two layers
| Layer | Examples | Lifetime |
|---|---|---|
| Startup policy | --concurrent, --kv-bits, parser, grammar engine, prefix cache, runtime, speculative resources | Fixed for the server process |
| Request choice | temperature, top_p, tools, tool_choice, response_format, stream, stop, logprobs | May differ for every call |
| Template policy | --default-chat-template-kwargs, --reasoning-effort, --no-thinking | Server defaults; request template kwargs may refine them |
MLX startup parameter map
This is the public composition surface grouped by responsibility. A compatibility flag can be syntactically accepted without changing runtime behavior; those exceptions are marked.
| Responsibility | Parameters | What they establish |
|---|---|---|
| Model and process | -m / --model, -s / --single-prompt, -i / --instructions, --port, --hostname, -w / --webui, --no-streaming | Checkpoint, execution shape, listener, default system instruction, and UI. |
| Sampling defaults | --temperature, --top-p, --top-k, --min-p, --presence-penalty, --repetition-penalty, --max-tokens, --seed, --stop, --max-logprobs | Defaults used when a request does not provide its own value. |
| Vision | --vlm, --media | Vision factory selection and single-prompt local media. |
| Tools and output | --tool-call-parser, --tools-json, --fix-tool-args, --guided-json, --enable-grammar-constraints, --raw, --json | Parser policy, CLI tool schema, default response schema, enforcement engine, and stdout representation. |
| Reasoning and templates | --default-chat-template-kwargs, --reasoning-effort, --no-thinking | Template defaults and the final reasoning override. |
| Memory and scheduling | --kv-bits, --prefill-step-size, --enable-prefix-caching, --concurrent, --cache-profile-path, --prewarm, --kv-eviction | KV representation, prompt chunks, cache reuse, scheduler capacity, cache timing, and startup warmup. KV eviction is not active yet. |
| Runtime acceleration | --mlx-runtime, --mtp, --mtp-depth, --eagle3, --dspark-support, --dspark-draft-tokens, --dspark-confidence, --dspark-strict | Runtime boundary and model-specific speculative resources. --mtp-depth is accepted but its value is currently unused. |
| Diagnostics | -v / --verbose, -V / --very-verbose, --vv, --gpu-profile, --gpu-profile-bw, --gpu-trace, --gpu-capture | Increasingly detailed application, request-boundary, memory, bandwidth, and Metal evidence. |
| Remote and automation | --telegram-bot-token, --telegram-allow, --telegram-format, --telegram-require-prefix, --openclaw-config, --help-json | Allowlisted Telegram bridge or machine-readable configuration output. Config/help modes exit without serving. |
| Compatibility only | --max-kv-size, --trust-remote-code, --chat-template, --dtype | Accepted for launcher compatibility, warned, and ignored. |
Request-time parameter map
| Request concern | Fields | Interaction with startup policy |
|---|---|---|
| Routing and conversation | model, messages, user | The server has one loaded model unless gateway discovery is used; messages carry text, tools, or multimodal parts. |
| Sampling | temperature, top_p, top_k, min_p, presence_penalty, repetition_penalty, seed | Request values replace server defaults. Non-greedy sampling leaves speculative fast paths. |
| Length and stopping | max_tokens or max_completion_tokens, stop | max_tokens wins when both length fields are present. Stop sequences make speculative streaming ineligible. |
| Streaming | stream, stream_options.include_usage | Streaming and non-streaming can both use MTP/EAGLE3 when every other condition qualifies. |
| Tools | tools, tool_choice, parallel_tool_calls | The startup parser determines extraction. Tools make speculative requests ineligible. |
| Structured output | response_format | Overrides --guided-json. Token enforcement additionally needs strict mode and the grammar engine. |
| Reasoning template | chat_template_kwargs, reasoning_effort | Merges over server template defaults, except the explicit no-thinking policy remains authoritative. |
| Inspection | logprobs, top_logprobs | Bounded by --max-logprobs; logprob requests leave speculative and lock-free fast paths. |
| Multimodal input | OpenAI message content parts and image URLs | Requires a VLM-capable loaded model; multimodal requests use ordinary decode. |
| Compatibility aliases | repeat_penalty, frequency_penalty | repeat_penalty is an alias used only when repetition_penalty is absent. frequency_penalty is parsed but currently ignored. |
1. A coding-agent server with repeated prompts
Use the radix cache for stable system prompts, allocate slots for several sessions, and opt into argument repair for imperfect coder checkpoints.
afm mlx -m mlx-community/Qwen3-Coder-Next-4bit \
--enable-prefix-caching \
--concurrent 4 \
--tool-call-parser afm_adaptive_xml \
--fix-tool-args \
--max-tokens 8192Why it composes: concurrency and prefix caching are both handled by the batch scheduler. Repair operates after model output. Cost: this is not a parity configuration, and speculative MTP/EAGLE3 will not engage while the persistent batch scheduler is active.
2. A strict extraction appliance
Pin a default schema, enable the grammar engine, and disable reasoning so output begins directly in the constrained language.
SCHEMA=$(jq -c . ./invoice.schema.json)
afm mlx -m <model> \
--guided-json "$SCHEMA" \
--enable-grammar-constraints \
--no-thinking \
--temperature 0Individual requests can replace the server schema with their own response_format. The grammar engine only performs token-level enforcement when the effective JSON schema has strict: true; otherwise the schema remains best-effort guidance.
3. Strict XML-function tools
afm mlx -m <qwen-xml-model> \
--tool-call-parser qwen3_xml \
--enable-grammar-constraints \
--fix-tool-argsStrict tool grammar is implemented for the XML-function path—auto-detected XML, qwen3_xml, or afm_adaptive_xml. JSON response-schema grammar is broader; strict tool grammar is deliberately narrower.
4. Long context under memory pressure
afm mlx -m <model> \
--kv-bits 8 \
--prefill-step-size 1024 \
--enable-prefix-caching \
--max-tokens 4096--kv-bits 8 reduces KV memory; a smaller prefill step lowers the amount of prompt work submitted in one GPU pass; prefix caching avoids recomputing a stable prefix. Measure all three: quantized KV can affect quality, smaller prefill steps may reduce peak pressure but cost throughput, and cached KV itself occupies memory.
5. Shared local throughput
afm mlx -m <model> \
--concurrent 6 \
--enable-prefix-caching \
--kv-bits 8 \
--hostname 127.0.0.1Use this for several local agents or applications sharing one loaded model. AFM fair-queues requests and exposes capacity in /metrics. Some architectures force serial generation for correctness; AFM then accepts concurrent clients but serializes model work.
6. One-shot visual inspection
afm mlx -m <vision-model> \
--media screenshot.png diagram.jpg \
-s "Compare these images and return the important differences." \
--no-thinking \
--json--media implies --vlm and is limited to single-prompt CLI mode. For a long-running VLM server, start with --vlm and send OpenAI-style image parts in the HTTP message instead.
7. Maximum serial decode on eligible checkpoints
# Qwen3.6 checkpoint that contains mtp.safetensors
afm mlx -m Youssofal/Qwen3.6-27B-MTPLX-Optimized-Speed \
--mtp --no-thinking
# Dense Gemma4-31B plus its EAGLE3 drafter
afm mlx -m mlx-community/gemma-4-31b-it-4bit \
--eagle3 /path/to/gemma-4-31B-speculator.eagle3Send greedy, text-only requests without tools, schemas, logprobs, or stop sequences. Do not add --concurrent 2: that changes the execution path to the scheduler and ordinary autoregressive decode. See the full eligibility table.
8. Fixed-schedule DwarfStar with DSpark
afm mlx -m /path/to/self-contained-checkpoint \
--mlx-runtime dwarfstar \
--dspark-support /path/to/support.gguf \
--dspark-draft-tokens 5 \
--dspark-confidence 0.7 \
--enable-prefix-cachingThe checkpoint must be a local, self-contained executor layout. DSpark draft tokens accept 1–16 and confidence accepts 0–1. Add --dspark-strict to load the support model but retain target-only decoding for correctness comparisons.
9. Reasoning policy with an explicit winner
# DeepSeek thinking budget
afm mlx -m <deepseek-model> --reasoning-effort max
# Disable reasoning regardless of template JSON or effort
afm mlx -m <model> \
--default-chat-template-kwargs '{"enable_thinking":true}' \
--reasoning-effort high \
--no-thinkingIn the second command, --no-thinking wins: it sets enable_thinking=false and removes reasoning_effort. This precedence is intentional and logged.
10. Tool-format diagnosis without repair
afm mlx -m <model> \
--tool-call-parser none \
--vv \
-s "Use the supplied tool." \
--tools-json '[{"type":"function","function":{"name":"lookup","parameters":{"type":"object","properties":{"query":{"type":"string"}},"required":["query"]}}}]'Raw parser mode returns emitted tool markup as assistant content. Trace logging shows the boundaries between raw model output, parsed output, and grammar input. Use this to diagnose a checkpoint or template—not as the production agent configuration.
11. Progressively deeper profiling
# Low-friction per-request report
afm mlx -m <model> --gpu-profile -s "Write 200 tokens"
# Add measured DRAM sampling; requires mactop and adds about 5 seconds
afm mlx -m <model> --gpu-profile-bw -s "Write 200 tokens"
# First-request Metal System Trace
afm mlx -m <model> --gpu-trace 10 -s "Write 200 tokens"
# Full GPU capture; automatically limited to five output tokens
afm mlx -m <small-model> \
--gpu-capture /tmp/afm-trace.gputrace -s "Count"12. Scriptable single-prompt mode
result=$(afm mlx -m <model> \
-s "Summarize the input" \
--temperature 0 \
--no-thinking \
--json)Single-prompt mode suppresses load and generation chatter unless verbose logging is enabled, leaving the response on stdout. Telegram options cannot be combined with -s or piped input because the bridge requires server mode.
Interaction matrix
| Parameter A | Parameter B | Result | Interpretation |
|---|---|---|---|
| Prefix cache | Concurrency ≥ 2 | Composes | BatchScheduler receives prefix caching; useful when parallel sessions share stable prompt prefixes. |
| MTP or EAGLE3 | Concurrency ≥ 2 | Fallback | The batch scheduler uses ordinary autoregressive decode. Keep speculative serving serial. |
| MTP or EAGLE3 | tools · schema · logprobs · stop · media · temperature > 0 | Fallback | The request still works, but it leaves the speculative fast path. |
| --guided-json | request response_format | Precedence | The request-level response format wins over the server default. |
| --enable-grammar-constraints | strict: true | Conditional | Both are required for token-level enforcement. Strict tools also require an XML-function parser. |
| --no-thinking | reasoning effort or template kwargs | Overrides | It forces enable_thinking=false and removes reasoning_effort. |
| --media | single-prompt CLI mode | Requires | Media implies --vlm and requires -s. Server VLM requests carry media in message content instead. |
| --gpu-profile-bw | --gpu-profile | Implies | Bandwidth sampling enables the normal GPU profile and adds about five seconds. |
| DwarfStar | KV bits · MTP · EAGLE3 · media · penalties · guided JSON | Rejected | The CLI returns a validation error instead of pretending the option applies. |
| --kv-eviction streaming | any workload | No effect yet | The flag is accepted, but the context-length integration is still marked TODO in source. |
Accepted but currently ignored
AFM accepts four MLX compatibility switches so external launchers do not fail, but it prints a warning and does not apply them:
--max-kv-size--trust-remote-code--chat-template--dtype
That is different from a speculative option that loads successfully but falls back per request. An ignored compatibility switch never changes execution.