Repository navigation
runner: keep the wired weights resident while the GPU idles - #2534
Open
AlexCheema wants to merge 1 commit into
Open
AlexCheema wants to merge 1 commit into
AlexCheema wants to merge 1 commit into
Conversation
macOS releases the residency of wired Metal allocations once the GPU has been idle for a second or two. The first request after a pause then re-wires the model's weights before its prefill can run: on a Mac Studio (M3 Ultra) about 7 ms per GB of weights, so seconds for a model of a few hundred GB. MLX 0.32.4 can re-request residency on a timer (MLX_METAL_RESIDENCY_REFRESH_INTERVAL_MS, a renewal thread that submits no GPU work). The runner now sets it to 500 ms next to MLX_METAL_FAST_SYNCH, keeping a value the user set (0 disables it). 8 real layers of GLM-5.3-4bit (30 GB, wired limit set as exo does), 512-token prefill, after an idle gap of 0 / 3 / 10 / 30 s: - unset: 191 / 236 / 443 / 446 ms - 500 ms: 192 / 212 / 220 / 225 ms (the rest is GPU clock ramp-up) - 2000 ms: 190 / 464 / 222 / 222 ms (residency already lost between renewals) Idle cost at 500 ms: 0.02 % of one CPU core; steady-state decode unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
AlexCheema
force-pushed
the
deps/mlx-0.32.4
branch
from
November 1, 2026 15:56
064b61d to
694f3db
Compare
AlexCheema
force-pushed
the
perf/mlx-residency-refresh
branch
from
November 1, 2026 19:34
2624680 to
de56aad
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds on #2508 (MLX 0.32.4), now merged into main.
Summary
macOS releases the residency of wired Metal allocations once the GPU has been idle for a second or two. The first request after a pause then has to re-wire the model's weights before its prefill can run. The cost is roughly proportional to the weights: about 7 ms per GB on a Mac Studio (M3 Ultra), so seconds for a model of a few hundred GB. Every request that arrives after a short pause pays it: a chat user typing, or a benchmark with a cooldown between requests.
MLX 0.32.4 can re-request residency on a timer.
MLX_METAL_RESIDENCY_REFRESH_INTERVAL_MSruns a renewal thread that submits no GPU work. The runner now sets it to 500 ms, next toMLX_METAL_FAST_SYNCH, before MLX creates its Metal device.0disables the renewal.Measurements
Mac Studio (M3 Ultra, 512 GB). The wired limit is set as exo sets it (
mx.set_wired_limitto the recommended working set). Each cell is a 512-token prefill after the given idle gap (each followed by a back-to-back control at ~191 ms).8 real layers of GLM-5.3-4bit (30 GB of weights):
mx.set_wired_limitthe same gaps cost ~55 ms flat. The penalty comes from the wired allocations.Control: Qwen3-1.7B-4bit (1 GB), 10 s gap: 137 ms unset vs 105 ms at 500 ms (back to back: 70-77 ms).
Full model: GLM-5.3-4bit (418 GB) on one M3 Ultra Mac Studio, 512-token requests through the API, 10 s cooldown between requests, 4 requests after a warm-up:
Cost of the renewal:
Test plan
uv run basedpyright,uv run ruff check,nix fmt,uv run pytest.test_residency_refresh.py):0;configure_mlx_environment) sets the variable and keeps a user's value.🤖 Generated with Claude Code