benchscope 1.0.4__tar.gz → 1.0.6__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 (90) hide show
  1. benchscope-1.0.6/PKG-INFO +85 -0
  2. benchscope-1.0.6/README.md +50 -0
  3. benchscope-1.0.6/benchscope/__init__.py +4 -0
  4. benchscope-1.0.6/benchscope/benches/base.py +192 -0
  5. benchscope-1.0.6/benchscope/benches/runner.py +376 -0
  6. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/benches/sglang_bench.py +8 -1
  7. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/benches/vllm_bench.py +8 -1
  8. benchscope-1.0.6/benchscope/builtin_datasets.py +103 -0
  9. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/cli.py +22 -2
  10. benchscope-1.0.6/benchscope/config.py +234 -0
  11. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/constants.py +11 -3
  12. benchscope-1.0.6/benchscope/env_info.py +145 -0
  13. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/parser.py +28 -7
  14. benchscope-1.0.6/benchscope/server/api_config.py +431 -0
  15. benchscope-1.0.6/benchscope/server/api_dashboard.py +90 -0
  16. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/server/api_logs.py +188 -24
  17. benchscope-1.0.6/benchscope/server/api_sessions.py +85 -0
  18. benchscope-1.0.6/benchscope/server/api_tasks.py +199 -0
  19. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/server/app.py +39 -12
  20. benchscope-1.0.6/benchscope/server/state.py +23 -0
  21. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/server/test_manager.py +27 -8
  22. benchscope-1.0.6/benchscope/session_manager.py +388 -0
  23. benchscope-1.0.6/benchscope/task_manager.py +585 -0
  24. benchscope-1.0.6/benchscope/webui/assets/AccuracyView-BjuVpuFU.css +1 -0
  25. benchscope-1.0.6/benchscope/webui/assets/AccuracyView-DuYXlzdF.js +1 -0
  26. benchscope-1.0.6/benchscope/webui/assets/DashboardView-B9NSQxgY.js +1 -0
  27. benchscope-1.0.6/benchscope/webui/assets/DashboardView-efxhNbZA.css +1 -0
  28. benchscope-1.0.6/benchscope/webui/assets/DatasAnalysisView-D4kMXxJP.css +1 -0
  29. benchscope-1.0.6/benchscope/webui/assets/DatasAnalysisView-Dq2PU74U.js +1 -0
  30. benchscope-1.0.6/benchscope/webui/assets/DatasEvalsView-CKDm5d0o.js +1 -0
  31. benchscope-1.0.6/benchscope/webui/assets/DatasEvalsView-Dw2s8Caq.css +1 -0
  32. benchscope-1.0.6/benchscope/webui/assets/DatasPerfsView-CiHoLV4u.js +22 -0
  33. benchscope-1.0.6/benchscope/webui/assets/DatasPerfsView-iOsgANDF.css +1 -0
  34. benchscope-1.0.6/benchscope/webui/assets/DatasView-CelHF7nF.js +1 -0
  35. benchscope-1.0.6/benchscope/webui/assets/DatasView-RZvG0ZHh.css +1 -0
  36. benchscope-1.0.6/benchscope/webui/assets/MetricsTable-BqMrqOR7.css +1 -0
  37. benchscope-1.0.6/benchscope/webui/assets/MetricsTable-CnuI6iCF.js +1 -0
  38. benchscope-1.0.6/benchscope/webui/assets/PerfCreateView-CuS38i63.js +5 -0
  39. benchscope-1.0.6/benchscope/webui/assets/PerfCreateView-snqxkmyk.css +1 -0
  40. benchscope-1.0.6/benchscope/webui/assets/PerformanceView-CHLBhiQ5.css +1 -0
  41. benchscope-1.0.6/benchscope/webui/assets/PerformanceView-KOF5Mglm.js +2 -0
  42. benchscope-1.0.6/benchscope/webui/assets/SessionsView-DD5s41VZ.js +4 -0
  43. benchscope-1.0.6/benchscope/webui/assets/SessionsView-M3-edhM0.css +1 -0
  44. benchscope-1.0.6/benchscope/webui/assets/SettingsView-8-rKWxWv.css +1 -0
  45. benchscope-1.0.6/benchscope/webui/assets/SettingsView-zpGCDV5m.js +1 -0
  46. benchscope-1.0.4/benchscope/webui/assets/antd-CmFZS0N1.js → benchscope-1.0.6/benchscope/webui/assets/antd-CEH7kT1R.js +97 -97
  47. benchscope-1.0.4/benchscope/webui/assets/echarts-Bb6yjXMn.js → benchscope-1.0.6/benchscope/webui/assets/echarts-52vywGac.js +24 -24
  48. benchscope-1.0.4/benchscope/webui/assets/index-N9BkGck-.css → benchscope-1.0.6/benchscope/webui/assets/index-BOkjDk-W.css +1 -1
  49. benchscope-1.0.6/benchscope/webui/assets/index-DN0xzMJ_.js +2 -0
  50. benchscope-1.0.4/benchscope/webui/assets/vue-Ch4zjUb1.js → benchscope-1.0.6/benchscope/webui/assets/vue-q1XafS6H.js +11 -11
  51. benchscope-1.0.6/benchscope/webui/blue_logo.png +0 -0
  52. benchscope-1.0.6/benchscope/webui/bs-logo.png +0 -0
  53. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/webui/index.html +5 -4
  54. benchscope-1.0.6/benchscope.egg-info/PKG-INFO +85 -0
  55. benchscope-1.0.6/benchscope.egg-info/SOURCES.txt +69 -0
  56. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope.egg-info/requires.txt +1 -0
  57. {benchscope-1.0.4 → benchscope-1.0.6}/pyproject.toml +7 -2
  58. benchscope-1.0.4/PKG-INFO +0 -133
  59. benchscope-1.0.4/README.md +0 -99
  60. benchscope-1.0.4/benchscope/__init__.py +0 -3
  61. benchscope-1.0.4/benchscope/benches/base.py +0 -54
  62. benchscope-1.0.4/benchscope/benches/runner.py +0 -185
  63. benchscope-1.0.4/benchscope/config.py +0 -91
  64. benchscope-1.0.4/benchscope/server/api_config.py +0 -97
  65. benchscope-1.0.4/benchscope/server/state.py +0 -18
  66. benchscope-1.0.4/benchscope/webui/assets/LogView-BDFIduo7.css +0 -1
  67. benchscope-1.0.4/benchscope/webui/assets/LogView-TcA_htXa.js +0 -1
  68. benchscope-1.0.4/benchscope/webui/assets/MetricsCharts-2foAhO3l.js +0 -1
  69. benchscope-1.0.4/benchscope/webui/assets/MetricsCharts-D1wU0LbK.css +0 -1
  70. benchscope-1.0.4/benchscope/webui/assets/SettingsView-7uuTFqXU.css +0 -1
  71. benchscope-1.0.4/benchscope/webui/assets/SettingsView-DNICupmh.js +0 -1
  72. benchscope-1.0.4/benchscope/webui/assets/TestView-BAwcOtR2.css +0 -1
  73. benchscope-1.0.4/benchscope/webui/assets/TestView-CkHWJhib.js +0 -4
  74. benchscope-1.0.4/benchscope/webui/assets/index-CySBHSRE.js +0 -2
  75. benchscope-1.0.4/benchscope.egg-info/PKG-INFO +0 -133
  76. benchscope-1.0.4/benchscope.egg-info/SOURCES.txt +0 -46
  77. {benchscope-1.0.4 → benchscope-1.0.6}/LICENSE +0 -0
  78. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/__main__.py +0 -0
  79. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/benches/__init__.py +0 -0
  80. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/datasets.py +0 -0
  81. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/gpu.py +0 -0
  82. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/server/__init__.py +0 -0
  83. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/server/api_test.py +0 -0
  84. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/server/status.py +0 -0
  85. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/server/ws.py +0 -0
  86. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope/summary.py +0 -0
  87. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope.egg-info/dependency_links.txt +0 -0
  88. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope.egg-info/entry_points.txt +0 -0
  89. {benchscope-1.0.4 → benchscope-1.0.6}/benchscope.egg-info/top_level.txt +0 -0
  90. {benchscope-1.0.4 → benchscope-1.0.6}/setup.cfg +0 -0
