vllm-benchmark 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. vllm_benchmark-0.1.0/LICENSE +21 -0
  2. vllm_benchmark-0.1.0/MANIFEST.in +5 -0
  3. vllm_benchmark-0.1.0/PKG-INFO +363 -0
  4. vllm_benchmark-0.1.0/PUBLISHING.md +96 -0
  5. vllm_benchmark-0.1.0/README.md +330 -0
  6. vllm_benchmark-0.1.0/RESULT_FORMAT.md +61 -0
  7. vllm_benchmark-0.1.0/examples/minimal/.vllm_bench/configs/base.yaml +18 -0
  8. vllm_benchmark-0.1.0/examples/minimal/.vllm_bench/configs/local_cpu.yaml +1 -0
  9. vllm_benchmark-0.1.0/examples/minimal/README.md +13 -0
  10. vllm_benchmark-0.1.0/examples/minimal/benchmark.py +9 -0
  11. vllm_benchmark-0.1.0/examples/minimal/startup.py +29 -0
  12. vllm_benchmark-0.1.0/pyproject.toml +54 -0
  13. vllm_benchmark-0.1.0/setup.cfg +4 -0
  14. vllm_benchmark-0.1.0/tests/compose_smoke.py +197 -0
  15. vllm_benchmark-0.1.0/tests/fixtures/benchmark.py +23 -0
  16. vllm_benchmark-0.1.0/tests/fixtures/startup.py +65 -0
  17. vllm_benchmark-0.1.0/tests/test_cli.py +455 -0
  18. vllm_benchmark-0.1.0/tests/test_external.py +191 -0
  19. vllm_benchmark-0.1.0/tests/test_modal.py +163 -0
  20. vllm_benchmark-0.1.0/vllm_bench/__init__.py +3 -0
  21. vllm_benchmark-0.1.0/vllm_bench/artifacts.py +126 -0
  22. vllm_benchmark-0.1.0/vllm_bench/bench_util.py +124 -0
  23. vllm_benchmark-0.1.0/vllm_bench/cli.py +336 -0
  24. vllm_benchmark-0.1.0/vllm_bench/config.py +168 -0
  25. vllm_benchmark-0.1.0/vllm_bench/contracts.py +31 -0
  26. vllm_benchmark-0.1.0/vllm_bench/external.py +61 -0
  27. vllm_benchmark-0.1.0/vllm_bench/gpu.py +92 -0
  28. vllm_benchmark-0.1.0/vllm_bench/json_io.py +12 -0
  29. vllm_benchmark-0.1.0/vllm_bench/metrics.py +115 -0
  30. vllm_benchmark-0.1.0/vllm_bench/processes.py +30 -0
  31. vllm_benchmark-0.1.0/vllm_bench/progress.py +7 -0
  32. vllm_benchmark-0.1.0/vllm_bench/providers/__init__.py +29 -0
  33. vllm_benchmark-0.1.0/vllm_bench/providers/base.py +21 -0
  34. vllm_benchmark-0.1.0/vllm_bench/providers/compose.py +261 -0
  35. vllm_benchmark-0.1.0/vllm_bench/providers/context.py +43 -0
  36. vllm_benchmark-0.1.0/vllm_bench/providers/modal.py +305 -0
  37. vllm_benchmark-0.1.0/vllm_bench/providers/modal_runtime.py +80 -0
  38. vllm_benchmark-0.1.0/vllm_bench/providers/paths.py +8 -0
  39. vllm_benchmark-0.1.0/vllm_bench/reports/__init__.py +5 -0
  40. vllm_benchmark-0.1.0/vllm_bench/reports/cache_hits.py +14 -0
  41. vllm_benchmark-0.1.0/vllm_bench/reports/charts.py +44 -0
  42. vllm_benchmark-0.1.0/vllm_bench/reports/data.py +61 -0
  43. vllm_benchmark-0.1.0/vllm_bench/reports/engine_activity.py +48 -0
  44. vllm_benchmark-0.1.0/vllm_bench/reports/engine_work.py +25 -0
  45. vllm_benchmark-0.1.0/vllm_bench/reports/generator.py +70 -0
  46. vllm_benchmark-0.1.0/vllm_bench/reports/gpu_usage.py +47 -0
  47. vllm_benchmark-0.1.0/vllm_bench/reports/preemptions.py +12 -0
  48. vllm_benchmark-0.1.0/vllm_bench/reports/runtime.py +7 -0
  49. vllm_benchmark-0.1.0/vllm_bench/reports/throughput.py +18 -0
  50. vllm_benchmark-0.1.0/vllm_bench/runner.py +159 -0
  51. vllm_benchmark-0.1.0/vllm_bench/service.py +33 -0
  52. vllm_benchmark-0.1.0/vllm_benchmark.egg-info/PKG-INFO +363 -0
  53. vllm_benchmark-0.1.0/vllm_benchmark.egg-info/SOURCES.txt +55 -0
  54. vllm_benchmark-0.1.0/vllm_benchmark.egg-info/dependency_links.txt +1 -0
  55. vllm_benchmark-0.1.0/vllm_benchmark.egg-info/entry_points.txt +2 -0
  56. vllm_benchmark-0.1.0/vllm_benchmark.egg-info/requires.txt +13 -0
  57. vllm_benchmark-0.1.0/vllm_benchmark.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 viniciusCSreis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,5 @@
