Repository navigation
Startup OOM: eager relaunch costs 2x on an 8B model, MAX_NUM_SEQS=32 avoids most of it, 'Cannot auto-fit' exits 1 #366
Description
I measured the startup-OOM relaunch from #346 on v2.30.1 (71d503e6, vLLM v0.32.0) to see what it costs when it fires. Three things came out of it: the eager relaunch halves throughput on a small model with nothing in the responses, the Hub default MAX_NUM_SEQS=256 costs boot time and context without a throughput gain at the worker's concurrency, and Cannot auto-fit max_model_len isn't matched by memory_shortfall(), so that case still ends in sys.exit(1) and a restart on the same footprint, the loop #346 set out to remove.
Setup. Not a deployed endpoint: vllm/vllm-openai:v0.32.0 (the worker's base image) running the args build_vllm_args() builds from the Hub form defaults (MAX_MODEL_LEN=auto, GPU_MEMORY_UTILIZATION=0.95, MAX_NUM_SEQS=256). For each failed boot, the last 400 log lines went through the worker's own startup_errors.py with main.py's rules to get what the worker would do. Benchmark: vllm bench serve, random 1024 in / 512 out, at 1, 8 and 30 concurrent (MAX_CONCURRENCY). Two cards, neither in the Hub's GPU list, so the numbers are from these cards only:
- RTX 5090 (32 GB),
deepseek-ai/DeepSeek-R1-Distill-Llama-8B(the Hub preset) - RTX PRO 6000 Blackwell (96 GB),
RedHatAI/Llama-3.3-70B-Instruct-FP8-dynamic
Output tok/s:
| Card, model | Variant | 1 | 8 | 30 | Boot | Auto-fit context |
|---|---|---|---|---|---|---|
| 5090, R1-Distill-8B | Hub defaults | 97.7 | 619.6 | 1,661.0 | 251 s | 106,784 |
OOM relaunch (ENFORCE_EAGER, 8192 batched tokens) |
49.2 | 383.2 | 1,134.5 | 55 s | 111,056 | |
MAX_NUM_SEQS=32, graphs on |
98.0 | 620.5 | 1,657.8 | 80 s | 110,096 | |
| PRO 6000, Llama-3.3-70B FP8 | Hub defaults | 19.2 | 140.4 | 412.8 | 210 s | 62,544 |
| OOM relaunch | 19.1 | 137.2 | 399.4 | 45 s | 67,040 | |
MAX_NUM_SEQS=32, graphs on |
19.2 | 140.3 | 412.4 | 90 s | 64,816 |
- The relaunch's cost depends on the model. Eager is 2.0x slower at one request on the 8B model (1.5x at 30) and 0-3% slower on the 70B. Nothing in the responses says it happened, so an 8B endpoint that lands on this path runs at half speed with no signal outside the logs.
MAX_NUM_SEQS=256costs boot time and context. Capturing graphs for 256 sequences took 158 s of the 5090 boot (75 + 83 s) and 101 s of the PRO 6000 boot; with 32 sequences it took 2-3 s.MAX_NUM_SEQS=32is still aboveMAX_CONCURRENCY=30, matched the default's throughput at every concurrency tested, booted in 80 s instead of 251 s and 90 s instead of 210 s, and fit 3.3K (5090) and 2.3K (PRO 6000) more tokens of context underauto. So with it as the default, fewer deploys reach the relaunch at all, and every cold start is 2-3 min shorter.- Most of the relaunch band can keep graphs. At an explicit
MAX_MODEL_LENbetween what the default andMAX_NUM_SEQS=32fit (108,440 on the 5090, 63,680 on the PRO 6000), the default failed with the KV shortfallmemory_shortfall()matches, and both the eager relaunch andMAX_NUM_SEQS=32with graphs served it. Above theMAX_NUM_SEQS=32fit, only eager helps: it frees the whole graph estimate and fits about 1K (5090) and 2.2K (PRO 6000) tokens more. Cannot auto-fitexits 1. When the weights leave no room for KV underMAX_MODEL_LEN=auto(forced here withGPU_MEMORY_UTILIZATION=0.45, standing in for a model that fills the card), vLLM v0.32.0 raisesCannot auto-fit max_model_len: not enough GPU memory available to serve even a single token(vllm/v1/core/kv_cache_utils.py:2453-2457). Underautothe auto-fit runs before the capacity check that printsNo available memory for the cache blocks, so a negative KV budget ends in this message too. Neithermemory_shortfall()norclassify()matches it, andmain.py:305-311exits 1. I didn't deploy an endpoint, so the restart on the same config is from the code, not observed.
Suggested changes:
- Default
MAX_NUM_SEQSin.runpod/hub.jsonto 32, or tie it toMAX_CONCURRENCY. - If 256 stays the default, the OOM relaunch could first try
MAX_NUM_SEQSatMAX_CONCURRENCYwith graphs on and keep eager as the last step. That adds a launch against Auto-retry startup OOM once with a reduced memory footprint #346's bound of three, so it's a tradeoff. - Match
Cannot auto-fit max_model_leninmemory_shortfall(), or at least inclassify(), so jobs get the memory advice instead of an exit 1.
I can send a PR for the first and third if that helps. The kits, with the exact args per variant and the results: https://github.com/adi-suresh01/sm120-kit/tree/main/issues/runpod-worker-vllm-r1d8b and https://github.com/adi-suresh01/sm120-kit/tree/main/issues/runpod-worker-vllm-l70b
Activity