Repository navigation
fix(rocm): reserve the in-flight budget in the pre-load memory estimate - #2195
Conversation
On ROCm the estimate behind `mlxcel inspect`, `--estimate-memory` and `--recommend-quant` was below the measured peak: for Llama-3.1-8B-4bit at 640 tokens it was 5,579,686,809 bytes against a peak of at most 6,145,000,000. Committed but unfinished command batches may hold up to `MLX_ROCM_MAX_INFLIGHT_MB` of transients, and nothing in the estimate modeled them. ROCm builds now add that budget as `backend_inflight_bytes`, parsed exactly as the overlay's `max_inflight_bytes()` parses it (strtoull semantics, invalid values fall back to 1024 MiB, `0` adds nothing). The term is gated with `#[cfg(feature = "rocm")]`, so Metal and CUDA totals are unchanged. It is part of `total_bytes` and `runtime_headroom_bytes`, printed as `Backend in-flight` by `inspect`, carried in the JSON report, and subtracted by the paged KV `auto` budget so that budget still satisfies the fit inequality. Measured on gfx1151 for Llama-3.1-8B, Qwen2.5-7B and Qwen3-30B-A3B at 640 and 4096 tokens with budgets 256, 1024 and 4096 MiB, guarded: the estimate now covers all 18 peaks (it missed 9 before). A test pins that table and fails without the term. Closes #2155
Implementation Review SummaryIntent
Findings AddressedNone needed fixing at CRITICAL or HIGH. I checked Remaining Items
Verification
|
The --recommend-quant advisor reads only the weight and KV figures of the estimate, so it does not see the ROCm in-flight term; the env-var page no longer says it does. The memory_estimate module doc now lists the backend in-flight term with the other components. Refs #2155
|
Security and performance review of the in-flight reserve change: no CRITICAL or HIGH findings, no commits made.
|
EnvGuard saved the previous value with std::env::var, which drops a non-UTF-8 value and then removed the variable on drop. It now saves and restores the OsString. Refs #2155
The test file added by #2195 (`src/execution/memory_estimate_inflight_tests.rs`) lacks the project license header, so the `license headers` job fails on `main` (run 37569698228) and on every PR CI run merged with it, for example #2194. This inserts the standard header with `python3 scripts/insert_apache_header.py`; `--check` now passes. No code change. The other failure on recent `main` runs, `WebUI installed artifact`, is unrelated: the GB10 runner could not obtain the host `gpu-lock` within 600 seconds because development benchmarks on that host held it (`issue-2190-bench-31b-b2`, `issue-2191-throughput`).
Summary
On ROCm the pre-load memory estimate (
mlxcel inspect,--estimate-memory, the paged KVautobudget, the prompt-cache capacity defaults) was below the measured peak for dense models, because committed but unfinished command batches may hold up toMLX_ROCM_MAX_INFLIGHT_MBof transients and nothing modeled them. ROCm builds now add that budget as its own term; Metal and CUDA totals are unchanged.rocm_inflight_reserve_bytesparses the variable exactly as the overlay'smax_inflight_bytes()does (strtoull semantics: leading whitespace and+accepted, a leading-, suffix or overflow falls back to 1024 MiB,0adds nothing). A test readsdevice.cppand fails if the default or the variable name drifts.#[cfg(feature = "rocm")], like the cache-limit default inruntime.rs, so the estimator stays side-effect-free. It is intotal_bytesandruntime_headroom_bytes, printed asBackend in-flight(only when non-zero), and carried asbackend_inflight_bytesininspect --json.autobudget subtracts the reserve, so the budget it picks still fits the estimate.--recommend-quantis unaffected: it reads only the estimate's weight and KV figures (the env-var page said otherwise in the first revision; corrected during review).Units: the issue's correction does not hold. The page's 5.58 is
total_bytes / 1e9(inspectprints 5.20 GiB, 5,579,686,809 bytes), so the original 0.56 GB gap was real. All comparisons below are in bytes.Verification (gfx1151)
scripts/rocm_gpu_guard.sh, one clean run per row) for Llama-3.1-8B, Qwen2.5-7B and Qwen3-30B-A3B at 640 and 4096 tokens with budgets 256, 1024 and 4096 MiB: before the change the estimate missed 9 of the 18 peaks; now it covers all 18, the smallest margin being 221,877,772 bytes (Llama, 4096 tokens, default). The table and raw lines are indocs/benchmark_results/rocm-memory-gfx1151-2026-09-30.md, "Estimate against peak".rocm_estimate_covers_every_measured_gfx1151_peakrebuilds all 18 estimates (equal toinspectbyte for byte) and asserts estimate >= peak bound. With the term forced to 0, it and two other tests fail.cargo test --features rocm --lib -- execution::memory_estimate server::prompt_cache::snapshot_sizing(70 passed), clippy on lib and tests with-D warnings,dead_doc_pointers, and the fastmake verify-*script gates pass. Fullmake verify-rocmat9374ae72(on main87538835): OK, 12004 passed, 0 failed, 384 ignored over 153 test binaries.Not verified: Metal and CUDA (not available on this host). On those builds the code path is the
#[cfg(not(feature = "rocm"))]stub that returns 0, plus the new zero-valued field and JSON key;non_rocm_estimate_reserves_nothing_for_inflightwas not compiled or run here.Closes #2155