This document is relevant for: Trn2, Trn3
determine_available_memory design#
1) KV cache budget#
By default, vLLM Neuron uses the memory-utilization and fractional-cap policy:
logical_core_hbm = hbm_stack_bytes / logical_cores_per_hbm_stack
total_budget = int(logical_core_hbm * gpu_memory_utilization)
user_budget = max(total_budget - model_weight_bytes, 0)
heuristic_cap = int(total_budget * cap_fraction)
available = max(min(user_budget, heuristic_cap), 0)
The default cap_fraction is 0.30. The worker respects
gpu_memory_utilization and VLLM_NEURON_KV_GMU_BUDGET_CAP_FRACTION.
This conservative policy limits the KV cache to a fraction of the memory-utilization budget.
An explicit headroom value enables the reserve policy:
available = max(logical_core_hbm - model_weight_bytes - headroom_bytes, 0)
hbm_stack_bytesis the HBM capacity reported for one physical stack.logical_cores_per_hbm_stackis 1 at LNC 2 and 2 at LNC 1.model_weight_bytesincludes model parameters and buffers.headroom_bytesreserves HBM per logical core for all other allocations.
The headroom includes internal tensors, scratchpad, DMA rings, runtime data, compiled code, and a safety margin.
Only headroom mode sets gpu_memory_utilization to 1.0 and bypasses the
fractional cap. An explicit zero also enables headroom mode.
2) Why headroom is necessary#
The compiler includes the KV cache shape in each compiled program. A larger KV cache changes the graph and its memory requirements.
The compiler gives the best estimate of non-KV memory after it receives a KV shape. However, the worker must select the KV shape before compilation. The worker therefore uses a configurable estimate for non-weight and non-KV memory.
In CPU inference, the default policy uses:
total_budget = int(host_available / local_workers * gpu_memory_utilization)
available = int(total_budget * cap_fraction)
Explicit headroom uses:
available = max(host_available / local_workers - headroom_bytes, 0)
Host available memory already excludes loaded weights and current allocations, so CPU mode does not subtract model weights again.
The reserve has no default. For example, 4 GiB is a tested reserve for GPT-OSS 120B on Trn3 with the Native backend and MXFP4 weights. Validate the reserve for your model and configuration.
3) Configuration#
Variable |
Default |
Description |
|---|---|---|
|
|
Fractional cap for default sizing. Headroom mode bypasses this value. |
|
unset |
Explicit reserve per worker. Enables headroom sizing on both routes. |
|
|
Minimum KV budget. The server stops if the budget is smaller. |
In headroom mode, increase the active reserve if model loading or compilation reports
NCC_EOOM002, Maximum peak HBM usage, NRT_RESOURCE in nrt_load_util, or
Allocation Failure. First confirm that the same configuration passes with a
smaller KV cache or with the default policy. Start with 1 GiB increments.
Each additional 1 GiB of headroom reduces the KV cache budget by 1 GiB. Rerun
the same model, sharding, backend, LNC degree, and hardware configuration, and
keep the smallest value that passes. Each backend deployment can use a
different value for the same headroom variable.
Do not increase headroom when the worker reports that the KV cache budget is below its minimum threshold. Decrease the active headroom variable for that error. A validated configuration can also decrease headroom to use a larger KV cache. At LNC 1, calculate the limit from half of the HBM stack:
maximum_headroom =
hbm_stack_bytes / 2 - model_weight_bytes - minimum_kv_budget
The startup log reports the logical-core HBM, model weights, active headroom, and resulting KV budget. An override at or above the logical-core HBM share leaves no usable KV cache.
Both backends and CPU use VLLM_NEURON_RESERVED_HEADROOM_GIB.
When this variable is unset, they use default fractional-cap sizing.
CPU compilation and device execution select the same budget policy.
In default mode, reduce the fractional cap to reduce KV capacity after an HBM allocation failure. An explicit headroom value changes the budget policy; validate the resulting KV capacity before deployment.
4) Implementation flow#
The implementation is in
vllm_neuron/vllm/worker/neuron_worker.py.
determine_available_memory()
|
+-- VLLM_NEURON_CPU_COMPILE == 1
| total_hbm = get_total_available_memory()
| model_weight_bytes = _get_byte_used_from_model()
| return _compute_kv_budget(total_hbm, model_weight_bytes)
|
+-- VLLM_NEURON_CPU_MODE == 1
| use the selected policy with the host memory fair share
|
+-- Neuron device
total_hbm = runtime_bytes_used + runtime_bytes_free
model_weight_bytes = _get_byte_used_from_model()
return _compute_kv_budget(total_hbm, model_weight_bytes)
CPU compilation and device execution use the same model weight calculation. This keeps the KV block count equal and permits compilation cache hits.
_compute_kv_budget(hbm_stack_bytes, model_weight_bytes):
logical_core_hbm = (
hbm_stack_bytes // get_logical_cores_per_hbm_stack()
)
if headroom is explicit:
available = max(
logical_core_hbm - model_weight_bytes - headroom_bytes, 0
)
else:
total_budget = int(logical_core_hbm * gpu_memory_utilization)
available = max(min(
max(total_budget - model_weight_bytes, 0),
int(total_budget * cap_fraction),
), 0)
if available < VLLM_NEURON_MIN_KV_BUDGET_GIB: raise RuntimeError
return available
The device path uses runtime statistics only to get total HBM. It does not use runtime memory usage as the model weight size.
The CPU inference path uses current available host memory, which already reflects model weights and other allocations. Neither CPU inference policy subtracts model weights again.
HBM stack sharing (LNC 1) scales the total first. One HBM stack serves 2 physical NeuronCores. At LNC 2 a logical core owns the stack. At LNC 1 two logical cores share it. Both inputs still report the whole stack. The runtime reports the stack to each core that holds a part of it, and the static table is per stack.
get_logical_cores_per_hbm_stack()gives the divisor, which is 1 at LNC 2 and 2 at LNC 1. Without it, two siblings each size a KV cache against the same memory, and the allocation fails at load (nrt_tensor_allocate status=4). The scaling is in_compute_kv_budget, so both paths that call it get the same budget. This keeps the KV block count equal, which the compile cache needs.CPU Compile only mode uses the static HBM size for the target platform (looked up via
NEURON_PLATFORM_TARGET_OVERRIDE) and computesbytes_usedfrom model parameter and buffer sizes. No device is present — the goal is to produce the same KV block count that the execution phase will use, ensuring compilation cache hits.Neuron mode (compile/execute) also uses
_get_byte_used_from_model()(model parameter + buffer sizes after model loading) rather than rawruntime.get_vnc_memory_stats()forbytes_used. This ensures the KV block count is identical between CPU compile and on-device execution. The runtime stats are only used to derivetotal_hbm_bytes.CPU mode (no compilation) is a separate path that uses host memory fair-share — it does not go through
_compute_kv_budgetand is unrelated to the compile/execute flow.An explicit headroom value reserves non-KV memory after the LNC share is known.
Minimum-KV guard fails fast for unusable configs.
5) Minimum budget check#
The worker compares both CPU and Neuron results with
VLLM_NEURON_MIN_KV_BUDGET_GIB. It stops early if the result is too small.
In default mode, the error names memory utilization and the fractional cap. In headroom mode, it names the active reserve and reports its maximum value. Increasing headroom makes a minimum-KV-budget error worse.
Known HBM allocation exceptions raised while loading, initializing the KV cache, compiling, or warming up retain their original exception and add a note with the active reserve and the 1 GiB tuning procedure in headroom mode.
This document is relevant for: Trn2, Trn3