@@ -0,0 +1,85 @@
1
+ Metadata-Version: 2.4
2
+ Name: benchscope
3
+ Version: 1.0.6
4
+ Summary: LLM inference performance testing tool. Supports vLLM, SGLang, and any OpenAI-compatible API.
5
+ Author-email: benchscope <labelnet@foxmail.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/LABELNET/benchscope
8
+ Project-URL: Documentation, https://github.com/LABELNET/benchscope#readme
9
+ Project-URL: Source, https://github.com/LABELNET/benchscope
10
+ Keywords: vllm,sglang,benchmark,llm,performance-test,inference,openai-api,web-ui,benchscope
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Classifier: Topic :: System :: Benchmark
21
+ Classifier: Framework :: FastAPI
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: fastapi>=0.110
26
+ Requires-Dist: uvicorn[standard]>=0.29
27
+ Requires-Dist: requests>=2.31
28
+ Requires-Dist: openpyxl>=3.1
29
+ Requires-Dist: pydantic>=2
30
+ Requires-Dist: python-multipart>=0.0.9
31
+ Requires-Dist: pyyaml>=6.0
32
+ Provides-Extra: modelscope
33
+ Requires-Dist: modelscope>=1.15; extra == "modelscope"
34
+ Dynamic: license-file
35
+
36
+ <div align="center">
37
+ <img src="asserts/black_logo.png" width="120" height="120" alt="BenchScope logo" />
38
+ </div>
39
+
40
+ <h1 align="center" style="font-size: 48px; margin-top: 12px;">BenchScope</h1>
41
+
42
+ <p align="center"><strong>English</strong> | <a href="README.zh-CN.md">简体中文</a></p>
43
+
44
+ BenchScope is an open‑source LLM inference benchmarking platform built with herness coding.
45
+
46
+ A visualization testing platform for LLM model **performance & accuracy**, supporting models deployed with vLLM / SGLang and any OpenAI-compatible inference service.
47
+
48
+ <div align="center">
49
+ <img src="asserts/main-performance.png" width="72%" alt="BenchScope main performance screenshot" />
50
+ </div>
51
+
52
+ ---
53
+
54
+ ## Features
55
+
56
+ - **Easy to install** — `pip install` and one command starts the whole web platform.
57
+ - **Performance testing dual mode** — Concurrency Mode (multi-level concurrency load) and Threshold Mode (auto-search the max concurrency meeting the threshold).
58
+ - **Accuracy testing dual mode** — Online / offline testing (planned, v5.0).
59
+ - **Real-time data feedback** — every concurrency result streams into tables, charts and progress in real time.
60
+ - **Visualization curves** — multi-dimensional charts for throughput / TTFT / TPOT / ITL.
61
+ - **Log cache & download** — run logs, mean/P99 summaries and Excel export with online preview & download.
62
+
63
+ ## Quick Start
64
+
65
+ ```bash
66
+ # Install from PyPI
67
+ pip install benchscope
68
+
69
+ # Start
70
+ benchscope
71
+
72
+ # Options
73
+ benchscope --port 8080 --no-browser
74
+ ```
75
+
76
+ ## Development
77
+
78
+ See [docs/Readme.md](docs/Readme.md).
79
+
80
+ ## Open Source
81
+
82
+ - **License** — [Apache License 2.0](LICENSE)
83
+ - **Published on** — [PyPI: benchscope](https://pypi.org/project/benchscope/)
84
+ - **Source** — <https://github.com/LABELNET/benchscope>
85
+ - **Contributing** — Feel free to open issues / pull requests on the source repository.
@@ -0,0 +1,50 @@
1
+ <div align="center">
2
+ <img src="asserts/black_logo.png" width="120" height="120" alt="BenchScope logo" />
3
+ </div>
4
+
5
+ <h1 align="center" style="font-size: 48px; margin-top: 12px;">BenchScope</h1>
6
+
7
+ <p align="center"><strong>English</strong> | <a href="README.zh-CN.md">简体中文</a></p>
8
+
9
+ BenchScope is an open‑source LLM inference benchmarking platform built with herness coding.
10
+
11
+ A visualization testing platform for LLM model **performance & accuracy**, supporting models deployed with vLLM / SGLang and any OpenAI-compatible inference service.
12
+
13
+ <div align="center">
14
+ <img src="asserts/main-performance.png" width="72%" alt="BenchScope main performance screenshot" />
15
+ </div>
16
+
17
+ ---
18
+
19
+ ## Features
20
+
21
+ - **Easy to install** — `pip install` and one command starts the whole web platform.
22
+ - **Performance testing dual mode** — Concurrency Mode (multi-level concurrency load) and Threshold Mode (auto-search the max concurrency meeting the threshold).
23
+ - **Accuracy testing dual mode** — Online / offline testing (planned, v5.0).
24
+ - **Real-time data feedback** — every concurrency result streams into tables, charts and progress in real time.
25
+ - **Visualization curves** — multi-dimensional charts for throughput / TTFT / TPOT / ITL.
26
+ - **Log cache & download** — run logs, mean/P99 summaries and Excel export with online preview & download.
27
+
28
+ ## Quick Start
29
+
30
+ ```bash
31
+ # Install from PyPI
32
+ pip install benchscope
33
+
34
+ # Start
35
+ benchscope
36
+
37
+ # Options
38
+ benchscope --port 8080 --no-browser
39
+ ```
40
+
41
+ ## Development
42
+
43
+ See [docs/Readme.md](docs/Readme.md).
44
+
45
+ ## Open Source
46
+
47
+ - **License** — [Apache License 2.0](LICENSE)
48
+ - **Published on** — [PyPI: benchscope](https://pypi.org/project/benchscope/)
49
+ - **Source** — <https://github.com/LABELNET/benchscope>
50
+ - **Contributing** — Feel free to open issues / pull requests on the source repository.
@@ -0,0 +1,4 @@
1
+ """BenchScope - LLM inference performance testing tool."""
2
+
3
+ # PEP 440:开发中带 .dev0 后缀,正式发布时改为 "1.0.6"
4
+ __version__ = "1.0.6"
@@ -0,0 +1,192 @@
1
+ """bench 命令构建的公共定义。"""
2
+ from __future__ import annotations
3
+
4
+ from dataclasses import dataclass, field
5
+ from typing import Any
6
+
7
+
8
+ @dataclass
9
+ class ParamDef:
10
+ """UI 表单中一个可配置参数的定义。"""
11
+
12
+ key: str # 表单字段名
13
+ flag: str # 实际 CLI flag,如 "--temperature"
14
+ label: str # 中文标签
15
+ help: str = ""
16
+ type: str = "str" # str | int | float | bool | select
17
+ default: Any = None
18
+ options: list = field(default_factory=list)
19
+ advanced: bool = False # 是否归入“高级参数”折叠区
20
+
21
+
22
+ @dataclass
23
+ class BenchOptions:
24
+ """一次 bench 执行所需的全部选项。"""
25
+
26
+ framework: str
27
+ model: str
28
+ api: dict # {host, port, base_url, endpoint, api_key, extra_headers}
29
+ dataset: dict # {type, path, input_len, output_len, sharegpt_output_len}
30
+ concurrency: int
31
+ request_rate: str | float = "inf"
32
+ curated: dict = field(default_factory=dict) # 表单参数 key -> value
33
+ extra_args: list = field(default_factory=list) # [{"flag": "--x", "value": "y"}]
34
+
35
+
36
+ def build_arg_list(flags: list[list]) -> list[str]:
37
+ """将 [["--flag","value"], ["--bool",""]] 展开为命令行列表。"""
38
+ out: list[str] = []
39
+ for item in flags:
40
+ flag, value = item[0], item[1] if len(item) > 1 else ""
41
+ if isinstance(value, bool):
42
+ if value:
43
+ out.append(flag)
44
+ continue
45
+ if value is None or value == "":
46
+ out.append(flag)
47
+ else:
48
+ out.extend([flag, str(value)])
49
+ return out
50
+
51
+
52
+ def flag_value(flag: str, value: Any) -> list[str]:
53
+ """单个 flag 的展开(供参数校验后使用)。"""
54
+ return build_arg_list([[flag, value]])
55
+
56
+
57
+ # 命令核心参数(由 payload / dataset 直接生成),yaml 参数附加时跳过以免重复
58
+ _CORE_FLAGS = {
59
+ "--model", "--tokenizer", "--max-concurrency", "--num-prompts",
60
+ "--random-input-len", "--random-output-len", "--dataset-name",
61
+ "--dataset-path", "--request-rate", "--host", "--port",
62
+ "--base-url", "--endpoint", "--backend", "--sharegpt-output-len",
63
+ "--sharegpt-context-len", "--apply-chat-template",
64
+ }
65
+
66
+
67
+ # ---------------------------------------------------------------------------
68
+ # 框架参数 yaml 的出厂默认内容(仅用于对比:命令只附加“被修改的参数”)
69
+ # 与 benchscope/configs/{framework}-default.yaml 的初始内容保持一致;
70
+ # 用户修改保存后,configs 文件变化,但此处出厂值不变,作为差异基线。
71
+ # ---------------------------------------------------------------------------
72
+ PARAM_YAML_DEFAULTS: dict[str, str] = {
73
+ "vllm": """version: vLLM v0.21.0
74
+ backend: openai-chat
75
+ endpoint: /v1/chat/completions
76
+ trust-remote-code: true
77
+ ignore-eos: true
78
+ burstiness: 1.0
79
+ seed: 0
80
+ num-warmups: 0
81
+ metric-percentiles: "99"
82
+ temperature: 0.0
83
+ top-p: 1.0
84
+ top-k: -1
85
+ min-p: 0.0
86
+ frequency-penalty: 0.0
87
+ presence-penalty: 0.0
88
+ sharegpt-output-len: 128
89
+ max-model-len: 32768
90
+ gpu-memory-utilization: 0.90
91
+ """,
92
+ "sglang": """version: SGLang v0.5.7
93
+ backend: openai
94
+ endpoint: /v1/chat/completions
95
+ trust-remote-code: true
96
+ ignore-eos: true
97
+ burstiness: 1.0
98
+ seed: 1
99
+ num-warmups: 0
100
+ metric-percentiles: "99"
101
+ temperature: 0.0
102
+ top-p: 1.0
103
+ top-k: -1
104
+ min-p: 0.0
105
+ frequency-penalty: 0.0
106
+ presence-penalty: 0.0
107
+ sharegpt-output-len: 128
108
+ max-model-len: 32768
109
+ mem-fraction-static: 0.90
110
+ """,
111
+ }
112
+
113
+
114
+ def _parse_yaml_map(content: str | None) -> dict[str, str]:
115
+ """解析 yaml 文本为 {key: value},跳过注释、空行与 version 行。"""
116
+ out: dict[str, str] = {}
117
+ for ln in (content or "").splitlines():
118
+ s = ln.strip()
119
+ if not s or s.startswith("#") or ":" not in s:
120
+ continue
121
+ k, v = s.split(":", 1)
122
+ k, v = k.strip(), v.strip()
123
+ if not k or k == "version":
124
+ continue
125
+ out[k] = v
126
+ return out
127
+
128
+
129
+ def yaml_params_to_args(content: str | None, defaults_map: dict[str, str] | None = None) -> list[str]:
130
+ """将框架默认参数 yaml 文本(每行 key: value)解析为 --key=value 列表。
131
+ 跳过注释、空行与 version 行(版本仅展示用,不进入命令)。
132
+ 若提供 defaults_map(出厂默认值),只输出“与默认值不同”的参数行——
133
+ 即仅把 Step2 中用户修改过的参数附加到测试命令,未修改的默认参数不进入命令。"""
134
+ args: list[str] = []
135
+ for ln in (content or "").splitlines():
136
+ s = ln.strip()
137
+ if not s or s.startswith("#") or ":" not in s:
138
+ continue
139
+ k, v = s.split(":", 1)
140
+ k, v = k.strip(), v.strip()
141
+ if not k or k == "version":
142
+ continue
143
+ # 差异过滤:与出厂默认一致则跳过(未修改参数不进入命令)
144
+ if defaults_map is not None and defaults_map.get(k) == v:
145
+ continue
146
+ args.append(f"--{k}={v}" if v else f"--{k}")
147
+ return args
148
+
149
+
150
+ def merge_extra_args(payload: dict, extra_args: list | None = None) -> list:
151
+ """合并 payload.extra_args 与 Step2 编辑的 params_yaml[framework] 参数,
152
+ 跳过核心参数与已存在的 flag,避免命令中出现重复参数。"""
153
+ framework = payload.get("framework", "vllm")
154
+ extra = list(extra_args if extra_args is not None else (payload.get("extra_args") or []))
155
+ used = set()
156
+ for item in extra:
157
+ if isinstance(item, str):
158
+ used.add(item.split("=", 1)[0])
159
+ elif isinstance(item, dict):
160
+ used.add(item.get("flag", ""))
161
+ py = (payload.get("params_yaml") or {}).get(framework)
162
+ if py:
163
+ defaults_map = _parse_yaml_map(PARAM_YAML_DEFAULTS.get(framework))
164
+ for a in yaml_params_to_args(py, defaults_map):
165
+ key = a.split("=", 1)[0]
166
+ if key in _CORE_FLAGS or key in used:
167
+ continue
168
+ extra.append(a)
169
+ used.add(key)
170
+ return extra
171
+
172
+
173
+ def normalize_extra_args(extra_args: list | None) -> list[list]:
174
+ """将 extra_args 统一为 [[flag, value]] 形式,供 build_command 追加。
175
+ 兼容两种来源:字符串("--temperature=0.7" / "--flag")与 dict({"flag","value"})。"""
176
+ out: list[list] = []
177
+ for item in extra_args or []:
178
+ if isinstance(item, str):
179
+ s = item.strip()
180
+ if not s:
181
+ continue
182
+ if "=" in s:
183
+ flag, value = s.split("=", 1)
184
+ out.append([flag, value])
185
+ else:
186
+ out.append([s, ""])
187
+ elif isinstance(item, dict):
188
+ flag = (item.get("flag") or "").strip()
189
+ if not flag:
190
+ continue
191
+ out.append([flag, item.get("value", "")])
192
+ return out