1
+ include LICENSE README.md RESULT_FORMAT.md PUBLISHING.md
2
+ recursive-include examples *.py *.yaml *.md
3
+ recursive-include tests *.py
4
+ prune examples/minimal/results
5
+ global-exclude __pycache__ *.py[cod]
@@ -0,0 +1,363 @@
1
+ Metadata-Version: 2.4
2
+ Name: vllm-benchmark
3
+ Version: 0.1.0
4
+ Summary: Run script-defined vLLM benchmarks through Docker Compose or Modal.
5
+ Author: viniciusCSreis
6
+ License-Expression: MIT
7
+ Project-URL: Repository, https://github.com/viniciusCSreis/vllm_benchmark
8
+ Project-URL: Issues, https://github.com/viniciusCSreis/vllm_benchmark/issues
9
+ Keywords: vllm,benchmark,docker,modal,inference
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Environment :: Console
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: System :: Benchmark
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: pydantic<3,>=2.12
22
+ Requires-Dist: PyYAML>=6
23
+ Requires-Dist: requests>=2.26
24
+ Requires-Dist: prometheus-client>=0.18
25
+ Requires-Dist: matplotlib>=3.7
26
+ Provides-Extra: modal
27
+ Requires-Dist: modal<2,>=1.6.2; extra == "modal"
28
+ Provides-Extra: dev
29
+ Requires-Dist: build>=1.2; extra == "dev"
30
+ Requires-Dist: twine>=6; extra == "dev"
31
+ Requires-Dist: ruff>=0.11; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ # vllm_bench
35
+
36
+ Run user-defined vLLM benchmarks against existing service URLs or with services
37
+ managed through Docker Compose or Modal. Benchmark
38
+ scripts and the runner execute on your machine; startup scripts execute in
39
+ containers. The same Python library supplies arguments and service addresses to
40
+ both. The provider owns service infrastructure; the runner and reports are shared.
41
+
42
+ ## Install
43
+
44
+ Requires Python 3.11 or newer on the host and in service images. Local runs
45
+ require Docker Compose v2; Modal runs require a Modal account and the optional
46
+ SDK. Once published on PyPI:
47
+
48
+ ```bash
49
+ python -m pip install vllm-benchmark
50
+ # Or, with Modal support:
51
+ python -m pip install 'vllm-benchmark[modal]'
52
+ ```
53
+
54
+ For development, clone this repository and run `python -m pip install -e '.[dev]'`.
55
+ No vLLM installation or sibling repository is required on the host unless your
56
+ own benchmark scripts need it. Project service images supply their own runtime
57
+ dependencies, such as PyTorch, vLLM, or FAISS.
58
+
59
+ The local provider mounts the installed `vllm_bench` package read-only into every
60
+ service container. Modal copies it into the remote image. Providers override
61
+ startup to run a wrapper that launches your configured script, samples GPUs,
62
+ and handles shutdown. Images need no CLI installation or special entrypoint;
63
+ no packages are installed at service startup. Service scripts can use
64
+ `from vllm_bench import bench_util` without an initialization call.
65
+
66
+ Try the [minimal example](examples/minimal/README.md) with an ordinary Python
67
+ image and no model download:
68
+
69
+ ```bash
70
+ cd examples/minimal
71
+ vllm_bench run_scenarios --benchmark example --scenario baseline
72
+ ```
73
+
74
+ ## Commands and selection
75
+
76
+ A project supplies `.vllm_bench/configs/base.yaml` plus environment configs:
77
+ `local_cpu.yaml`, `local_cpu_arm.yaml`, and `modal.yaml`. The default environment
78
+ is `local_cpu`; choose another with `--config`. Environment selection is separate
79
+ from benchmark and scenario selection.
80
+
81
+ Both `up` and `run_scenarios` require `--benchmark` and `--scenario`. The plural aliases
82
+ `--benchmarks` and `--scenarios` work too. Each accepts one or more names or `'*'`
83
+ on its own. Quote the wildcard so your shell does not expand it into filenames.
84
+
85
+ ```bash
86
+ # Every scenario for one benchmark:
87
+ vllm_bench run_scenarios --config local_cpu --benchmark example --scenarios '*'
88
+ # A named scenario across all benchmarks:
89
+ vllm_bench run_scenarios --benchmark '*' --scenario baseline
90
+ # Every benchmark and its own scenarios:
91
+ vllm_bench run_scenarios --benchmark '*' --scenario '*'
92
+ # Explicit subsets:
93
+ vllm_bench run_scenarios --benchmark example other --scenario baseline distributed
94
+ # Start one environment and follow its logs:
95
+ vllm_bench up --config local_cpu_arm --benchmark example --scenario baseline
96
+ vllm_bench down
97
+ vllm_bench report results/local-comparison/run001
98
+ ```
99
+
100
+ A named scenario must exist in every selected benchmark. Unknown names fail
101
+ before starting containers, stopping an active environment, or saving results.
102
+ A scenario wildcard uses each benchmark's own scenarios; they need not match.
103
+ `run_scenarios` creates fresh services for every selected benchmark/scenario/repeat and
104
+ then generates reports. The former `run` command is now named `run_scenarios`.
105
+
106
+ `up` must resolve to exactly one benchmark/scenario pair. It only attaches to an
107
+ active environment when provider, image, benchmark, scenario, and arguments match.
108
+ It streams logs;
109
+ Ctrl+C stops services and saves output. Use `up -d` to leave it running, then
110
+ `down` to stop it. `down` uses saved state, and `report` uses its result directory,
111
+ so neither needs benchmark/scenario selectors or an environment config.
112
+
113
+ `run_scenarios` stops an existing environment only after validating the complete selection.
114
+ Failures retain partial results and continue; Ctrl+C stops the experiment.
115
+ Cleanup failures preserve recovery state for `down` and stop further scheduling.
116
+ Reports can be regenerated offline.
117
+
118
+ `--current-dir /path/to/project` works before or after any command and sets the
119
+ root for config lookup, scripts, snapshots, runtime state, and results. Relative
120
+ report paths also resolve from this root. `--config` works before or after `up`
121
+ or `run_scenarios`; it accepts an environment name or YAML path.
122
+
123
+ ## Run against existing services
124
+
125
+ `run_only` executes exactly one benchmark/scenario once, regardless of `runs`.
126
+ It does not start, stop, reconfigure, or restart services, and leaves any active
127
+ `up` environment and its state file untouched. It uses the same benchmark executor
128
+ and report format as `run_scenarios`. Managed runs use the startup/readiness
129
+ routine shared with `up` and the provider shutdown used by `down` after each trial,
130
+ including failed trials.
131
+
132
+ ```bash
133
+ vllm_bench run_only --config local_cpu \
134
+ --benchmark example --scenario baseline \
135
+ --service-url leader=https://example.com:8000
136
+ ```
137
+
138
+ Repeat `--service-url NAME=URL` for each required service. Names match the config's
139
+ `services` keys. Supply every service selected by the scenario and benchmark
140
+ service dependencies; unknown, duplicate, and missing names fail before execution.
141
+ URLs must be HTTP(S) base URLs, including any reverse-proxy prefix. Each supplied
142
+ service group describes one external endpoint; `replicas` controls managed services
143
+ only. The client uses the supplied URLs for health checks, metrics, and benchmark
144
+ requests. `internal=True` returns the same URLs in this mode, so services that call
145
+ each other must also be able to reach those addresses.
146
+
147
+ Only benchmark scripts need to exist locally. An external-only config can omit
148
+ `base_image` and service `startup_script`; `up` and `run_scenarios` still require
149
+ those fields. Set `global_args` and `service_args` to match the models already
150
+ served. Selecting a scenario records its arguments; it does not change the remote
151
+ server's coordinator or model. The old `run` command has been renamed to
152
+ `run_scenarios`.
153
+
154
+ Results are saved under `results/external-<name>/runNNN/`, with one trial,
155
+ endpoint URLs, the client context, logs, metrics, and reports. External runs do not
156
+ upload a project snapshot, transfer inputs, or collect server logs/GPU samples.
157
+ When the client and servers share a filesystem, `get_service_path()` returns the
158
+ local path unchanged. For cloud deployments, make inputs available to the servers
159
+ first; `--dataset-path /server/path` passes that value as the benchmark's
160
+ `dataset_path` argument. Your benchmark adapter decides how to use it.
161
+
162
+ After health checks pass, `up` prints a copyable `run_only` command before the
163
+ endpoint and log details, including the selected config, project, benchmark,
164
+ scenario, and service URLs. You can start an environment with `up -d`, then run
165
+ that command as often as needed before stopping it with `down`. Supply dataset paths
166
+ visible to that existing environment when it cannot access the client's paths.
167
+
168
+ ## Configuration
169
+
170
+ `base.yaml` defines shared services and scenarios. Benchmarks reference scenario names. For example:
171
+
172
+ ```yaml
173
+ name: comparison
174
+ services:
175
+ leader:
176
+ role: leader
177
+ startup_script: scripts/start_leader.py
178
+ health_port: 8000
179
+ metrics_path: /metrics
180
+ worker:
181
+ role: worker
182
+ startup_script: scripts/start_worker.py
183
+ health_port: 8000
184
+ metrics_path: /metrics
185
+ scenarios:
186
+ baseline:
187
+ args:
188
+ coordinator: single_worker
189
+ services: [leader]
190
+ distributed:
191
+ args:
192
+ coordinator: round_robin
193
+ services: [leader, worker]
194
+ benchmarks:
195
+ example:
196
+ script: scripts/benchmark.py
197
+ script_args:
198
+ dataset_percentage: 0.1
199
+ scenarios: [baseline, distributed]
200
+ runs: 1
201
+ startup_timeout: 1800
202
+ benchmark_timeout: 3600
203
+ sample_interval: 1
204
+ ```
205
+
206
+ `local_cpu.yaml` selects the local image and model:
207
+
208
+ ```yaml
209
+ provider: local
210
+ base_image: my-project:cpu
211
+ global_args:
212
+ model: Qwen/Qwen2.5-0.5B-Instruct
213
+ ```
214
+
215
+ `local_cpu_arm.yaml` uses the same structure with an ARM64 CPU image.
216
+ An environment config automatically merges over its sibling `base.yaml`.
217
+ Mappings merge recursively; child lists and scalar values replace base values.
218
+ `extends: other_config` can inherit another environment before applying overrides.
219
+ Saved runs contain the resolved environment, shared scenario definitions, and
220
+ selected benchmarks with their selected scenario references. There are no separate benchmark YAML files or `benchmark_scenarios` field.
221
+
222
+ Scenarios are defined once in the top-level `scenarios` mapping. Each benchmark
223
+ selects a nonempty list of unique scenario names. Every scenario declares a
224
+ nonempty list of known service names. A benchmark may also declare `services: [icp]` to add dependencies to every selected scenario. The CLI combines both
225
+ service lists, removes overlaps, and expands each service to its replica count.
226
+ Scenario and benchmark arguments are arbitrary project data.
227
+ Names use lowercase letters, digits, underscores, or hyphens, starting with a
228
+ letter. Script paths are relative to the project root.
229
+
230
+ Optional settings:
231
+
232
+ - Service `replicas`: number of instances; defaults to one.
233
+ - Service `gpus: all` or `gpus: ["0"]`: local NVIDIA GPU allocation. Omit for CPU.
234
+ - Service `environment`: extra string environment values.
235
+ - Service `service_args`: arguments that override `global_args` for that service.
236
+ Startup scripts use `bench_util.get_service_args()` to read the merged values;
237
+ clients can use `bench_util.get_service_args("cascade")` for a named service.
238
+ Unspecified arguments inherit global values; `get_global_args()` stays unchanged.
239
+ - Service `health_path`: defaults to `/health`; omit `metrics_path` if unavailable.
240
+ - `skip_volume_mount: true`: use project code already inside the image.
241
+ - `image_workdir`: project directory for that mode; defaults to `/workspace/project`.
242
+
243
+ Startup scripts bind to `0.0.0.0` on their assigned service port and run in the
244
+ foreground. Returning stops the service. Images must support the selected
245
+ hardware; a CUDA-only vLLM build cannot automatically run on CPU.
246
+
247
+ ## Modal
248
+
249
+ Install `python -m pip install 'vllm-benchmark[modal]'` and authenticate with
250
+ `modal setup`. Define `.vllm_bench/configs/modal.yaml`:
251
+
252
+ ```yaml
253
+ provider: modal
254
+ base_image: your-registry/benchmark:cuda
255
+ global_args:
256
+ model: Qwen/Qwen2.5-0.5B-Instruct
257
+ modal:
258
+ app: vllm-bench
259
+ gpu: T4:1
260
+ cpu: 8
261
+ memory: 16384
262
+ timeout: 14400
263
+ cache_volume: vllm-bench-model-cache
264
+ ```
265
+
266
+ ```bash
267
+ vllm_bench run_scenarios --config modal --benchmark example --scenario '*'
268
+ vllm_bench up --config modal --benchmark example --scenario baseline
269
+ vllm_bench down
270
+ ```
271
+
272
+ The registry image contains project dependencies; Modal copies the installed CLI
273
+ library into it without installing packages at startup. Each trial uses one
274
+ sandbox in the named Modal App. Services share its CPU/GPU allocation and use
275
+ separate ports. Service `gpus` settings apply to local Compose; `modal.gpu` sets
276
+ the remote allocation. Memory is in MiB, and timeout is the sandbox lifetime in
277
+ seconds. The model-cache volume mounts at `/mnt/vllm-bench-cache`; the provider
278
+ points `HF_HOME`, `VLLM_CACHE_ROOT`, and `XDG_CACHE_HOME` there. This keeps the
279
+ mount separate from cache files already baked into the service image. Pin the registry image digest for reproducible runs: Modal can cache
280
+ mutable tags after the registry image changes.
281
+
282
+ Project snapshots and client-generated dataset files are uploaded. Benchmark
283
+ scripts, metrics collection, and reports execute locally using HTTPS tunnels.
284
+ Use `bench_util` for addresses, assigned ports, and file paths. Shutdown downloads
285
+ service output and logs. If the sandbox exits early, available combined logs are
286
+ saved as `modal.log`; service files may no longer be available.
287
+
288
+ ## Script library
289
+
290
+ ```python
291
+ from vllm_bench import bench_util
292
+
293
+ model = bench_util.get_global_arg("model")
294
+ options = bench_util.get_service_args()
295
+ coordinator = bench_util.get_scenario_arg("coordinator")
296
+ fraction = bench_util.get_benchmark_arg("dataset_percentage", 1.0)
297
+ repeat = bench_util.current_run
298
+ benchmark = bench_util.current_benchmark
299
+ output = bench_util.get_output_dir()
300
+ ```
301
+
302
+ Other helpers:
303
+
304
+ - `get_project_dir()` returns the project root in the calling environment.
305
+ - `get_service()` returns the calling startup's name, role, replica, and URL;
306
+ it returns `None` in client benchmark scripts.
307
+ - `get_leader_url()` and `get_worker_urls()` choose the correct addresses for
308
+ the calling environment. Disabled workers yield an empty list.
309
+ - `get_service_url("icp")` returns a named service. For a replicated group, use
310
+ its individual name such as `worker-1`.
311
+ - `get_service_url("icp", internal=True)` returns the container address when
312
+ constructing a benchmark payload that the leader will execute.
313
+ - `get_service_path(local_path)` translates project/trial paths in a client
314
+ benchmark to paths readable inside the containers.
315
+ - `get_gpu_count()`, `is_gpu_available()`, and `is_cpu()` inspect the calling
316
+ environment using `nvidia-smi` without importing PyTorch.
317
+
318
+ Benchmark scripts write `response.json` in `get_output_dir()`. Arbitrary JSON
319
+ is preserved. When present, a numeric `latency_sec` and a `results` list provide
320
+ additional summary fields; process runtime is measured independently.
321
+
322
+ ## Files and infrastructure
323
+
324
+ The CLI library is mounted read-only at `/opt/vllm-bench-lib/vllm_bench`,
325
+ independently of the project mount and even with `skip_volume_mount: true`.
326
+ Keep the host installation available while containers run. Compose uses
327
+ `python3 -m vllm_bench.service` as its startup override and prepends the library
328
+ location to the configured service `PYTHONPATH`.
329
+
330
+ The project is mounted read-only at `/workspace/project`. Each trial directory
331
+ is mounted writable at `/run/vllm-bench/trial`; `get_output_dir()` selects the
332
+ client trial directory or a replica's service subdirectory. Docker logs and GPU
333
+ samples are saved under `services/<group>-<replica>/`.
334
+
335
+ The generated Compose file, resolved per-service contexts, and provider IDs are
336
+ saved under the trial's `.provider/`. The active state is recorded under the
337
+ project's `.vllm_bench/state.json`. Host ports bind to `127.0.0.1` and container addresses
338
+ use Compose DNS. A named model-cache volume persists after `down`.
339
+
340
+ By default, each run also saves a ZIP of nonignored project files. Results,
341
+ environments, native binaries, caches, `.env` files, and generated wheels are
342
+ excluded. The live local project mount reflects subsequent edits; keep files
343
+ unchanged during a run when comparing its saved snapshot.
344
+
345
+ See [RESULT_FORMAT.md](RESULT_FORMAT.md) for the saved contract and reports.
346
+
347
+ ## Development checks
348
+
349
+ ```bash
350
+ python -m pip install -e '.[dev]'
351
+ ruff check .
352
+ python -m unittest discover -s tests
353
+ python tests/compose_smoke.py --image python:3.12-slim
354
+ ```
355
+
356
+ The opt-in Compose check launches HTTP stand-ins with Prometheus metrics. It
357
+ checks lifecycle, endpoints, mounting, scenarios, collection, and reports without
358
+ loading any model or allocating cloud resources.
359
+
360
+ ## Publishing and license
361
+
362
+ See [PUBLISHING.md](PUBLISHING.md) for GitHub setup, package checks, and PyPI
363
+ Trusted Publishing. The project uses the [MIT license](LICENSE).
@@ -0,0 +1,96 @@
1
+ # Publishing vllm-benchmark
2
+
3
+ This directory is an independent Git repository. The distribution is named
4
+ `vllm-benchmark`, the Python package and command are `vllm_bench`, and the source
5
+ repository is `viniciusCSreis/vllm_benchmark`. The project uses the MIT license.
6
+ No sibling checkout is needed to build, test, install, or publish it.
7
+
8
+ ## Create the public repository
9
+
10
+ Create an empty public GitHub repository named `vllm_benchmark` under
11
+ `viniciusCSreis`. Do not initialize it with a README or license; these files
12
+ already exist locally. From this directory:
13
+
14
+ ```bash
15
+ git add .
16
+ git commit -m "Prepare standalone benchmark package"
17
+ git remote add origin https://github.com/viniciusCSreis/vllm_benchmark.git
18
+ git push -u origin HEAD
19
+ ```
20
+
21
+ If `origin` already exists, inspect `git remote -v` and use `git remote set-url`
22
+ instead of adding it again. Update `[project.urls]` in `pyproject.toml` if you
23
+ choose another owner or repository name.
24
+
25
+ ## Check a release locally
26
+
27
+ ```bash
28
+ python3 -m venv .venv
29
+ source .venv/bin/activate
30
+ python -m pip install -e '.[dev]'
31
+ ruff check .
32
+ python -m unittest discover -s tests
33
+ python tests/compose_smoke.py --image python:3.12-slim
34
+ python -m build
35
+ python -m twine check dist/*
36
+ ```
37
+
38
+ The Compose smoke check requires Docker and launches ordinary Python containers;
39
+ it does not load a model or allocate cloud GPUs. The build creates a wheel and
40
+ source distribution in `dist/`. Use an empty `dist/` for each release so older
41
+ versions are not uploaded with it.
42
+
43
+ The version is defined only in `vllm_bench/__init__.py`; the initial release is
44
+ `0.1.0`. Change it before every later release. PyPI does not allow reusing an
45
+ uploaded version's filenames.
46
+
47
+ ## Configure PyPI Trusted Publishing
48
+
49
+ 1. Create a PyPI account, verify your email, and enable two-factor authentication.
50
+ 2. In GitHub repository Settings, create an Actions environment named `pypi`.
51
+ 3. Open <https://pypi.org/manage/account/publishing/> and add a pending GitHub
52
+ publisher with these exact values:
53
+
54
+ | Field | Value |
55
+ | --- | --- |
56
+ | PyPI project name | `vllm-benchmark` |
57
+ | Owner | `viniciusCSreis` |
58
+ | Repository | `vllm_benchmark` |
59
+ | Workflow filename | `publish.yml` |
60
+ | Environment | `pypi` |
61
+
62
+ The package name had no public PyPI project during preparation; PyPI still must
63
+ accept the name when you register/publish. If it is unavailable, choose another
64
+ `[project].name` and update this guide, install commands, and the workflow URL.
65
+ The import name can remain `vllm_bench`.
66
+
67
+ See PyPI's [pending publisher instructions](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/)
68
+ and [GitHub Actions publishing guide](https://docs.pypi.org/trusted-publishers/using-a-publisher/).
69
+ The workflow authenticates with GitHub OIDC, so no PyPI API-token secret is needed.
70
+
71
+ ## Publish the release
72
+
73
+ Wait for CI to pass, then create and push a version tag:
74
+
75
+ ```bash
76
+ git tag v0.1.0
77
+ git push origin v0.1.0
78
+ ```
79
+
80
+ On GitHub, create and publish a Release using that existing tag. Publishing the
81
+ release triggers `.github/workflows/publish.yml`; pushing a tag alone does not.
82
+ The workflow runs checks, verifies the tag matches the package version, builds
83
+ both distributions, and uploads them to PyPI through the `pypi` environment.
84
+ If you configured environment reviewers, approve the waiting publish job.
85
+
86
+ After the workflow succeeds, check installation in a fresh virtual environment:
87
+
88
+ ```bash
89
+ python3 -m venv /tmp/vllm-benchmark-check
90
+ /tmp/vllm-benchmark-check/bin/python -m pip install vllm-benchmark
91
+ /tmp/vllm-benchmark-check/bin/vllm_bench --version
92
+ ```
93
+
94
+ Users install Modal support with `python -m pip install 'vllm-benchmark[modal]'`.
95
+ For later releases, update the version, commit and push, then repeat with the
96
+ matching `vX.Y.Z` tag and GitHub Release.