Memory Estimation¶
mlxcel can estimate a model load before it touches the MLX runtime. Use this to size a model, context length, batch shape, and KV-cache mode before running generation or starting a server.
The estimator is intentionally pre-load and read-only. It reads config.json, safetensors metadata, environment limits, and Linux memory information when available; it does not allocate tensors, initialize MLX, or load model weights.
What Is Counted¶
The estimate has these components:
| Component | Source |
|---|---|
| Weights | Exact safetensors footprint when possible. Sharded indexes use validated metadata.total_size; stale indexes fall back to shard/header inspection. Single-file safetensors are read from the binary header without loading tensor data. |
| KV cache | config.json architecture fields: layers, KV heads, head_dim, element width, context length, and batch, with the architecture taken into account (sliding-window, MLA, hybrid and pure-SSM layouts are sized by their own cache shape, not the flat per-layer formula). Context is rounded up to the next 256-token allocation block. |
| Allocator overhead | MLXCEL_HEADROOM_FACTOR (default 1.20) applied to weights + KV cache, covering MLX allocator and graph working set. The factor scales only this term. |
| Activation reserve | MLXCEL_ACTIVATION_MULT (default 2.0) times batch x min(context, prefill chunk) x (hidden + intermediate) x 2 bytes, plus the last-token logit buffer batch x vocab x 2 bytes. The prefill chunk is MLXCEL_PREFILL_CHUNK, or 2048 when unset. |
| Backend in-flight | ROCm builds only: the MLX_ROCM_MAX_INFLIGHT_MB budget (default 1024 MiB) that committed but unfinished command batches may hold. Every other build reserves 0. |
| Host shadows | Windows ROCm builds only: pinned host copies the allocator keeps for GPU buffers the CPU touches, estimated per sequence as one f32 logits row (vocab x 4) plus the int32 token ids of the context (context x 4). They draw from host RAM, so they are compared against host RAM separately and are not added to the total; fits requires both comparisons to pass. Every other build reserves 0. |
| Available memory | Apple unified memory, Linux /proc/meminfo, Windows GlobalMemoryStatusEx, or an explicit MLXCEL_MEMORY_LIMIT cap when set. |
The runtime headroom reported by inspect is the sum of the allocator overhead, the activation reserve, and the backend in-flight reserve; the total is weights + KV cache + runtime headroom. The server uses the same estimator to size the paged KV --kv-cache-budget auto budget and the model-aware prompt-cache capacity defaults.
The KV estimate honors INT8 KV cache settings from --kv-cache-mode int8 or split --cache-type-k int8 --cache-type-v int8. TurboQuant modes are reported through the same flag surface, but the current estimator only distinguishes the INT8 byte-width case from the default FP16-equivalent KV cache.
Inspect a Model¶
mlxcel inspect prints the same byte breakdown used by the preflight checks, then exits without loading the model.
Common sizing overrides:
# Estimate a longer context window.
mlxcel inspect -m ./models/qwen3-8b --max-tokens 32768
# Estimate concurrent server slots.
mlxcel inspect -m ./models/qwen3-8b --max-tokens 8192 --batch 4
# Estimate INT8 KV cache.
mlxcel inspect -m ./models/qwen3-8b --kv-cache-mode int8
--quant fp16|int8|int4 labels the intended weight mode in the output. It does not rewrite the weight-byte total because mlxcel takes the safetensors header at face value and quantized checkpoints already encode their real on-disk tensor dtype and shape.
JSON Report¶
Use --json when a recipe builder, scheduler, or CI check needs machine-readable fit data:
The command writes exactly one JSON object to stdout on success. Resolution, download, and estimator errors still use the existing stderr path and exit nonzero, so a pipeline can treat stdout as parseable JSON only after the command succeeds.
The report fields are raw bytes unless noted otherwise:
| Field | Meaning |
|---|---|
mlxcel_version, model, model_type, family | Binary version, resolved model path, raw top-level config.json.model_type, and the registry family slug used by architecture metadata. |
inputs | Effective max_tokens, batch, kv_cache_mode, and quant labels used for the estimate. |
weights_bytes, weights_source | Weight footprint and whether it came from a safetensors header, analytical config estimate, or fallback. |
kv_bytes_per_token | FP16 and INT8 per-token KV rates when model geometry is available; turbo4 is null until the estimator models TurboQuant storage widths directly. |
kv_bytes_total, kv_detail | Total KV allocation for the requested context and batch, plus the architecture detail string shown in the text banner. |
per_slot_overhead_bytes | Paged-decode workspace reserve for default paged families; null for dense-default or unavailable geometry. |
activation_bytes, headroom_bytes, headroom_factor | Activation reserve, total runtime headroom (allocator overhead plus activation reserve plus backend in-flight reserve), and the multiplier used for allocator overhead. |
backend_inflight_bytes | Backend in-flight reserve included in headroom_bytes. Non-zero only on ROCm builds, where it equals MLX_ROCM_MAX_INFLIGHT_MB; the text banner prints it as a Backend in-flight line. |
host_shadow_bytes, host_ram_available_bytes, host_shadow_fits | Windows ROCm host-shadow reserve, the host RAM it is compared against, and whether it fits. 0, 0 (or the RAM figure) and true on other builds. |
budget_bytes, total_bytes, fits | Available-memory budget, total estimate, and the same fit boolean used by preflight checks. fits is false when either the device budget or the host-shadow comparison fails. |
Preflight Generation¶
mlxcel generate --estimate-memory runs after prompt rendering/tokenization and before model load. It sizes the KV cache from:
If the estimated total exceeds available memory, generation aborts before loading the model. Override only after checking the breakdown:
mlxcel generate \
--model ./models/qwen3-8b \
--prompt "Summarize this deployment plan." \
--max-tokens 1024 \
--estimate-memory
mlxcel generate ... --estimate-memory --force
--no-memory-check is an alias for --force.
Preflight Server Startup¶
mlxcel serve --estimate-memory and mlxcel-server --estimate-memory run before worker startup. They use the same server context semantics as runtime:
effective_context = floor(--ctx-size / active_slots)
active_slots = --max-batch-size when set, otherwise --n-parallel
With --no-batch, active_slots is 1. If --ctx-size is 0, the estimator uses its default 8192-token context length because the model-default context is not known until load time.
For this example, the server preflight sizes each active slot with an 8192-token context and a batch of 4. /health.context_size and /slots[].context_size report the same effective per-slot context window once the server is running.
Environment Variables¶
| Variable | Default | Effect |
|---|---|---|
MLXCEL_MEMORY_LIMIT | unset | Soft allocator memory cap. Nonzero values become the authoritative available-memory budget for inspect, --estimate-memory, and MLX runtime setup. Supports values such as 48GB, 512MB, or raw bytes. |
MLXCEL_HEADROOM_FACTOR | 1.20 | Allocator-overhead multiplier on weights + KV cache. It does not scale the activation reserve or the backend in-flight reserve. Positive values <= 1.0 disable the allocator-overhead term; invalid or non-positive values warn and fall back to the default. |
MLXCEL_ACTIVATION_MULT | 2.0 | Multiplier in the activation reserve batch x min(context, prefill chunk) x (hidden + intermediate) x 2 bytes. Invalid or non-positive values warn and fall back to the default. |
MLX_ROCM_MAX_INFLIGHT_MB | 1024 | ROCm builds only. Backend in-flight budget in MiB, reserved by the estimator as backend_inflight_bytes. 0 removes the backend bound, and the estimator then reserves nothing. |
Use MLXCEL_MEMORY_LIMIT for container, CI, or shared-host deployments where the OS-reported memory is not the real budget available to the process.
Relationship to Quantization Advice¶
--recommend-quant uses the same weight and KV-cache estimator as inspect and memory preflight. That keeps the recommendation, printed memory table, and startup refusal condition aligned for the same model directory and KV-cache mode.