11import os
22import json
33import random
4+ import math
45from typing import Any , Dict , List
56from guidellm .core .distribution import Distribution
67from guidellm .core import TextGenerationBenchmarkReport , TextGenerationBenchmark
@@ -74,16 +75,72 @@ def generate_run_info(report: TextGenerationBenchmarkReport) -> Dict[str, Any]:
7475 "timestamp" : timestamp
7576 }
7677
78+ def linearly_interpolate_value (target_input , lower_input , lower_output , upperInput , upper_output ):
79+ fraction = (target_input - lower_input ) / (upperInput - lower_input )
80+ return lower_output + fraction * (upper_output - lower_output )
81+
7782def generate_request_over_time_data (benchmarks : List [TextGenerationBenchmark ]) -> List [Dict [str , Any ]]:
83+
7884 request_over_time_results = []
7985 for benchmark in benchmarks :
8086 # compare benchmark start time to text generation result end time
8187 all_result_end_times = [result .end_time for result in benchmark .results if result .end_time is not None ]
8288 request_over_time_values = list (map (lambda time : time - benchmark .start_time , all_result_end_times ))
8389 request_distribution = Distribution (data = request_over_time_values )
8490 result = generate_metric_report (request_distribution , "requestsOverTime" )
85- request_over_time_results .append (result ["requestsOverTime" ])
86- return request_over_time_results
91+ result ["requestsPerSecond" ] = benchmark .completed_request_rate
92+ request_over_time_results .append (result )
93+
94+ if len (benchmarks ) == 1 :
95+ return request_over_time_results
96+
97+ request_over_time_raw = []
98+ sorted_bm = sorted (benchmarks , key = lambda bm : bm .completed_request_rate )
99+ for benchmark in sorted_bm :
100+ # compare benchmark start time to text generation result end time
101+ all_result_end_times = [result .end_time for result in benchmark .results if result .end_time is not None ]
102+ request_over_time_values = list (map (lambda time : time - benchmark .start_time , all_result_end_times ))
103+ request_at_rps = { "rps" : benchmark .completed_request_rate , "requests_over_time" : request_over_time_values }
104+ request_over_time_raw .append (request_at_rps )
105+
106+ rps_values = [request_obj ["rps" ] for request_obj in request_over_time_raw ]
107+ rps_range = list (range (math .ceil (min (rps_values )), math .ceil (max (rps_values ))))
108+ interpolated_request_values = []
109+ lower_rps_index = 0
110+ for rps in rps_range :
111+ if rps > rps_values [lower_rps_index + 1 ]: lower_rps_index += 1
112+ if rps == rps_values [lower_rps_index ]:
113+ interpolated_request_values .append ({
114+ "requests_per_second" : rps ,
115+ "requests_over_time" : request_over_time_raw [lower_rps_index ]["requests_over_time" ][:]
116+ })
117+ lower_rps_index += 1
118+ elif rps < rps_values [lower_rps_index + 1 ]:
119+ interpolated_requests_at_new_rps = []
120+ for i in range (len (request_over_time_raw [lower_rps_index ]["requests_over_time" ])):
121+ lower_request = request_over_time_raw [lower_rps_index ]["requests_over_time" ][i ]
122+ upper_request = request_over_time_raw [lower_rps_index + 1 ]["requests_over_time" ][i ]
123+ new_value = linearly_interpolate_value (rps , rps_values [lower_rps_index ], lower_request , rps_values [lower_rps_index + 1 ], upper_request )
124+ interpolated_requests_at_new_rps .append (new_value )
125+ interpolated_request_values .append ({ "requests_per_second" : rps , "requests_over_time" : interpolated_requests_at_new_rps })
126+ elif rps > rps_values [lower_rps_index + 1 ]:
127+ while rps > rps_values [lower_rps_index + 1 ]:
128+ lower_rps_index += 1
129+ interpolated_requests_at_new_rps = []
130+ for i in range (len (request_over_time_raw [lower_rps_index ]["requests_over_time" ])):
131+ lower_request = request_over_time_raw [lower_rps_index ]["requests_over_time" ][i ]
132+ upper_request = request_over_time_raw [lower_rps_index + 1 ]["requests_over_time" ][i ]
133+ new_value = linearly_interpolate_value (rps , rps_values [lower_rps_index ], lower_request , rps_values [lower_rps_index + 1 ], upper_request )
134+ interpolated_requests_at_new_rps .append (new_value )
135+ interpolated_request_values .append ({ "requests_per_second" : rps , "requests_over_time" : interpolated_requests_at_new_rps })
136+ interpolated_request_over_time_results = []
137+ for request_value in interpolated_request_values :
138+ request_distribution = Distribution (data = request_value ["requests_over_time" ])
139+ result = generate_metric_report (request_distribution , "requestsOverTime" )
140+ result ["requestsPerSecond" ] = request_value ["requests_per_second" ]
141+ interpolated_request_over_time_results .append (result )
142+
143+ return interpolated_request_over_time_results
87144
88145
89146def generate_workload_details (report : TextGenerationBenchmarkReport ) -> Dict [str , Any ]:
@@ -93,13 +150,18 @@ def generate_workload_details(report: TextGenerationBenchmarkReport) -> Dict[str
93150 all_output_token_distribution = Distribution (data = all_output_token_data )
94151
95152 prompt_token_data = generate_metric_report (all_prompt_token_distribution , "tokenDistributions" )
96- prompt_token_samples = [result .prompt for benchmark in report .benchmarks for result in benchmark .results ]
97- sample_prompts = random .sample (prompt_token_samples , min (5 , len (prompt_token_samples )))
98- sample_prompts = list (map (lambda prompt : prompt .replace ("\n " , " " ).replace ("\" " , "'" ), sample_prompts ))
99153 output_token_data = generate_metric_report (all_output_token_distribution , "tokenDistributions" )
154+
155+ prompt_token_samples = [result .prompt for benchmark in report .benchmarks for result in benchmark .results ]
100156 output_token_samples = [result .output for benchmark in report .benchmarks for result in benchmark .results ]
101- sample_outputs = random .sample (output_token_samples , min (5 , len (output_token_samples )))
102157
158+ num_samples = min (5 , len (prompt_token_samples ), len (output_token_samples ))
159+ sample_indices = random .sample (range (len (prompt_token_samples )), num_samples )
160+
161+ sample_prompts = [prompt_token_samples [i ] for i in sample_indices ]
162+ sample_prompts = list (map (lambda prompt : prompt .replace ("\n " , " " ).replace ("\" " , "'" ), sample_prompts ))
163+
164+ sample_outputs = [output_token_samples [i ] for i in sample_indices ]
103165 sample_outputs = list (map (lambda output : output .replace ("\n " , " " ).replace ("\" " , "'" ), sample_outputs ))
104166
105167 request_over_time_results = generate_request_over_time_data (report .benchmarks )
0 commit comments