Skip to content

Commit 5af9bfc

Browse files
committed
Initial state for new progress output
1 parent 69b0e66 commit 5af9bfc

File tree

5 files changed

+90
-6
lines changed

5 files changed

+90
-6
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ dependencies = [
6969
"pyyaml>=6.0.0",
7070
"rich",
7171
"sanic",
72+
"tabulate",
7273
"transformers",
7374
"uvloop>=0.18",
7475
"torch",

src/guidellm/benchmark/output.py

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
import json
55
import math
66
from abc import ABC, abstractmethod
7-
from collections import OrderedDict
7+
from collections import OrderedDict, defaultdict
88
from copy import deepcopy
99
from datetime import datetime
1010
from pathlib import Path
1111
from typing import Any, ClassVar
1212

1313
from pydantic import BaseModel, ConfigDict, Field
14-
from rich.console import Console
1514
from rich.padding import Padding
1615
from rich.text import Text
16+
from tabulate import tabulate
1717

1818
from guidellm.benchmark.profile import (
1919
AsyncProfile,
@@ -31,11 +31,13 @@
3131
from guidellm.settings import settings
3232
from guidellm.utils import (
3333
Colors,
34+
Console,
3435
DistributionSummary,
3536
RegistryMixin,
3637
StatusDistributionSummary,
3738
camelize_str,
3839
recursive_key_update,
40+
safe_format_number,
3941
safe_format_timestamp,
4042
split_text_list_by_length,
4143
)
@@ -175,12 +177,62 @@ async def finalize(self, report: GenerativeBenchmarksReport) -> str:
175177
:param report: The completed benchmark report.
176178
:return:
177179
"""
178-
self._print_benchmarks_metadata(report.benchmarks)
179-
self._print_benchmarks_info(report.benchmarks)
180-
self._print_benchmarks_stats(report.benchmarks)
180+
self.console.print("\n\n")
181+
self._print_report_benchmarks_info(report)
181182

182183
return "printed to console"
183184

185+
def _print_report_benchmarks_info(self, report: GenerativeBenchmarksReport):
186+
benchmark_key = "\nBenchmark"
187+
start_key = "\nStart"
188+
end_key = "\nEnd"
189+
timings_key = "Duration, Warmup, Cooldown\nsec, sec, sec"
190+
requests_key = "Requests\nCompl, Incomp, Err"
191+
input_tokens_key = "Input Tokens\nCompl, Incomp, Err"
192+
output_tokens_key = "Output Tokens\nCompl, Incomp, Err"
193+
194+
columns = defaultdict(list)
195+
196+
for benchmark in report.benchmarks:
197+
columns[benchmark_key].append(str(benchmark.scheduler.strategy))
198+
columns[start_key].append(safe_format_timestamp(benchmark.start_time))
199+
columns[end_key].append(safe_format_timestamp(benchmark.end_time))
200+
columns[timings_key].append(
201+
f"{safe_format_number(benchmark.duration)}, "
202+
f"{safe_format_number(report.args.warmup)}, "
203+
f"{safe_format_number(report.args.cooldown)}"
204+
)
205+
columns[requests_key].append(
206+
f"{safe_format_number(benchmark.request_totals.successful)}, "
207+
f"{safe_format_number(benchmark.request_totals.incomplete)}, "
208+
f"{safe_format_number(benchmark.request_totals.errored)}"
209+
)
210+
columns[input_tokens_key].append(
211+
f"{safe_format_number(benchmark.metrics.prompt_token_count.successful.total_sum)}, "
212+
f"{safe_format_number(benchmark.metrics.prompt_token_count.incomplete.total_sum)}, "
213+
f"{safe_format_number(benchmark.metrics.prompt_token_count.errored.total_sum)}"
214+
)
215+
columns[output_tokens_key].append(
216+
f"{safe_format_number(benchmark.metrics.output_token_count.successful.total_sum)}, "
217+
f"{safe_format_number(benchmark.metrics.output_token_count.incomplete.total_sum)}, "
218+
f"{safe_format_number(benchmark.metrics.output_token_count.errored.total_sum)}"
219+
)
220+
221+
self.console.print_update("Benchmarks Info", None, "info")
222+
self.console.print(
223+
Padding(
224+
tabulate(
225+
columns,
226+
headers="keys",
227+
tablefmt="pipe",
228+
numalign="center",
229+
stralign="center",
230+
rowalign="center",
231+
),
232+
(0, 0, 0, 2),
233+
)
234+
)
235+
184236
def _print_benchmarks_metadata(self, benchmarks: list[GenerativeBenchmark]):
185237
start_time = benchmarks[0].run_stats.start_time
186238
end_time = benchmarks[-1].run_stats.end_time

src/guidellm/benchmark/schemas.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1373,7 +1373,7 @@ def compile(
13731373
# General token stats
13741374
prompt_token_count=StatusDistributionSummary.from_values(
13751375
value_types=request_types,
1376-
values=[float(req.prompt_tokens or 0) for req in requests],
1376+
values=[float(req.input_tokens or 0) for req in requests],
13771377
),
13781378
output_token_count=StatusDistributionSummary.from_values(
13791379
value_types=request_types,
@@ -1390,10 +1390,14 @@ def compile(
13901390
time_per_output_token_ms=StatusDistributionSummary.from_values(
13911391
value_types=request_types,
13921392
values=[req.time_per_output_token_ms or 0.0 for req in requests],
1393+
weights=[req.output_tokens or 0.0 for req in requests],
13931394
),
13941395
inter_token_latency_ms=StatusDistributionSummary.from_values(
13951396
value_types=request_types,
13961397
values=[req.inter_token_latency_ms or 0.0 for req in requests],
1398+
weights=[
1399+
max(0.0, (req.output_tokens or 1.0) - 1.0) for req in requests
1400+
],
13971401
),
13981402
output_tokens_wo_first_per_iteration=StatusDistributionSummary.from_values(
13991403
value_types=request_types,

src/guidellm/utils/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
all_defined,
1414
safe_add,
1515
safe_divide,
16+
safe_format_number,
1617
safe_format_timestamp,
1718
safe_getattr,
1819
safe_multiply,
@@ -114,6 +115,7 @@
114115
"recursive_key_update",
115116
"safe_add",
116117
"safe_divide",
118+
"safe_format_number",
117119
"safe_format_timestamp",
118120
"safe_getattr",
119121
"safe_multiply",

src/guidellm/utils/functions.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"all_defined",
1616
"safe_add",
1717
"safe_divide",
18+
"safe_format_number",
1819
"safe_format_timestamp",
1920
"safe_getattr",
2021
"safe_multiply",
@@ -132,3 +133,27 @@ def safe_format_timestamp(
132133
return datetime.fromtimestamp(timestamp).strftime(format_)
133134
except (ValueError, OverflowError, OSError):
134135
return default
136+
137+
138+
def safe_format_number(
139+
number: int | float | None, default: str = "--", precision: int = 1
140+
) -> str:
141+
"""
142+
Safely format a number with specified precision and default handling.
143+
144+
:param number: Number to format, or None
145+
:param default: Value to return if number is None
146+
:param precision: Number of decimal places for formatting floats
147+
:return: Formatted number string or default value
148+
"""
149+
if number is None:
150+
return default
151+
152+
if isinstance(number, int):
153+
return str(number)
154+
155+
try:
156+
format_str = f"{{:.{precision}f}}"
157+
return format_str.format(number)
158+
except (ValueError, TypeError):
159+
return default

0 commit comments

Comments
 (0)