Repository navigation
[ROCm][Bugfix] W4A16 dense cache: count cached allocator blocks as free in the budget check - #1411
Merged
Merged
Conversation
eble-amd
reviewed
Oct 28, 2026
Signed-off-by: Zohaib Moti <zohaib.moti@amd.com>
zohaibm-amd
force-pushed
the
zohaibm.w4a16-dequant-budget-empty-cache
branch
from
October 29, 2026 15:36
624e869 to
43b34c0
Compare
Signed-off-by: Zohaib Moti <zohaib.moti@amd.com>
eble-amd
approved these changes
Oct 29, 2026
6 tasks done
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.
Overview
Follow-up to #1410. With
kernel_config.rdna_hybrid_w4a16_prefill_dequant=enable, the per-layer budget check_fits_in_memory_budgetreads device-wide free memory. That reading counts blocks the torch caching allocator holds after load-time temporaries (checkpoint loading, int4 unpack/dequant scratch) as used. Those blocks are reusable by the next allocation, and the allocator releases them itself if an allocation would otherwise fail. vLLM's KV-cache sizing already excludes them (memory_profilingmeasures afterempty_cache()). As a result the check over-reserves, and a model that fits fails at startup withNot enough room in the gpu_memory_utilization budget ....This change counts
reserved - allocated(already captured byMemorySnapshotastorch_memory - torch_allocated) as free. It adds no flush or device sync, so neither load time nor runtime changes, and the result no longer depends on allocator state.An earlier revision of this PR flushed the cache with
torch.accelerator.empty_cache()when the check came up short. That also worked, but it costs a sync plus fresh device allocations, and it would also run if weights were re-processed at runtime (weight reload, sleep/wake).Why keep the check at all
The dense copies are 4x their int4 weights and come out of the KV budget. Without the check, a config that does not fit fails later, either with the generic KV-sizing error or with an OOM mid-load, and neither names this option. The copy set must also be all-or-nothing, because the compile cache key does not record which layers hold a copy.
Measurements (gfx1151, 96 GiB device memory, CI wheel + this change)
Gemma-4-31B AWQ-4bit, MTP-3 draft,
max_model_len=4096,gpu_memory_utilization=0.99:Peak need with allocator cache excluded, for the other prefill-dequant configs we run (all fit their budgets):
Rejected alternatives:
PYTORCH_ALLOC_CONF=expandable_segments:Trueis worse: 55.7 GiB cached-free, 55 failures.garbage_collection_thresholdhas no effect, because it needs a per-process memory fraction that vLLM does not set.Serving performance is unaffected; the check only runs while weights load. A/B against the pre-#1410
hardbuild, with the same torch/triton ROCm nightly, 10 MMStar prompts and max_num_seqs=1: mean TTFT 939.3 vs 942.7 ms, mean TPOT 35.30 vs 35.45 ms, MTP acceptance 2.82 in both.Tests
tests/kernels/quantization/test_rdna_hybrid_w4a16.py -k prefill_dequant: 20 passed.torch_memory/torch_allocated.empty_cacheis never called.