Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
f393964
Add stub of function to calculate required blocks
maxdebayser May 21, 2026
526fac3
fix typo
maxdebayser May 21, 2026
0c69697
input_batch adaptation for preemption
sducouedic May 20, 2026
9cc4310
run pre-commit hook
sducouedic May 21, 2026
7e2c516
make constraint greedy when scheduling new requests
sducouedic May 21, 2026
baa4de5
Fill get_blocks_required_for_decode_batch
maxdebayser May 21, 2026
0c37074
Merge branch 'decode_holdback' of github.com:maxdebayser/vllm-spyre i…
maxdebayser May 21, 2026
cf457b9
temporary tests
sducouedic May 22, 2026
0baa5ec
correct volumetric violated prefill holdback test
sducouedic May 26, 2026
9777fc6
remove max-context-len constraint entirely
sducouedic May 27, 2026
86a4aa9
scheduler predict next tkv
sducouedic May 28, 2026
88a7c4d
rename holdback to pausing
sducouedic May 29, 2026
ed9b1ab
rename handle pausing and resuming
sducouedic May 29, 2026
e39dc32
bugfix: wrong tkv when expanding to new block
sducouedic May 29, 2026
117f7f2
continued: rename holdback to pausing
sducouedic May 29, 2026
cd28178
complete decode pausing tests
sducouedic May 29, 2026
2053a3b
handle paused decoding requests abort
sducouedic May 29, 2026
6a4c605
fix tests
sducouedic May 29, 2026
8555656
only add requests that were paused
sducouedic May 29, 2026
01e43b2
fix tests
sducouedic May 29, 2026
867e38c
fix tests
sducouedic May 30, 2026
15cabb9
pause/resume concept in intput batch
sducouedic Jun 1, 2026
2195185
small bugs catched
sducouedic Jun 2, 2026
41ee95e
handle finish of paused requests
sducouedic Jun 2, 2026
944ed67
clean the tests
sducouedic Jun 2, 2026
75eb053
logits_processor advanced test: also check the output
sducouedic Jun 2, 2026
0530cab
remove superseded design idea for block reservation
maxdebayser Jun 2, 2026
84cf5db
Fix input batch removal of requests
maxdebayser Jun 3, 2026
4bd1c83
cleanup test code
sducouedic Jun 3, 2026
9d5f9d0
factor out common part
sducouedic Jun 3, 2026
fa6de4a
predict next tkv using num_computed_tokens instead of allocated blocks
sducouedic Jun 4, 2026
24691b9
don't schedule new requests if there are paused ones
sducouedic Jun 4, 2026
5395320
comments and docstrings cleaning
sducouedic Jun 4, 2026
d007194
merge with main
sducouedic Jun 4, 2026
b39f262
log preemption
sducouedic Jun 5, 2026
82167b5
custom bench serve: first version
sducouedic Jun 9, 2026
b523729
allow to use sendnn-bench serve
sducouedic Jun 9, 2026
e850da5
add some debug prints
sducouedic Jun 9, 2026
acfc886
bugfix processes isolations
sducouedic Jun 9, 2026
a6a4590
bug fixed, remove prints
sducouedic Jun 9, 2026
2250d9e
cleaner output print
sducouedic Jun 9, 2026
baf5388
pretty print final output
sducouedic Jun 10, 2026
f846041
inject per request results to vllm bench serve .json file
sducouedic Jun 10, 2026
cae6cc7
standalone metric: num prefill chunks
sducouedic Jun 10, 2026
92b78a5
add benchmark tests
sducouedic Jun 10, 2026
3fc7054
scheduler: move bench attributes to dedicated dataclass
sducouedic Jun 10, 2026
8a17565
custom detailed timeline
sducouedic Jun 10, 2026
71dbc31
surface decode metrics
sducouedic Jun 10, 2026
6e4394e
timeline legend show itl range
sducouedic Jun 10, 2026
c2790c1
Merge branch 'main' into decode_holdback
maxdebayser Jun 11, 2026
bcf882e
Fix worker out-of-order bug and improve tests
maxdebayser Jun 11, 2026
0845da8
update hf_cache.json
maxdebayser Jun 11, 2026
d7ebd58
Merge branch 'decode_holdback' of github.com:maxdebayser/vllm-spyre i…
maxdebayser Jun 11, 2026
b54fd0c
modelrunner: use dedicated dataclass for bench data
sducouedic Jun 12, 2026
ffeac1f
remove decode_tkv
sducouedic Jun 12, 2026
dcca355
update tests
sducouedic Jun 12, 2026
d23408e
track all metrics in scheduler
sducouedic Jun 12, 2026
6014899
Always allow last prefill chunks onto the decode batch if it doesn't …
maxdebayser Jun 12, 2026
5f28438
debug tests
sducouedic Jun 12, 2026
636d4c1
update timeline
sducouedic Jun 12, 2026
885f037
add claude skill
sducouedic Jun 12, 2026
b2556a9
cleanup block pool before tests
maxdebayser Jun 12, 2026
3a51f7d
display prefix cache hit
sducouedic Jun 12, 2026
3009cca
Merge branch 'main' into decode_holdback
maxdebayser Jun 12, 2026
c4233b7
display left-padding
sducouedic Jun 12, 2026
182306f
refactor pause/resume
maxdebayser Jun 12, 2026
e2f7ecf
remove cond2
maxdebayser Jun 12, 2026
e10d1bb
merge with decode_holdback
sducouedic Jun 12, 2026
11f4051
display prefix cache hit
sducouedic Jun 12, 2026
49db7f8
address PR review comments
maxdebayser Jun 15, 2026
fd5321a
Merge branch 'main' into decode_holdback
maxdebayser Jun 15, 2026
6243d35
address review comment
maxdebayser Jun 15, 2026
a19dea2
fix test
maxdebayser Jun 15, 2026
dcf2459
display left-padding
sducouedic Jun 12, 2026
224c9aa
don't prioritize any endpoint so that we support --skip-chat-template
sducouedic Jun 16, 2026
0cac781
display pause time
sducouedic Jun 12, 2026
8359657
Merge remote-tracking branch 'sop-fork/custom_bench_metrics' into sav…
sducouedic Jun 16, 2026
28d4456
rename 'previous_step_was_prefill' to 'step_is_prefill'
sducouedic Jun 16, 2026
d1dbe75
address pause/resume logic comments
sducouedic Jun 16, 2026
a99e662
Merge remote-tracking branch 'max/decode_holdback' into save_custom_b…
sducouedic Jun 16, 2026
42b1528
Merge remote-tracking branch 'origin/main' into decode_holdback
sducouedic Jun 16, 2026
c78a340
Merge remote-tracking branch 'max/decode_holdback' into save_custom_b…
sducouedic Jun 16, 2026
f83d4f4
support multi endpoints
sducouedic Jun 16, 2026
bb6ce98
extract bench part of update_from_output
sducouedic Jun 16, 2026
72d16e8
Merge remote-tracking branch 'origin/main' into custom_bench_metrics
sducouedic Jun 16, 2026
0b8b170
address md error
sducouedic Jun 16, 2026
d1af985
address precommit hook error
sducouedic Jun 16, 2026
7722d20
fix tests
sducouedic Jun 16, 2026
6e455fa
timestamp right before return
sducouedic Jun 16, 2026
1aa8ca4
Merge remote-tracking branch 'sop-fork/custom_bench_metrics' into sav…
sducouedic Jun 16, 2026
2a262b1
rename prev_was_prefill to is_prefill
sducouedic Jun 16, 2026
7a3ec53
don't put dedicated test workflow
sducouedic Jun 16, 2026
192af4b
count the number of requests blocked by missing kv blocks
sducouedic Jun 17, 2026
5260e9c
restore cond2
sducouedic Jun 18, 2026
db632e1
per request metrics json file save: one line per metric
sducouedic Jun 18, 2026
e21b6fd
Merge remote-tracking branch 'origin/main' into custom_bench_metrics
sducouedic Jun 18, 2026
dc53819
remove dead code
sducouedic Jun 24, 2026
c6f9351
add explanation comment for queued_time_s
sducouedic Jun 30, 2026
3b3cafb
Merge remote-tracking branch 'origin/main' into custom_bench_metrics
sducouedic Jun 30, 2026
2f750fd
Merge remote-tracking branch 'upstream/main' into custom_bench_metrics
sducouedic Aug 10, 2026
040502f
Merge remote-tracking branch 'origin/custom_bench_metrics' into decod…
sducouedic Aug 10, 2026
3f6ef78
restore diverging to main
sducouedic Aug 10, 2026
76d73e6
bench pausing starting
sducouedic Aug 10, 2026
92da4e9
restore round_up function
sducouedic Aug 10, 2026
6ae0167
Merge pull request #1 from sducouedic/decode_pausing_bench_metrics
sducouedic Aug 10, 2026
72507da
format
sducouedic Aug 10, 2026
988c482
test fix multimodal
sducouedic Aug 10, 2026
0eaf86d
add metrics descriptions
sducouedic Aug 11, 2026
f88f697
add prefilling breakdown metrics
sducouedic Aug 11, 2026
1082287
bench metrics description: move it to file instead of print
sducouedic Aug 11, 2026
dc1a72d
bugfix: time_ts was using end of first chunk instead of start
sducouedic Aug 12, 2026
65af154
more thorough prefill phase breakdown test
sducouedic Aug 12, 2026
f105f25
fix ordering
yannicks1 Aug 12, 2026
db1f1ab
Merge pull request #3 from yannicks1/fix-ordering
sducouedic Aug 12, 2026
2be9330
test patch_serving compatibility
sducouedic Aug 12, 2026
a0844f0
test main_async marker compatibility
sducouedic Aug 12, 2026
a178f5c
force set explicit name when --save-result or --plot-timeline
sducouedic Aug 13, 2026
3e3fd99
bugfix: number of left-padding blocks can momentally go negative
sducouedic Aug 13, 2026
68e5288
handle detailed_timeline_plot in warning message
sducouedic Aug 13, 2026
8f579b4
bugfix failing test
sducouedic Aug 13, 2026
e828990
add sendnn-bench docs
sducouedic Aug 13, 2026
f9e2767
add test to pin _free_request return contract and kv_transfer_params …
yannicks1 Aug 14, 2026
2603eb7
fix(bench): skip per-request metric injection when result JSON lacks …
yannicks1 Aug 14, 2026
55acec1
tolerate present-but-null metric values in _print_spyre_section
yannicks1 Aug 14, 2026
81b8c47
Update tests/benchmarks/test_bench_metrics.py
yannicks1 Aug 17, 2026
9a289de
Merge pull request #4 from yannicks1/custom-bench-robustness
sducouedic Aug 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
302 changes: 302 additions & 0 deletions .claude/skills/add-bench-metric/SKILL.md

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions docs/.nav.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ nav:
- Supported Features: user_guide/supported_features.md
- Supported Models: user_guide/supported_models.md
- Performance Tuning: user_guide/performance.md
- Detailed Performance Measurement: user_guide/detailed_performance_measurement.md
- Developer Guide:
- Contributing: contributing/README.md
- Maintaining: contributing/maintaining.md
Expand All @@ -38,6 +39,7 @@ nav:
- Supported Features: user_guide/supported_features.md
- Supported Models: user_guide/supported_models.md
- Performance Tuning: user_guide/performance.md
- Detailed Performance Measurement: user_guide/detailed_performance_measurement.md
- Developer Guide:
- Contributing: contributing/README.md
- Maintaining: contributing/maintaining.md
Expand Down
106 changes: 106 additions & 0 deletions docs/user_guide/detailed_performance_measurement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Detailed Performance Measurement

