From 1e91a6ab0ce0c33429f585457b0b6e54e864e4e2 Mon Sep 17 00:00:00 2001 From: Krzysztof Smusz Date: Wed, 8 Oct 2025 16:17:59 +0200 Subject: [PATCH] [Docs] README update - bucketing, warmup, defragmenter and sampler warmup (#353) Porting https://github.com/vllm-project/vllm-gaudi/pull/231 and https://github.com/vllm-project/vllm-gaudi/pull/278 --------- Signed-off-by: Krzysztof Smusz Co-authored-by: Agata Dobrzyniewicz <160237065+adobrzyn@users.noreply.github.com> Co-authored-by: Yaser Afshar --- .../graphs/exponential_bucketing_example.png | Bin 0 -> 99919 bytes .../graphs/unified_bucketing_example.png | Bin 0 -> 24883 bytes docs/configuration/env_vars.md | 58 ++--- docs/features/bucketing_mechanism.md | 186 +++++++-------- docs/features/warmup.md | 225 ++++++++++++++++++ 5 files changed, 331 insertions(+), 138 deletions(-) create mode 100755 docs/assets/graphs/exponential_bucketing_example.png create mode 100755 docs/assets/graphs/unified_bucketing_example.png create mode 100644 docs/features/warmup.md diff --git a/docs/assets/graphs/exponential_bucketing_example.png b/docs/assets/graphs/exponential_bucketing_example.png new file mode 100755 index 0000000000000000000000000000000000000000..02dd0c2c72668f510703ff8a2d9cb9d7006cc78b GIT binary patch literal 99919 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
-|-TS$-`e%FpHH%koW3eemXC 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 L^Q7Kz+n4Y==>Y-W literal 0 HcmV?d00001 diff --git a/docs/configuration/env_vars.md b/docs/configuration/env_vars.md index 4f37c185..8451c7a6 100644 --- a/docs/configuration/env_vars.md +++ b/docs/configuration/env_vars.md @@ -14,40 +14,9 @@ **Performance Tuning Knobs:** -- `VLLM_SKIP_WARMUP`: if `true`, warmup is skipped. The default is `false`. - `VLLM_GRAPH_RESERVED_MEM`: percentage of memory dedicated to HPUGraph capture. The default is `0.1`. -- `VLLM_GRAPH_PROMPT_RATIO`: percentage of reserved graph memory dedicated to prompt graphs. The default is `0.3`. -- `VLLM_GRAPH_PROMPT_STRATEGY`: strategy determining order of prompt graph capture, `min_tokens` or `max_bs`. The default is `min_tokens`. -- `VLLM_GRAPH_DECODE_STRATEGY`: strategy determining order of decode graph capture, `min_tokens` or `max_bs`. The default is `max_bs`. - `VLLM_EXPONENTIAL_BUCKETING`: if `true`, enables exponential bucket spacing instead of linear. The default is `true`. -- `VLLM_{phase}_{dim}_BUCKET_{param}`: collection of 12 environment variables configuring ranges of bucketing mechanism (linear bucketing only). - - `{phase}` is either `PROMPT` or `DECODE` - - `{dim}` is either `BS`, `SEQ` or `BLOCK` - - `{param}` is either `MIN`, `STEP` or `MAX` - - Default values: - - Prompt: - - batch size min (`VLLM_PROMPT_BS_BUCKET_MIN`): `1` - - batch size step (`VLLM_PROMPT_BS_BUCKET_STEP`): `min(max_num_seqs, 32)` - - batch size max (`VLLM_PROMPT_BS_BUCKET_MAX`): `min(max_num_seqs, 64)` - - sequence length min (`VLLM_PROMPT_SEQ_BUCKET_MIN`): `block_size` - - sequence length step (`VLLM_PROMPT_SEQ_BUCKET_STEP`): `block_size` - - sequence length max (`VLLM_PROMPT_SEQ_BUCKET_MAX`): `1024` - - sequence ctx min (`VLLM_PROMPT_CTX_BUCKET_MIN`): `0` - - sequence ctx step (`VLLM_PROMPT_CTX_BUCKET_STEP`): `1` - - sequence ctx max (`VLLM_PROMPT_CTX_BUCKET_MAX`): `(max_model_len - block_size) // block_size` - - Decode: - - batch size min (`VLLM_DECODE_BS_BUCKET_MIN`): `1` - - batch size step (`VLLM_DECODE_BS_BUCKET_STEP`): `min(max_num_seqs, 32)` - - batch size max (`VLLM_DECODE_BS_BUCKET_MAX`): `max_num_seqs` - - block size min (`VLLM_DECODE_BLOCK_BUCKET_MIN`): `block_size` - - block size step (`VLLM_DECODE_BLOCK_BUCKET_STEP`): `block_size` - - block size max (`VLLM_DECODE_BLOCK_BUCKET_MAX`): `max(128, (max_num_seqs*2048)/block_size)` - - Recommended Values: - - Prompt: - - sequence length max (`VLLM_PROMPT_SEQ_BUCKET_MAX`): `max_model_len` - - Decode: - - - block size max (`VLLM_DECODE_BLOCK_BUCKET_MAX`): `max(128, (max_num_seqs*max_model_len/block_size)` +- `VLLM_SKIP_WARMUP`: if `true`, warmup is skipped. The default is `false`. !!! note If the model config reports a high `max_model_len`, set it to max `input_tokens+output_tokens` rounded up to a multiple of `block_size` as per actual requirements. @@ -69,3 +38,28 @@ Additionally, there are HPU PyTorch Bridge environment variables impacting vLLM - `PT_HPU_ENABLE_LAZY_COLLECTIVES`: must be set to `true` for tensor parallel inference with HPU Graphs. The default is `true`. - `PT_HPUGRAPH_DISABLE_TENSOR_CACHE`: must be set to `false` for LLaVA, qwen, and RoBERTa models. The default is `false`. - `VLLM_PROMPT_USE_FLEX_ATTENTION`: enabled only for the Llama model, allowing usage of `torch.nn.attention.flex_attention` instead of FusedSDPA. Requires `VLLM_PROMPT_USE_FUSEDSDPA=0`. The default is `false`. + +**Additional Performance Tuning Knobs - Linear Bucketing Strategy only:** + +- `VLLM_{phase}_{dim}_BUCKET_{param}`: collection of 12 environment variables configuring ranges of bucketing mechanism (linear bucketing only). + - `{phase}` is either `PROMPT` or `DECODE` + - `{dim}` is either `BS`, `SEQ` or `BLOCK` + - `{param}` is either `MIN`, `STEP` or `MAX` + - Default values: + - Prompt: + - batch size min (`VLLM_PROMPT_BS_BUCKET_MIN`): `1` + - batch size step (`VLLM_PROMPT_BS_BUCKET_STEP`): `32` + - batch size max (`VLLM_PROMPT_BS_BUCKET_MAX`): `max_num_prefill_seqs` + - sequence length min (`VLLM_PROMPT_SEQ_BUCKET_MIN`): `block_size` + - sequence length step (`VLLM_PROMPT_SEQ_BUCKET_STEP`): `block_size` + - sequence length max (`VLLM_PROMPT_SEQ_BUCKET_MAX`): `max_model_len` + - sequence ctx min (`VLLM_PROMPT_CTX_BUCKET_MIN`): `0` + - sequence ctx step (`VLLM_PROMPT_CTX_BUCKET_STEP`): `1` + - sequence ctx max (`VLLM_PROMPT_CTX_BUCKET_MAX`): `(max_model_len - block_size) // block_size` + - Decode: + - batch size min (`VLLM_DECODE_BS_BUCKET_MIN`): `1` + - batch size step (`VLLM_DECODE_BS_BUCKET_STEP`): `32` + - batch size max (`VLLM_DECODE_BS_BUCKET_MAX`): `max_num_seqs` + - block size min (`VLLM_DECODE_BLOCK_BUCKET_MIN`): `block_size` + - block size step (`VLLM_DECODE_BLOCK_BUCKET_STEP`): `block_size` + - block size max (`VLLM_DECODE_BLOCK_BUCKET_MAX`): `max_blocks` diff --git a/docs/features/bucketing_mechanism.md b/docs/features/bucketing_mechanism.md index 88d1f7d8..6a98cdc2 100644 --- a/docs/features/bucketing_mechanism.md +++ b/docs/features/bucketing_mechanism.md @@ -9,23 +9,69 @@ Intel Gaudi accelerators perform best when operating on models with fixed tensor generates optimized binary code that implements the given model topology on Gaudi. In its default configuration, the produced binary code may be highly dependent on input and output tensor shapes, requiring graph recompilation when encountering tensors with different shapes within the same topology. While these binaries efficiently utilize Gaudi, the compilation process itself can introduce noticeable overhead in end-to-end execution. In dynamic inference serving scenarios, minimizing the number of graph compilations and reducing the risk of graph compilation occurring during server runtime is important. Currently, this is achieved by -"bucketing" the model's forward pass across two dimensions: `batch_size` and `sequence_length`. +"bucketing" the model's forward pass across three dimensions. -!!! note - Bucketing helps significantly reduce the number of required graphs, but does not handle graph compilation or device code generation. These tasks are performed during the warmup and HPUGraph capture phase. +> [!NOTE] +> Bucketing helps significantly reduce the number of required graphs, but does not handle graph compilation or device code generation. These tasks are performed during the warmup and HPUGraph capture phase. + +## Bucketing Strategies + +Bucketing is focused on three dimensions: +- `batch size`: number of samples in batch +- `query lenght`: sequence length without context tokens +- `num blocks`: context length counted in blocks -Bucketing ranges are determined with 3 parameters - `min`, `step`, and `max`. They can be set separately for the prompt and decode phase, and batch size and sequence length dimensions. These parameters -can be observed in logs during vLLM startup: +Bucketing ranges are generated based on 4 parameters - `min`, `step`, `max` and `limit`, separately for the prompt and decode phase, and batch size, query length and context blocks dimensions. These parameters can be observed in logs during vLLM startup: ```{.} -INFO 08-01 21:37:59 hpu_model_runner.py:493] Prompt bucket config (min, step, max_warmup) bs:[1, 32, 4], seq:[128, 128, 1024] -INFO 08-01 21:37:59 hpu_model_runner.py:499] Generated 24 prompt buckets: [(1, 128), (1, 256), (1, 384), (1, 512), (1, 640), (1, 768), (1, 896), (1, 1024), (2, 128), (2, 256), (2, 384), (2, 512), (2, 640), (2, 768), (2, 896), (2, 1024), (4, 128), (4, 256), (4, 384), (4, 512), (4, 640), (4, 768), (4, 896), (4, 1024)] -INFO 08-01 21:37:59 hpu_model_runner.py:504] Decode bucket config (min, step, max_warmup) bs:[1, 128, 4], seq:[128, 128, 2048] -INFO 08-01 21:37:59 hpu_model_runner.py:509] Generated 48 decode buckets: [(1, 128), (1, 256), (1, 384), (1, 512), (1, 640), (1, 768), (1, 896), (1, 1024), (1, 1152), (1, 1280), (1, 1408), (1, 1536), (1, 1664), (1, 1792), (1, 1920), (1, 2048), (2, 128), (2, 256), (2, 384), (2, 512), (2, 640), (2, 768), (2, 896), (2, 1024), (2, 1152), (2, 1280), (2, 1408), (2, 1536), (2, 1664), (2, 1792), (2, 1920), (2, 2048), (4, 128), (4, 256), (4, 384), (4, 512), (4, 640), (4, 768), (4, 896), (4, 1024), (4, 1152), (4, 1280), (4, 1408), (4, 1536), (4, 1664), (4, 1792), (4, 1920), (4, 2048)] +INFO 07-07 19:27:37 [exponential.py:36] Prompt bucket config (min, step, max_warmup, limit) bs:[1, 1, 1, 1], seq:[128, 128, 1024, 11] +INFO 07-07 19:27:37 [common.py:85] Generated 36 prompt buckets [bs, query, num_blocks]: [(1, 128, 0), (1, 128, 1), (1, 128, 2), (1, 128, 3), (1, 128, 4), (1, 128, 5), (1, 128, 6), (1, 128, 7), (1, 256, 0), (1, 256, 1), (1, 256, 2), (1, 256, 3), (1, 256, 4), (1, 256, 5), (1, 256, 6), (1, 384, 0), (1, 384, 1), (1, 384, 2), (1, 384, 3), (1, 384, 4), (1, 384, 5), (1, 512, 0), (1, 512, 1), (1, 512, 2), (1, 512, 3), (1, 512, 4), (1, 640, 0), (1, 640, 1), (1, 640, 2), (1, 640, 3), (1, 768, 0), (1, 768, 1), (1, 768, 2), (1, 896, 0), (1, 896, 1), (1, 1024, 0)] +INFO 07-07 19:27:37 [common.py:85] Generated 42 decode buckets [bs, query, num_blocks]: [(1, 1, 128), (1, 1, 256), (1, 1, 384), (1, 1, 512), (1, 1, 640), (1, 1, 768), (1, 1, 896), (1, 1, 1024), (1, 1, 1408), (1, 1, 1792), (1, 1, 2432), (1, 1, 3328), (1, 1, 4352), (1, 1, 5888), (2, 1, 128), (2, 1, 256), (2, 1, 384), (2, 1, 512), (2, 1, 640), (2, 1, 768), (2, 1, 896), (2, 1, 1024), (2, 1, 1408), (2, 1, 1792), (2, 1, 2432), (2, 1, 3328), (2, 1, 4352), (2, 1, 5888), (4, 1, 128), (4, 1, 256), (4, 1, 384), (4, 1, 512), (4, 1, 640), (4, 1, 768), (4, 1, 896), (4, 1, 1024), (4, 1, 1408), (4, 1, 1792), (4, 1, 2432), (4, 1, 3328), (4, 1, 4352), (4, 1, 5888)] ``` -`min` determines the lowest value of the bucket. `step` determines the interval between buckets, and `max` determines the upper bound of the bucket. Furthermore, the interval between `min` and `step` has special handling - `min` gets multiplied by consecutive powers of two, until the multiplier is less than or equal to `step`. We call this the ramp-up phase, and it is used for handling lower batch sizes with minimum wastage, -while allowing larger padding on larger batch sizes. +> [!WARNING] +> If a request exceeds the maximum bucket size in any dimension, it will be processed without padding, and its processing may require a graph compilation, potentially significantly increasing end-to-end latency. +The boundaries of the buckets are user-configurable via environment variables, and upper bucket boundaries can be increased to avoid such scenario. + +For example, if a request with 3 sequences, each having a maximum sequence length of 412, is sent to an idle vLLM server, it will be padded and executed as a `(4, 512, 0)` prefill bucket, WHERE 4=bs, 512 .... This is because the `batch_size` +(number of sequences) will be padded to 4 (the nearest batch size dimension higher than 3), and the maximum sequence length will be padded to 512 (the nearest sequence length dimension higher than 412). After the +prefill stage, it will be executed as a `(4, 1, 512)` decode bucket and will remain in this bucket until either the batch dimension changes (e.g., due to a request being completed), in which case it will become +a `(2, 1, 512)` bucket, or the context length increases beyond 512 tokens. It will become a `(4, 1, 640)` bucket at that point. + +> [!NOTE] +> Bucketing is transparent to the user – padding in the sequence length dimension is never returned, and padding in the batch dimension does not create new requests. + +### Exponential Strategy - Default + +Exponential strategy is the default warm-up mechanism. It is based on 4 parameters: +- `min`: the smallest value +- `step`: the rounding value for bucket boundaries +- `max`: the largest value +- `limit`: the maximum number of buckets + +> [!WARNING] +> These parameters are not configurable by the user. + +The exponential bucketing strategy applies exponential spacing between buckets. The `min` and `max` values are always included in the warm-up, and the intermediate values are calculated using an exponent. The base remains unchanged. If duplicate values are generated, they are removed to ensure the warm-up process is as efficient as possible. All the values generated in this way, ranging from batch size, query length and context blocks, will be warmed up with each other. + +Example distribution is shown below: + +```{.} +min = 128, step = 128, max = 4096, limit = 13 +``` + +![exponential bucketing distribution for 4096 max query length](../../docs/assets/graphs/exponential_bucketing_example.png) + +This strategy creates more buckets with smaller values closer to `min`. As the values increase toward `max`, the buckets become less frequent, meaning the distance between them gets larger. This helps prioritize warming up the smaller values more precisely, while still covering the full range. + +### Linear Strategy + +> [!NOTE] +> Starting from v1.22.0 Intel Gaudi Software release, Linear strategy is no longer the default warm-up mechanism. + +Linear strategy is determined with 3 parameters only - `min`, `step` and `max`. They can be set separately for the prompt and decode phase, and batch size and sequence length dimensions, by user. + +`min` determines the lowest value of the bucket. `step` determines the interval between buckets, and `max` determines the upper bound of the bucket. Furthermore, the interval between `min` and `step` has special handling: `min` is multiplied by consecutive powers of two until the multiplier is less than or equal to `step`. We refer to this as the ramp-up phase, which is used for handling lower batch sizes with minimal wastage, while allowing for larger padding on larger batch sizes. **Example with ramp-up** @@ -45,115 +91,43 @@ min = 128, step = 128, max = 512 => buckets = ramp_up + stable => (128, 256, 384, 512) ``` -In the logged scenario, 24 buckets were generated for prompt (prefill) runs, and 48 buckets for decode runs. Each bucket corresponds to a separate optimized device binary for a given model with specified tensor -shapes. Whenever a batch of requests is processed, it is padded across batch and sequence length dimension to the smallest possible bucket. +### Unified Strategy -> [!WARNING] -> If a request exceeds the maximum bucket size in any dimension, it will be processed without padding, and its processing may require a graph compilation, potentially significantly increasing end-to-end latency. -The boundaries of the buckets are user-configurable via environment variables, and upper bucket boundaries can be increased to avoid such scenario. +Unified strategy is dedicated strategy for Unified Attention. It's buckets are determined by different dimensions: +- `query length`: number of currently processed tokens, without context tokens +- `shared num blocks`: context length counted in blocks, including only blocks that are either shared between at least two block tables (different requests) or is used by at least two tokens in query +- `unique num blocks`: context length counted in blocks, including only blocks that are not shared between block tables and are used only by one token +- `is causal`: only two possible values: 0 and 1. Causal determines if there is at least one prompt in batch -For example, if a request with 3 sequences, each having a maximum sequence length of 412, is sent to an idle vLLM server, it will be padded and executed as a `(4, 512)` prefill bucket. This is because the `batch_size` -(number of sequences) will be padded to 4 (the nearest batch size dimension higher than 3), and the maximum sequence length will be padded to 512 (the nearest sequence length dimension higher than 412). After the -prefill stage, it will be executed as a `(4, 512)` decode bucket and will remain in this bucket until either the batch dimension changes (e.g., due to a request being completed), in which case it will become -a `(2, 512)` bucket, or the context length increases beyond 512 tokens. It will become a `(4, 640)` bucket at that point. +Unified bucketing prepares buckets for both prompt and decode as one, known as `unified cfg`. -> [!NOTE] -> Bucketing is transparent to the user – padding in the sequence length dimension is never returned, and padding in the batch dimension does not create new requests. +> [!WARNING] +> No parameters for unified warmup are configurable by the user. -## Warmup +**Alpha Version:** -Warmup is an optional but highly recommended step that occurs before the vLLM server starts listening. It executes a forward pass for each bucket using dummy data. The goal is to pre-compile all graphs -and avoid any graph compilation overhead within bucket boundaries during server runtime. Each warmup step is logged during vLLM startup. +Currently there are six points in ranges for query length, shared blocks and unique blocks. They are based on `max num seqs` and `max num batched tokens` values. Points are as follows whole, half and one quarter of both values resulting in six points in total. -This example uses the same buckets as those in the Bucketing Mechanism section. Each output line corresponds to the execution of a single bucket. When a bucket is executed for the first time, its graph -is compiled and can be reused later, avoiding further graph compilations. +Example distribution is shown below: ```{.} -INFO 08-01 22:26:47 hpu_model_runner.py:1066] [Warmup][Prompt][1/24] batch_size:4 seq_len:1024 free_mem:79.16 GiB -INFO 08-01 22:26:47 hpu_model_runner.py:1066] [Warmup][Prompt][2/24] batch_size:4 seq_len:896 free_mem:55.43 GiB -INFO 08-01 22:26:48 hpu_model_runner.py:1066] [Warmup][Prompt][3/24] batch_size:4 seq_len:768 free_mem:55.43 GiB -... -INFO 08-01 22:26:59 hpu_model_runner.py:1066] [Warmup][Prompt][24/24] batch_size:1 seq_len:128 free_mem:55.43 GiB -INFO 08-01 22:27:00 hpu_model_runner.py:1066] [Warmup][Decode][1/48] batch_size:4 seq_len:2048 free_mem:55.43 GiB -INFO 08-01 22:27:00 hpu_model_runner.py:1066] [Warmup][Decode][2/48] batch_size:4 seq_len:1920 free_mem:55.43 GiB -INFO 08-01 22:27:01 hpu_model_runner.py:1066] [Warmup][Decode][3/48] batch_size:4 seq_len:1792 free_mem:55.43 GiB -... -INFO 08-01 22:27:16 hpu_model_runner.py:1066] [Warmup][Decode][47/48] batch_size:2 seq_len:128 free_mem:55.43 GiB -INFO 08-01 22:27:16 hpu_model_runner.py:1066] [Warmup][Decode][48/48] batch_size:1 seq_len:128 free_mem:55.43 GiB +batch size = 64, max num batched tokens = 4096 ``` -> [!TIP] -> Compiling all the buckets may take some time and can be disabled by setting the `VLLM_SKIP_WARMUP=true` environment variable. Remember that if you do this, you may encounter graph compilations -when executing a given bucket for the first time. +![exponential bucketing distribution for 4096 max query length](../../docs/assets/graphs/unified_bucketing_example.png) -> [!WARNING] -> Disabling warmup is fine for development, but it is highly recommended to enable it in deployment. - -## HPU Graph Capture - -[HPU Graphs](https://docs.habana.ai/en/latest/PyTorch/Inference_on_PyTorch/Inference_Using_HPU_Graphs.html) are currently the most performant execution method of vLLM on Intel Gaudi. When HPU Graphs are enabled, -execution graphs will be traced (recorded) ahead of time (after performing warmup), to be later replayed during inference, significantly reducing host overheads. Recording can take large amounts of memory, which -needs to be taken into account when allocating KV cache. Enabling HPU Graphs will impact the number of available KV cache blocks, but vLLM provides user-configurable variables to control memory management. - -When HPU Graphs are used, they share the common memory pool ("usable memory") with the KV cache, as determined by the `gpu_memory_utilization` flag (default value is `0.9`). Before the KV cache is allocated, -the model weights are loaded onto the device, and a forward pass of the model is executed on dummy data to estimate memory usage. Only after that, the `gpu_memory_utilization` flag is applied. At its default value, -it marks 90% of the free device memory at that point as usable. Next, the KV cache is allocated, the model is warmed up, and HPU Graphs are captured. The `VLLM_GRAPH_RESERVED_MEM` environment variable defines -the ratio of memory reserved for HPU Graph capture. With its default value (`VLLM_GRAPH_RESERVED_MEM=0.1`), 10% of the usable memory will be reserved for graph capture (referred to as "usable graph memory"), -and the remaining 90% will be used for the KV cache. The environment variable `VLLM_GRAPH_PROMPT_RATIO` determines the ratio of usable graph memory reserved for prefill and decode graphs. A lower value corresponds to less usable graph memory reserved for the prefill stage. For example, setting `VLLM_GRAPH_PROMPT_RATIO=0.2` -reserves 20% of usable graph memory for prefill graphs, while 80% is allocated for decode graphs. - -> [!NOTE] -> `gpu_memory_utilization` does not represent the absolute memory usage across the HPU. Instead, it specifies the memory margin after loading the model and running a profile. For example, if a device has 100 GiB of -total memory and 50 GiB of free memory after loading the model weights and executing the profiling run, the default value of `gpu_memory_utilization` will mark 90% of the 50 GiB as usable, leaving 5 GiB as a margin, -regardless of the total device memory. +Additionaly for context blocks, both shared and unique, `0` value will be added as well. -You can also configure the strategy for capturing HPU graphs separately for the prompt and decode stages. The strategy affects the order in which graphs are captured. Two strategies are implemented: +This way our bucketing will look like this: -- `max_bs` - The graph capture queue is sorted in descending order by batch size. Buckets with equal batch sizes are sorted by sequence length in ascending order - (e.g., `(64, 128)`, `(64, 256)`, `(32, 128)`, `(32, 256)`, `(1, 128)`, `(1,256)`), which is the default strategy for decode. -- `min_tokens` - The graph capture queue is sorted in ascending order by the number of tokens each graph processes (`batch_size*sequence_length`), which is the default strategy for prompt. - -When many requests are pending, the vLLM scheduler attempts to fill the maximum batch size for decoding as quickly as possible. Once a request is finished, the decode batch size decreases. -When this happens, vLLM attempts to schedule a prefill iteration for requests in the waiting queue to restore the decode batch size to its previous state. In a fully loaded scenario, the decode -batch size is often at its maximum, making large-batch HPU graphs critical to capture, as indicated by the `max_bs` strategy. Conversely, prefill iterations will typically be executed with very low -batch sizes (1-4), as reflected in the `min_tokens` strategy. - -> [!NOTE] -> `VLLM_GRAPH_PROMPT_RATIO` does not set a hard limit on the memory allocated for graphs in each stage (prefill and decode). vLLM first attempts to use the entire usable prefill graph memory -(usable graph memory * VLLM_GRAPH_PROMPT_RATIO) to capture prefilled HPU graphs. It will then attempt to do the same for decode graphs and the usable decode graph memory pool. If one stage is fully -captured and there is unused memory remaining in the usable graph memory pool, vLLM will attempt to capture more graphs for the other stage, until no more HPU Graphs can be captured without exceeding -the reserved memory pool. The behavior of this mechanism is illustrated in the example below. +```{.} +INFO 09-23 12:32:43 [common.py:100] Generated 375 unified buckets [query, shared_blocks, unique_blocks]: [(8, 0, 0, 1), (8, 0, 8, 0), ..., (2048, 256, 2890, 1), (2048, 256, 5781, 1)] +``` -Each step outlined is logged by the vLLM server, with negative values indicating memory release: +With every bucket logged separately in warm-up phase: ```{.} -INFO 08-02 17:37:44 hpu_model_runner.py:493] Prompt bucket config (min, step, max_warmup) bs:[1, 32, 4], seq:[128, 128, 1024] -INFO 08-02 17:37:44 hpu_model_runner.py:499] Generated 24 prompt buckets: [(1, 128), (1, 256), (1, 384), (1, 512), (1, 640), (1, 768), (1, 896), (1, 1024), (2, 128), (2, 256), (2, 384), (2, 512), (2, 640), (2, 768), (2, 896), (2, 1024), (4, 128), (4, 256), (4, 384), (4, 512), (4, 640), (4, 768), (4, 896), (4, 1024)] -INFO 08-02 17:37:44 hpu_model_runner.py:504] Decode bucket config (min, step, max_warmup) bs:[1, 128, 4], seq:[128, 128, 2048] -INFO 08-02 17:37:44 hpu_model_runner.py:509] Generated 48 decode buckets: [(1, 128), (1, 256), (1, 384), (1, 512), (1, 640), (1, 768), (1, 896), (1, 1024), (1, 1152), (1, 1280), (1, 1408), (1, 1536), (1, 1664), (1, 1792), (1, 1920), (1, 2048), (2, 128), (2, 256), (2, 384), (2, 512), (2, 640), (2, 768), (2, 896), (2, 1024), (2, 1152), (2, 1280), (2, 1408), (2, 1536), (2, 1664), (2, 1792), (2, 1920), (2, 2048), (4, 128), (4, 256), (4, 384), (4, 512), (4, 640), (4, 768), (4, 896), (4, 1024), (4, 1152), (4, 1280), (4, 1408), (4, 1536), (4, 1664), (4, 1792), (4, 1920), (4, 2048)] -INFO 08-02 17:37:52 hpu_model_runner.py:430] Pre-loading model weights on hpu:0 took 14.97 GiB of device memory (14.97 GiB/94.62 GiB used) and 2.95 GiB of host memory (475.2 GiB/1007 GiB used) -INFO 08-02 17:37:52 hpu_model_runner.py:438] Wrapping in HPU Graph took 0 B of device memory (14.97 GiB/94.62 GiB used) and -252 KiB of host memory (475.2 GiB/1007 GiB used) -INFO 08-02 17:37:52 hpu_model_runner.py:442] Loading model weights took in total 14.97 GiB of device memory (14.97 GiB/94.62 GiB used) and 2.95 GiB of host memory (475.2 GiB/1007 GiB used) -INFO 08-02 17:37:54 hpu_worker.py:134] Model profiling run took 504 MiB of device memory (15.46 GiB/94.62 GiB used) and 180.9 MiB of host memory (475.4 GiB/1007 GiB used) -INFO 08-02 17:37:54 hpu_worker.py:158] Free device memory: 79.16 GiB, 39.58 GiB usable (gpu_memory_utilization=0.5), 15.83 GiB reserved for HPUGraphs (VLLM_GRAPH_RESERVED_MEM=0.4), 23.75 GiB reserved for KV cache -INFO 08-02 17:37:54 hpu_executor.py:85] # HPU blocks: 1519, # CPU blocks: 0 -INFO 08-02 17:37:54 hpu_worker.py:190] Initializing cache engine took 23.73 GiB of device memory (39.2 GiB/94.62 GiB used) and -1.238 MiB of host memory (475.4 GiB/1007 GiB used) -INFO 08-02 17:37:54 hpu_model_runner.py:1066] [Warmup][Prompt][1/24] batch_size:4 seq_len:1024 free_mem:55.43 GiB -... -INFO 08-02 17:38:22 hpu_model_runner.py:1066] [Warmup][Decode][48/48] batch_size:1 seq_len:128 free_mem:55.43 GiB -INFO 08-02 17:38:22 hpu_model_runner.py:1159] Using 15.85 GiB/55.43 GiB of free device memory for HPUGraphs, 4.755 GiB for prompt and 11.095 GiB for decode (VLLM_GRAPH_PROMPT_RATIO=0.3) -INFO 08-02 17:38:22 hpu_model_runner.py:1066] [Warmup][Graph/Prompt][1/24] batch_size:1 seq_len:128 free_mem:55.43 GiB -... -INFO 08-02 17:38:26 hpu_model_runner.py:1066] [Warmup][Graph/Prompt][11/24] batch_size:1 seq_len:896 free_mem:48.77 GiB -INFO 08-02 17:38:27 hpu_model_runner.py:1066] [Warmup][Graph/Decode][1/48] batch_size:4 seq_len:128 free_mem:47.51 GiB -... -INFO 08-02 17:38:41 hpu_model_runner.py:1066] [Warmup][Graph/Decode][48/48] batch_size:1 seq_len:2048 free_mem:47.35 GiB -INFO 08-02 17:38:41 hpu_model_runner.py:1066] [Warmup][Graph/Prompt][12/24] batch_size:4 seq_len:256 free_mem:47.35 GiB -INFO 08-02 17:38:42 hpu_model_runner.py:1066] [Warmup][Graph/Prompt][13/24] batch_size:2 seq_len:512 free_mem:45.91 GiB -INFO 08-02 17:38:42 hpu_model_runner.py:1066] [Warmup][Graph/Prompt][14/24] batch_size:1 seq_len:1024 free_mem:44.48 GiB -INFO 08-02 17:38:43 hpu_model_runner.py:1066] [Warmup][Graph/Prompt][15/24] batch_size:2 seq_len:640 free_mem:43.03 GiB -INFO 08-02 17:38:43 hpu_model_runner.py:1128] Graph/Prompt captured:15 (62.5%) used_mem:14.03 GiB buckets:[(1, 128), (1, 256), (1, 384), (1, 512), (1, 640), (1, 768), (1, 896), (1, 1024), (2, 128), (2, 256), (2, 384), (2, 512), (2, 640), (4, 128), (4, 256)] -INFO 08-02 17:38:43 hpu_model_runner.py:1128] Graph/Decode captured:48 (100.0%) used_mem:161.9 MiB buckets:[(1, 128), (1, 256), (1, 384), (1, 512), (1, 640), (1, 768), (1, 896), (1, 1024), (1, 1152), (1, 1280), (1, 1408), (1, 1536), (1, 1664), (1, 1792), (1, 1920), (1, 2048), (2, 128), (2, 256), (2, 384), (2, 512), (2, 640), (2, 768), (2, 896), (2, 1024), (2, 1152), (2, 1280), (2, 1408), (2, 1536), (2, 1664), (2, 1792), (2, 1920), (2, 2048), (4, 128), (4, 256), (4, 384), (4, 512), (4, 640), (4, 768), (4, 896), (4, 1024), (4, 1152), (4, 1280), (4, 1408), (4, 1536), (4, 1664), (4, 1792), (4, 1920), (4, 2048)] -INFO 08-02 17:38:43 hpu_model_runner.py:1206] Warmup finished in 49 secs, allocated 14.19 GiB of device memory -INFO 08-02 17:38:43 hpu_executor.py:91] init_cache_engine took 37.92 GiB of device memory (53.39 GiB/94.62 GiB used) and 57.86 MiB of host memory (475.4 GiB/1007 GiB used) +(EngineCore_DP0 pid=805) INFO 09-23 12:32:50 [hpu_model_runner.py:3320] [Warmup][Unified CFG][2/375] query_len:2048 shared_blocks:256 unique_blocks:2890 (causal) free_mem:11.16 GiB +(EngineCore_DP0 pid=805) INFO 09-23 12:32:53 [hpu_model_runner.py:3320] [Warmup][Unified CFG][3/375] query_len:2048 shared_blocks:256 unique_blocks:1445 (causal) free_mem:11.16 GiB +(EngineCore_DP0 pid=805) INFO 09-23 12:32:56 [hpu_model_runner.py:3320] [Warmup][Unified CFG][4/375] query_len:2048 shared_blocks:256 unique_blocks:32 (causal) free_mem:11.16 GiB ``` diff --git a/docs/features/warmup.md b/docs/features/warmup.md new file mode 100644 index 00000000..a64d2582 --- /dev/null +++ b/docs/features/warmup.md @@ -0,0 +1,225 @@ +--- +title: Warm-up +--- +[](){ #Warm-up } + +## Warm-up + +Warm-up is a highly recommended step that occurs before the vLLM server starts listening. It performs a forward pass for each bucket using dummy data. The goal is to precompile all graphs and eliminate any graph compilation overhead within bucket boundaries during server runtime. Each warmup step is logged during vLLM startup. +This example uses the same buckets as those described in the Bucketing Mechanism section. Each output line corresponds to the execution of a single bucket. When a bucket is executed for the first time, its graph is compiled and can be reused later, avoiding further graph compilations. + +```{.} +INFO 08-01 22:26:47 hpu_model_runner.py:1066] [Warmup][Prompt][1/24] batch_size:4 seq_len:1024 free_mem:79.16 GiB +INFO 08-01 22:26:47 hpu_model_runner.py:1066] [Warmup][Prompt][2/24] batch_size:4 seq_len:896 free_mem:55.43 GiB +INFO 08-01 22:26:48 hpu_model_runner.py:1066] [Warmup][Prompt][3/24] batch_size:4 seq_len:768 free_mem:55.43 GiB +... +INFO 08-01 22:26:59 hpu_model_runner.py:1066] [Warmup][Prompt][24/24] batch_size:1 seq_len:128 free_mem:55.43 GiB +INFO 08-01 22:27:00 hpu_model_runner.py:1066] [Warmup][Decode][1/48] batch_size:4 seq_len:2048 free_mem:55.43 GiB +INFO 08-01 22:27:00 hpu_model_runner.py:1066] [Warmup][Decode][2/48] batch_size:4 seq_len:1920 free_mem:55.43 GiB +INFO 08-01 22:27:01 hpu_model_runner.py:1066] [Warmup][Decode][3/48] batch_size:4 seq_len:1792 free_mem:55.43 GiB +... +INFO 08-01 22:27:16 hpu_model_runner.py:1066] [Warmup][Decode][47/48] batch_size:2 seq_len:128 free_mem:55.43 GiB +INFO 08-01 22:27:16 hpu_model_runner.py:1066] [Warmup][Decode][48/48] batch_size:1 seq_len:128 free_mem:55.43 GiB +``` + +> [!TIP] +> Compiling all buckets may take some time and can be disabled by setting the `VLLM_SKIP_WARMUP=true` environment variable. Keep in mind that if you do this, you may encounter graph compilations when executing a given bucket for the first time. + +> [!WARNING] +> Disabling warmup is acceptable for development purposes, but it is strongly recommended to enable it in production deployments. + +## HPU Graph Capture + +[HPU Graphs](https://docs.habana.ai/en/latest/PyTorch/Inference_on_PyTorch/Inference_Using_HPU_Graphs.html) are currently the most performant execution method for vLLM on Intel Gaudi. When HPU Graphs are enabled, +execution graphs are be traced (recorded) ahead of time (after performing warmup), and later replayed during inference, significantly reducing host overheads. Recording can consume large amounts of memory, which +must be considred when allocating KV cache. Enabling HPU Graphs affects the number of available KV cache blocks, but vLLM provides user-configurable variables to manage memory usage. + +When HPU Graphs are used, they share the common memory pool ("usable memory") with the KV cache, as determined by the `gpu_memory_utilization` flag (default value is `0.9`). Before allocating the KV cache, +the model weights are loaded onto the device, and a forward pass is executed on dummy data to estimate memory usage. Only then is the `gpu_memory_utilization` flag applied. At its default value, +it marks 90% of the free device memory at that point as usable. Next, the KV cache is allocated, the model is warmed up, and HPU Graphs are captured. The `VLLM_GRAPH_RESERVED_MEM` environment variable defines +the ratio of memory reserved for HPU Graph capture. With its default value (`VLLM_GRAPH_RESERVED_MEM=0.1`), 10% of the usable memory will be reserved for graph capture (referred to as "usable graph memory"), and the remaining 90% will be used for the KV cache. + +> [!NOTE] +> `gpu_memory_utilization` does not represent the absolute memory usage across the HPU. Instead, it specifies the memory margin after loading the model and running a profiling pass. For example, if a device has 100 GiB of total memory and 50 GiB of free memory after loading the model weights and executing the profiling run, the default value of `gpu_memory_utilization` will mark 90% of the 50 GiB as usable, leaving 5 GiB as a margin - regardless of the total device memory. + +When many requests are pending, the vLLM scheduler attempts to fill the maximum decode batch size as quickly as possible. Once a request completes, the decode batch size decreases. When this happens, vLLM schedules a prefill iteration for requests in the waiting queue to restore the previous decode batch size. In fully loaded scenarios, the decode batch size is often at its maximum, making large-batch HPU graphs critical to capture. On the other hand, prompt iterations typically execute with very low batch sizes (1-4). + +Each step outlined is logged by the vLLM server, with negative values indicating memory release: + +```{.} +INFO 08-02 17:37:44 hpu_model_runner.py:493] Prompt bucket config (min, step, max_warmup) bs:[1, 32, 4], seq:[128, 128, 1024] +INFO 08-02 17:37:44 hpu_model_runner.py:499] Generated 24 prompt buckets: [(1, 128), (1, 256), (1, 384), (1, 512), (1, 640), (1, 768), (1, 896), (1, 1024), (2, 128), (2, 256), (2, 384), (2, 512), (2, 640), (2, 768), (2, 896), (2, 1024), (4, 128), (4, 256), (4, 384), (4, 512), (4, 640), (4, 768), (4, 896), (4, 1024)] +INFO 08-02 17:37:44 hpu_model_runner.py:504] Decode bucket config (min, step, max_warmup) bs:[1, 128, 4], seq:[128, 128, 2048] +INFO 08-02 17:37:44 hpu_model_runner.py:509] Generated 48 decode buckets: [(1, 128), (1, 256), (1, 384), (1, 512), (1, 640), (1, 768), (1, 896), (1, 1024), (1, 1152), (1, 1280), (1, 1408), (1, 1536), (1, 1664), (1, 1792), (1, 1920), (1, 2048), (2, 128), (2, 256), (2, 384), (2, 512), (2, 640), (2, 768), (2, 896), (2, 1024), (2, 1152), (2, 1280), (2, 1408), (2, 1536), (2, 1664), (2, 1792), (2, 1920), (2, 2048), (4, 128), (4, 256), (4, 384), (4, 512), (4, 640), (4, 768), (4, 896), (4, 1024), (4, 1152), (4, 1280), (4, 1408), (4, 1536), (4, 1664), (4, 1792), (4, 1920), (4, 2048)] +INFO 08-02 17:37:52 hpu_model_runner.py:430] Pre-loading model weights on hpu:0 took 14.97 GiB of device memory (14.97 GiB/94.62 GiB used) and 2.95 GiB of host memory (475.2 GiB/1007 GiB used) +INFO 08-02 17:37:52 hpu_model_runner.py:438] Wrapping in HPU Graph took 0 B of device memory (14.97 GiB/94.62 GiB used) and -252 KiB of host memory (475.2 GiB/1007 GiB used) +INFO 08-02 17:37:52 hpu_model_runner.py:442] Loading model weights took in total 14.97 GiB of device memory (14.97 GiB/94.62 GiB used) and 2.95 GiB of host memory (475.2 GiB/1007 GiB used) +INFO 08-02 17:37:54 hpu_worker.py:134] Model profiling run took 504 MiB of device memory (15.46 GiB/94.62 GiB used) and 180.9 MiB of host memory (475.4 GiB/1007 GiB used) +INFO 08-02 17:37:54 hpu_worker.py:158] Free device memory: 79.16 GiB, 39.58 GiB usable (gpu_memory_utilization=0.5), 15.83 GiB reserved for HPUGraphs (VLLM_GRAPH_RESERVED_MEM=0.4), 23.75 GiB reserved for KV cache +INFO 08-02 17:37:54 hpu_executor.py:85] # HPU blocks: 1519, # CPU blocks: 0 +INFO 08-02 17:37:54 hpu_worker.py:190] Initializing cache engine took 23.73 GiB of device memory (39.2 GiB/94.62 GiB used) and -1.238 MiB of host memory (475.4 GiB/1007 GiB used) +INFO 08-02 17:37:54 hpu_model_runner.py:1066] [Warmup][Prompt][1/24] batch_size:4 seq_len:1024 free_mem:55.43 GiB +... +INFO 08-02 17:38:22 hpu_model_runner.py:1066] [Warmup][Decode][48/48] batch_size:1 seq_len:128 free_mem:55.43 GiB +INFO 08-02 17:38:22 hpu_model_runner.py:1159] Using 15.85 GiB/55.43 GiB of free device memory for HPUGraphs, 4.755 GiB for prompt and 11.095 GiB for decode (VLLM_GRAPH_PROMPT_RATIO=0.3) +INFO 08-02 17:38:22 hpu_model_runner.py:1066] [Warmup][Graph/Prompt][1/24] batch_size:1 seq_len:128 free_mem:55.43 GiB +... +INFO 08-02 17:38:26 hpu_model_runner.py:1066] [Warmup][Graph/Prompt][11/24] batch_size:1 seq_len:896 free_mem:48.77 GiB +INFO 08-02 17:38:27 hpu_model_runner.py:1066] [Warmup][Graph/Decode][1/48] batch_size:4 seq_len:128 free_mem:47.51 GiB +... +INFO 08-02 17:38:41 hpu_model_runner.py:1066] [Warmup][Graph/Decode][48/48] batch_size:1 seq_len:2048 free_mem:47.35 GiB +INFO 08-02 17:38:41 hpu_model_runner.py:1066] [Warmup][Graph/Prompt][12/24] batch_size:4 seq_len:256 free_mem:47.35 GiB +INFO 08-02 17:38:42 hpu_model_runner.py:1066] [Warmup][Graph/Prompt][13/24] batch_size:2 seq_len:512 free_mem:45.91 GiB +INFO 08-02 17:38:42 hpu_model_runner.py:1066] [Warmup][Graph/Prompt][14/24] batch_size:1 seq_len:1024 free_mem:44.48 GiB +INFO 08-02 17:38:43 hpu_model_runner.py:1066] [Warmup][Graph/Prompt][15/24] batch_size:2 seq_len:640 free_mem:43.03 GiB +INFO 08-02 17:38:43 hpu_model_runner.py:1128] Graph/Prompt captured:15 (62.5%) used_mem:14.03 GiB buckets:[(1, 128), (1, 256), (1, 384), (1, 512), (1, 640), (1, 768), (1, 896), (1, 1024), (2, 128), (2, 256), (2, 384), (2, 512), (2, 640), (4, 128), (4, 256)] +INFO 08-02 17:38:43 hpu_model_runner.py:1128] Graph/Decode captured:48 (100.0%) used_mem:161.9 MiB buckets:[(1, 128), (1, 256), (1, 384), (1, 512), (1, 640), (1, 768), (1, 896), (1, 1024), (1, 1152), (1, 1280), (1, 1408), (1, 1536), (1, 1664), (1, 1792), (1, 1920), (1, 2048), (2, 128), (2, 256), (2, 384), (2, 512), (2, 640), (2, 768), (2, 896), (2, 1024), (2, 1152), (2, 1280), (2, 1408), (2, 1536), (2, 1664), (2, 1792), (2, 1920), (2, 2048), (4, 128), (4, 256), (4, 384), (4, 512), (4, 640), (4, 768), (4, 896), (4, 1024), (4, 1152), (4, 1280), (4, 1408), (4, 1536), (4, 1664), (4, 1792), (4, 1920), (4, 2048)] +INFO 08-02 17:38:43 hpu_model_runner.py:1206] Warmup finished in 49 secs, allocated 14.19 GiB of device memory +INFO 08-02 17:38:43 hpu_executor.py:91] init_cache_engine took 37.92 GiB of device memory (53.39 GiB/94.62 GiB used) and 57.86 MiB of host memory (475.4 GiB/1007 GiB used) +``` + +## Sampler Warm-Up +The sampler converts model logits into next-token selections, using configured decoding strategies (greedy or probabilistic). Its warm-up phase prepares compiled graph variants (or internal code paths) for a representative set of batch sizes and sampling parameter combinations, so that first real user requests avoid extra compilation/setup latency. + +### How the Sampler Warm-Up Works + +Implemented in `warmup_sampler`, the routine systematically exercises the sampling stack across a Cartesian set of (batch size, temperature, top-p, top-k) patterns and a flag, that signals whether the batch size changed. Key steps: + +1. Build a list of test batch sizes: it prepends `[0, 1]` to the distinct decode bucket batch sizes, as these need to be always warmed up. +2. Define a list of sampling configurations (12 total) covering: + * Greedy (temperature=0.0) + * Typical random sampling (temperature=1.0) + * Creative settings (0.7/0.9/top-k=50) + * Conservative (0.3/0.95/top-k=20) + * High temperature (1.2/0.8/top-k=100) + * Top-p only variants (e.g. 0.8/0.85/top-k=0) + Each appears twice: once with `batch_changed=True` and once with `batch_changed=False` to exercise any internal fast-path or cache invalidation logic tied to batch resizing. +3. For every batch size: + * Create a dummy hidden state tensor shaped `(batch_size, hidden_size)` and compute logits via `model.compute_logits`. + * Instantiate dummy request objects (at least one) with placeholder prompt tokens and single KV block. +4. For each sampling configuration: + * Update each request's `SamplingParams` (temperature, top_p, top_k). + * Mark the request as greedy or random (separate sets) to test branching. + * Populate `req_output_token_ids` with padded placeholders and refresh internal sampling metadata. + * Invoke `_run_sampling` passing `batch_changed` so both changed/unchanged batch-size code paths get compiled/exercised. + * Reset per-iteration sampler bookkeeping sets/lists. +5. After finishing all sampling configs for a batch size, clear request maps and continue. +6. Perform an HPU synchronize and log success. + +### What the Logs Look Like + +Typical sequence: + +```text +INFO 09-22 16:39:42 [hpu_model_runner.py:3347] Warming up sampler with batch sizes: [0, 1, 138] and following configs: +INFO 09-22 16:39:42 [hpu_model_runner.py:3349] temp=0.0, top_p=1.0, top_k=0, batch_changed=True +INFO 09-22 16:39:42 [hpu_model_runner.py:3349] temp=1.0, top_p=1.0, top_k=0, batch_changed=True +INFO 09-22 16:39:42 [hpu_model_runner.py:3349] temp=0.7, top_p=0.9, top_k=50, batch_changed=True +INFO 09-22 16:39:42 [hpu_model_runner.py:3349] temp=0.3, top_p=0.95, top_k=20, batch_changed=True +INFO 09-22 16:39:42 [hpu_model_runner.py:3349] temp=1.2, top_p=0.8, top_k=100, batch_changed=True +INFO 09-22 16:39:42 [hpu_model_runner.py:3349] temp=0.8, top_p=0.85, top_k=0, batch_changed=True +INFO 09-22 16:39:42 [hpu_model_runner.py:3349] temp=0.0, top_p=1.0, top_k=0, batch_changed=False +INFO 09-22 16:39:42 [hpu_model_runner.py:3349] temp=1.0, top_p=1.0, top_k=0, batch_changed=False +INFO 09-22 16:39:42 [hpu_model_runner.py:3349] temp=0.7, top_p=0.9, top_k=50, batch_changed=False +INFO 09-22 16:39:42 [hpu_model_runner.py:3349] temp=0.3, top_p=0.95, top_k=20, batch_changed=False +INFO 09-22 16:39:42 [hpu_model_runner.py:3349] temp=1.2, top_p=0.8, top_k=100, batch_changed=False +INFO 09-22 16:39:42 [hpu_model_runner.py:3349] temp=0.8, top_p=0.85, top_k=0, batch_changed=False +INFO 09-22 16:39:42 [hpu_model_runner.py:3350] Starting sampler warmup... +INFO 09-22 16:39:43 [hpu_model_runner.py:3411] Sampler warmup completed successfully +``` + +If warm-up is globally skipped ([see below](#how-to-turn-it-off)), none of these lines appear. + +### Why We Warm Up the Sampler (and Risks If We Do Not) + +Without sampler warm-up: +* The first real request using a new combination (e.g., first high-temp + top-k path, or first batch size after scaling up load) might incur graph recompilation, adding latency to that user request. +* Tail latency variance increases: early heterogeneous workloads cause multiple staggered compilations. +* Batch-size transition logic (paths where `batch_changed=True`) may pay initialization cost during live traffic. + +With warm-up: +* Common sampling hyperparameter mixes are compiled ahead-of-time. +* Greedy vs random branching and metadata refresh code paths are stabilized. +* Batch growth/shrink handling is already exercised, smoothing later scaling behavior. + +Skipping the sampler warm-up does not affect correctness—only the latency profile of the earliest varied sampling requests. + +### How to Turn It Off + +There is no dedicated flag for the sampler alone. It participates in the global warm-up sequence and is skipped when: + +* `VLLM_SKIP_WARMUP=true` is set. +* The engine is configured to enforce eager execution in a mode where no graph capture/compilation is desired (sampler still runs the first time on demand, but without a separate warm-up call). + +### Related Notes & Environment Variables + +* `VLLM_SKIP_WARMUP` – Disables sampler warm-up along with other warm-up phases. +* Decode bucket configuration env vars indirectly influence the set of batch sizes the sampler warms up (since it derives test batch sizes from decode buckets). + +> [!NOTE] +> If you introduce new sampling behaviors (e.g., new nucleus filtering, penalties, or speculative metadata), extend `sampling_configs` in `warmup_sampler` so their graph paths are primed. + +## Defragmenter Warm-Up + +The defragmenter reclaims and compacts sparse KV-cache block usage at runtime by swapping rarely packed high-index blocks with lower free indices. Its warm-up phase pre-compiles the small swap graphs so that later online defragmentation can execute with near-zero graph compile latency. + +### How the Defragmenter Warm-Up Works + +During the main warm-up (`warmup_model`) we call an internal method (`warmup_defragmenter`) after the KV caches and defragmenter have been initialized. The routine: + +1. Verifies the feature is enabled (defragmenter only runs when unified attention is enabled) and that swap utilities (`cache_utils`) are prepared. +2. Determines the list of padding thresholds: `[8, 16, 32, 64, 128, 256, 512]`. +3. Chooses a minimal valid swap pair `[(1, 0)]` (two distinct block IDs). Only two real blocks are required; internally each swap call is padded up to the current threshold length so that a compiled graph for that exact padded size is produced. +4. Iterates through each threshold and invokes a swap. This captures/compiles (depending on execution mode) the swap graph for that padded size. +5. If the number of thresholds is odd, performs one extra swap with the first threshold so that the sequence of swaps returns the KV cache to its original state (net zero logical change). +6. Logs completion. + +Because every future real defragmentation swap request will round/pad to one of these known thresholds, all operational swap sizes hit a pre-compiled path and avoid on-demand compilation latency. + +### What the Logs Look Like + +You will typically see one of two flows. If there are at least two KV-cache blocks available: + +```text +INFO 09-22 16:26:24 [hpu_model_runner.py:3428] Warming up defragmenter with thresholds: [8, 16, 32, 64, 128, 256, 512] +INFO 09-22 16:26:27 [hpu_model_runner.py:3452] Defragmenter warmup completed successfully +``` + +If insufficient blocks exist (e.g., extremely small test configuration or allocation failure) warm-up is skipped gracefully: + +```text +INFO 09-22 16:26:24 [hpu_model_runner.py:3428] Warming up defragmenter with thresholds: [8, 16, 32, 64, 128, 256, 512] +WARNING hh:mm:ss hpu_model_runner.py:#### Skipping defragmenter warmup, insufficient blocks (1) +``` + +Add `VLLM_DEBUG=defrag` to the environment to emit fine-grained debug messages during live defragmentation (not during the minimal warm-up swaps only) such as the number of blocks swapped and post-compaction statistics. + +### Why We Warm Up (and What Happens If We Do Not) + +Defragmentation may be triggered mid-serving when the highest allocated block index drifts far above the actual number of in-use blocks (fragmentation). The operation itself is a sequence of swap kernels over key & value caches. Without warm-up: + +* The first fragmentation event that requires a new (previously unseen) padded swap size would incur graph capture/compilation in the critical path. +* That added latency can surface as a sudden tail-latency spike for a user request. +* Multiple different first-seen swap sizes across processes could each trigger separate compilations. + +With warm-up, all representative padded sizes are compiled ahead-of-time via a deterministic, tiny swap, so online defragmentation becomes a predictable, low-latency maintenance task. + +Skipping only the defragmenter warm-up does not break correctness; it only risks sporadic latency when fragmentation first crosses a threshold that mandates compaction. + +### How to Turn It Off + +You can disable (a) the warm-up step itself or (b) the entire defragmentation feature: + +* Disable all warm-up phases (including defragmenter) by setting `VLLM_SKIP_WARMUP=true`. +* Run without unified attention (the defragmenter is tied to unified attention; if unified attention is disabled, `defrag` is not enabled and the warm-up is a no-op). There is no separate dedicated environment flag to force-enable/disable defrag beyond unified attention in this version. +* Avoid graph compilation for defragmenter swaps by setting `VLLM_DEFRAG_WITH_GRAPHS=false` (falls back to regular execution; warm-up will still exercise swaps but without graph capture), if supported by the execution mode. + +Related environment variables: + +* `VLLM_DEFRAG_THRESHOLD` – Fragmentation trigger heuristic (default 32). Lower values make compaction more aggressive. +* `VLLM_DEFRAG_WITH_GRAPHS` – Whether swap paths are compiled/graphed (defaults to `bridge_mode == eager`). +* `VLLM_DEBUG=defrag` – Enables verbose defragmentation debug logging. +* `VLLM_SKIP_WARMUP` – Disables all warm-up stages including this one. + +> [!NOTE] +> Disabling defragmenter warm-up does not disable defragmentation itself (unless unified attention/the feature is off). It only removes ahead-of-time graph preparation, potentially pushing compile cost into the first live fragmentation event.