Skip to content

Commit b8ac9c1

Browse files
author
Dmytro Parfeniuk
committed
🚧 WIP
1 parent bf5251d commit b8ac9c1

File tree

2 files changed

+89
-10
lines changed

2 files changed

+89
-10
lines changed

src/guidellm/core/report.py

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import time
22
from datetime import datetime
3-
from typing import List, Optional
3+
from pathlib import Path
4+
from typing import List, Literal, Optional, Union, get_args
45

56
from loguru import logger
67
from pydantic import Field
@@ -10,11 +11,14 @@
1011
from rich.table import Table
1112

1213
from guidellm.core.result import TextGenerationBenchmark, TextGenerationBenchmarkReport
13-
from guidellm.core.serializable import Serializable
14+
from guidellm.core.serializable import Serializable, SerializableFileType
1415

1516
__all__ = ["GuidanceReport"]
1617

1718

19+
FlatFileType = Literal["csv"]
20+
21+
1822
def _create_benchmark_report_details(report: TextGenerationBenchmarkReport) -> str:
1923
"""
2024
Create a detailed string representation of a benchmark report.
@@ -319,3 +323,61 @@ def print(
319323
console.print(report_viz)
320324

321325
logger.info("Guidance report printing completed.")
326+
327+
def _get_data(self):
328+
"""
329+
Select the data from the report and return it
330+
in a flat format to be saved to the CSV file.
331+
"""
332+
333+
raise NotImplementedError("Work in progress...")
334+
335+
def save_data(
336+
self,
337+
path: Union[str, Path],
338+
type_: FlatFileType = "csv",
339+
) -> str:
340+
"""
341+
Save the data to a file in CSV format.
342+
343+
:param path: Path to the exact file or the containing directory.
344+
If it is a directory, the file name will be inferred from the class name.
345+
:param type_: Optional type to save ('csv' is only supported).
346+
:return: The path to the saved file.
347+
"""
348+
349+
logger.debug("Saving to file... {} with format: {}", path, type_)
350+
351+
if isinstance(path, str):
352+
path = Path(path)
353+
354+
if path.suffix:
355+
# is a file
356+
ext = path.suffix[1:].lower()
357+
if type_ not in get_args(FlatFileType):
358+
raise ValueError(
359+
f"Unsupported file extension: {type_}. "
360+
f"Expected one of {SerializableFileType} "
361+
f"for {path}"
362+
)
363+
type_ = ext # type: ignore # noqa: PGH003
364+
else:
365+
# is a directory
366+
file_name = f"{self.__class__.__name__.lower()}.{type_}"
367+
path = path / file_name
368+
369+
path.parent.mkdir(parents=True, exist_ok=True)
370+
371+
with path.open("w") as file:
372+
if type_ == "csv":
373+
file.write(self._get_data())
374+
else:
375+
raise ValueError(
376+
f"Unsupported file extension: {type_}"
377+
f"Expected one of {SerializableFileType} "
378+
f"for {path}"
379+
)
380+
381+
logger.info("Successfully saved {} to {}", self.__class__.__name__, path)
382+
383+
return str(path)

src/guidellm/main.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@
132132
),
133133
)
134134
@click.option(
135-
"--output-path",
135+
"--output-report-path",
136136
type=str,
137137
default=None,
138138
help=(
@@ -142,6 +142,16 @@
142142
"printed to the console."
143143
),
144144
)
145+
@click.option(
146+
"--output-data-path",
147+
type=str,
148+
default=None,
149+
help=(
150+
"The output path to save flat data results. "
151+
"Ex: --output-data-path=data.csv"
152+
"The default is None, meaning a file won't be generated."
153+
),
154+
)
145155
@click.option(
146156
"--enable-continuous-refresh",
147157
is_flag=True,
@@ -162,7 +172,8 @@ def generate_benchmark_report_cli(
162172
rate: Optional[float],
163173
max_seconds: Optional[int],
164174
max_requests: Optional[int],
165-
output_path: str,
175+
output_report_path: str,
176+
output_data_path: str,
166177
enable_continuous_refresh: bool,
167178
):
168179
"""
@@ -179,7 +190,8 @@ def generate_benchmark_report_cli(
179190
rate=rate,
180191
max_seconds=max_seconds,
181192
max_requests=max_requests,
182-
output_path=output_path,
193+
output_report_path=output_report_path,
194+
output_data_path=output_data_path,
183195
cont_refresh_table=enable_continuous_refresh,
184196
)
185197

@@ -195,7 +207,8 @@ def generate_benchmark_report(
195207
rate: Optional[float],
196208
max_seconds: Optional[int],
197209
max_requests: Optional[int],
198-
output_path: str,
210+
output_report_path: str,
211+
output_data_path: str,
199212
cont_refresh_table: bool,
200213
) -> GuidanceReport:
201214
"""
@@ -216,6 +229,7 @@ def generate_benchmark_report(
216229
:param max_seconds: Maximum duration for each benchmark run in seconds.
217230
:param max_requests: Maximum number of requests per benchmark run.
218231
:param output_path: Path to save the output report file.
232+
:param output_csv_path: Path to save the flat output data.
219233
:param cont_refresh_table: Continually refresh the table in the CLI
220234
until the user exits.
221235
"""
@@ -224,7 +238,7 @@ def generate_benchmark_report(
224238
)
225239

226240
# Create backend
227-
backend_inst = Backend.create(
241+
backend_inst: Backend = Backend.create(
228242
backend_type=backend,
229243
target=target,
230244
model=model,
@@ -284,11 +298,14 @@ def generate_benchmark_report(
284298
guidance_report = GuidanceReport()
285299
guidance_report.benchmarks.append(report)
286300

287-
if output_path:
288-
guidance_report.save_file(output_path)
301+
if output_report_path:
302+
guidance_report.save_file(output_report_path)
303+
304+
if output_data_path:
305+
guidance_report.save_file(output_report_path)
289306

290307
guidance_report.print(
291-
save_path=output_path if output_path is not None else "stdout",
308+
save_path=output_report_path if output_report_path is not None else "stdout",
292309
continual_refresh=cont_refresh_table,
293310
)
294311

0 commit comments

Comments
 (0)