`sendnn-bench` is a drop-in replacement for [`vllm bench serve`](https://docs.vllm.ai/en/stable/benchmarking/cli/#online-benchmark) that collects **additional Spyre-specific per-request metrics** on top of the usual TTFT/TPOT/ITL/E2EL values described in [Benchmarking and Performance](./performance.md). It reuses the upstream implementation — every `vllm bench serve` flag keeps working — and augments it with scheduler-level information such as queue wait time, per-chunk prefill latencies, per-step decode latencies, prefix cache hit rate, left padding and request pausing.

## Usage

1. Start the server with Spyre metrics collection enabled:

```bash
SENDNN_INFERENCE_BENCH_METRICS_ENABLED=1 vllm serve \
--model {model} \
--max-model-len {max-model-len} \
--max-num-seqs {max-num-seqs}
```

!!! warning

`SENDNN_INFERENCE_BENCH_METRICS_ENABLED=1` must be set **on the server**. The client does not read it. Without it the server returns no Spyre metrics and the client logs a warning.

1. Run the benchmark client with `sendnn-bench serve` instead of `vllm bench serve`:

```bash
sendnn-bench serve \
--model {model} \
--endpoint /v1/completions \
--dataset-name {custom/sharegpt/random...} \
--dataset-path {path to dataset} \
--num-prompts {num-prompts} \
--max-concurrency {num-concurrent-users} \
--save-result \
--result-dir {path/to/results} \
--result-filename result.json
```

!!! note

`sendnn-bench` uses its own `spyre-chat` backend by default, which parses the extra metrics out of the streamed response. Do not override it with `--backend`.

Any flag that makes a result JSON be written (`--save-result`, `--plot-timeline`, `--detailed-timeline`) requires **both** `--result-dir` and `--result-filename`, so that the file to inject the Spyre metrics into is unambiguous. `--append-result` is not supported.

The Spyre metrics are printed in a `SenDNN Metrics` section appended to the regular benchmark result table:

```text
============ Serving Benchmark Result ============
Successful requests: XX
...
----------------End-to-end Latency----------------
Mean E2EL (ms): XX
...
================= SenDNN Metrics =================
Total prefill chunks processed: XX
Requests blocked by missing KV blocks: XX
---------------- Queue Wait Time -----------------
Mean Queue Wait Time (ms): XX
Median Queue Wait Time (ms): XX
P99 Queue Wait Time (ms): XX
P100 Queue Wait Time (ms): XX
------------- Chunked Prefill Count --------------
...
------------ Chunked Prefill Latency -------------
...
--------------- Prefill Phase Time ---------------
...
------------- Time Spent Prefilling --------------
...
------------ Prefill Phase Idle Time -------------
...
-------------- Decode Step Latency ---------------
...
---------------- Prefix Cache Hit ----------------
...
-------------- Left Padding Blocks ---------------
...
----------------- Pause Latency ------------------
...
---------------- Number of Pauses ----------------
...
--------------- Total Time Paused ----------------
...
==================================================
```

## Additional Flags

Beyond the upstream `vllm bench serve` flags, `sendnn-bench` adds:

- **`--describe-metrics`**: writes a `sendnn_bench_metrics_description.txt` file into `--result-dir` (or the current directory), documenting what every printed metric measures and its sample granularity (one sample per request, per prefill chunk, per decode step, …). Recommended whenever you share results with someone else.

- **`--detailed-timeline`**: writes a `{result-filename}_detailed_timeline.html` Gantt chart next to the result JSON, viewable in any modern web browser. Unlike the upstream `--plot-timeline` — which shows a single TTFT bar per request — it breaks each request down into its queue wait, its individual chunked prefill steps, and its decode steps, which makes it easy to see where the time actually went.

- **`--decode-thresholds LOW,HIGH`**: two decode latency thresholds in milliseconds used to color the decode steps of the detailed timeline (green below `LOW`, orange between, red above `HIGH`). Only meaningful together with `--detailed-timeline`.

Combined with `--save-result`, per-request Spyre values are also injected into the result JSON as `spyre_*` arrays (`spyre_queued_time_s`, `spyre_chunk_prefill_latencies_s`, `spyre_decode_latencies_s`, `spyre_prefix_cache_hit_pct`, …), aligned with vLLM's own per-request arrays (`ttfts`, `itls`, `start_times`).

!!! info

Plot generation requires the plotting libraries: `uv pip install vllm[bench]`

## Adding a New Metric

The set of collected metrics is meant to grow. The [`add-bench-metric`](https://github.com/torch-spyre/sendnn-inference/blob/main/.claude/skills/add-bench-metric/SKILL.md) Claude Code skill walks through every layer that a new per-request metric has to touch — scheduler-side timing, transport to the client, aggregation, printing, result JSON injection and tests. Give it a precise description of the metric and where its value should be computed:

```text
/add-bench-metric add a metric for the prefix cache hit percent, based on the number of
chunks saved from a cache hit over the expected number of prefill chunks, for each request.
```
4 changes: 4 additions & 0 deletions docs/user_guide/performance.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ The following additional flags can help with insights and result interpretation:
- `--save-detailed`: saves individual recorded data per request (useful for debugging)
- `--result-dir {path/to/results}`: target path for output results

!!! tip

For Spyre-specific per-request metrics (queue wait time, per-chunk prefill latencies, per-step decode latencies, prefix cache hit rate, left padding, pausing), use `sendnn-bench serve` instead of `vllm bench serve`. See [Detailed Performance Measurement](./detailed_performance_measurement.md).

### `--custom-output-len -1`

When running benchmarks, all requests typically use the same `max-tokens` value (the maximum number of output tokens for a request). This value can be set using [`--output-len`](https://docs.vllm.ai/en/stable/cli/bench/serve/#-output-len). For the `custom` dataset (`--dataset-name custom`), if the dataset contains per-request output token counts as shown in the [Custom dataset documentation](https://docs.vllm.ai/en/stable/api/vllm/benchmarks/datasets/#vllm.benchmarks.datasets.CustomDataset), you can load the per-request `max-tokens` using `--custom-output-len -1`. Paired with `--ignore-eos` (which tells the model to ignore the EOS token and always generate exactly `max-tokens` tokens), this makes benchmarks more stable and reproducible, since the number of output tokens is fixed across runs. Without this, output length varies across runs — even at temperature 0.0, unless using [batch invariance](https://docs.vllm.ai/en/latest/features/batch_invariance/#batch-invariance) — making results more variable and difficult to interpret.
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ dynamic = ["version"]
[project.entry-points."vllm.platform_plugins"]
sendnn_inference = "sendnn_inference:register"

[project.scripts]
sendnn-bench = "sendnn_inference.benchmarks.spyre_bench_serve:main"

[tool.setuptools.packages.find]
where = ["."] # list of folders that contain the packages (["."] by default)
include = ["sendnn_inference*"] # package names should match these glob patterns (["*"] by default)
Expand Down
Empty file.
Loading
Loading