Skip to content

Commit b70edbf

Browse files
committed
docs: add cold-start benchmarks (Qwen2.5-7B on A10)
Measured phase breakdown of vLLM cold start and the warmupStrategy trade-off on real GPU hardware: init engine is 30.4s with CUDA graphs (Graph) vs 8.3s without (Eager), a 3.7x difference that justifies the strategy field. Measured with vLLM run directly; validation through the operator's Warming->Ready transition on a GPU cluster remains on the roadmap. Raw logs kept local (gitignored).
1 parent 555261e commit b70edbf

2 files changed

Lines changed: 60 additions & 0 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
/target
2+
3+
# Local benchmark logs (raw, kept off the repo)
4+
*.log
5+
BENCHMARKS-raw.txt

docs/BENCHMARKS.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Cold-start benchmarks
2+
3+
Measured cold-start cost of a vLLM server, broken down by phase, and the
4+
effect of the `warmupStrategy` trade-off this operator exposes.
5+
6+
## Setup
7+
8+
- Model: Qwen/Qwen2.5-7B-Instruct (bfloat16)
9+
- GPU: NVIDIA A10 (24 GB), Lambda Cloud
10+
- vLLM: 0.22.0, `--max-model-len 4096`
11+
- Measured with vLLM run directly (Docker, `--gpus all`). Validation through
12+
the operator's Warming->Ready transition on a GPU cluster is on the roadmap;
13+
the numbers below are the cost that transition observes.
14+
15+
## Method
16+
17+
Cold start is timed from process start to the `/health` endpoint returning
18+
200 (the moment the server can actually serve). Phase durations are taken
19+
from vLLM's own startup logs. Weight *download* time is reported but excluded
20+
from the strategy comparison: it is one-time (cached afterwards) and varies
21+
with network, so it is noise for the cold-start trade-off.
22+
23+
## Results
24+
25+
Phase breakdown, Qwen2.5-7B on A10:
26+
27+
| Phase | Graph (default) | Eager (`--enforce-eager`) |
28+
|---|---|---|
29+
| Weight download (one-time) | 14.5s | 14.2s |
30+
| Model loading (14.29 GiB) | 17.6s | 17.1s |
31+
| Init engine (compile + KV cache + warmup) | 30.4s | 8.3s |
32+
33+
The first two phases are essentially identical across strategies. The
34+
difference is concentrated in init engine, which is exactly what
35+
`warmupStrategy` controls.
36+
37+
## The warmupStrategy trade-off
38+
39+
`Graph` (CUDA graphs on) spends 30.4s in init engine: ~14.7s of
40+
`torch.compile` plus ~6s capturing CUDA graphs. `Eager` disables both and
41+
spends 8.3s — a **3.7x faster** init engine, saving ~22s of cold start.
42+
43+
- `warmupStrategy: Eager` — fast cold start. Best for scale-to-zero, where a
44+
pod is recreated on demand and time-to-serve dominates.
45+
- `warmupStrategy: Graph` — slower cold start, but the compiled graphs pay off
46+
in steady-state throughput. Best for long-lived, high-traffic replicas.
47+
48+
This is the trade-off the operator makes a first-class, declarative choice
49+
rather than a hidden flag.
50+
51+
## A note on measurement
52+
53+
Wall-clock time-to-ready can mislead: an `Eager` run measured a *longer*
54+
total than a `Graph` run because both re-downloaded weights and download time
55+
varied. Isolating the phase that the strategy actually changes — init engine —
56+
is what reveals the real 3.7x difference. Compare phases, not wall-clock.

0 commit comments

Comments
 (0)