Spaces:
Running
Running
| from __future__ import annotations | |
| import math | |
| import random | |
| from .models import Request, SimulationConfig | |
| def _sample_lognormal(mean: float, cv: float, rng: random.Random, minimum: int = 1) -> int: | |
| if cv <= 1e-9: | |
| return max(minimum, int(round(mean))) | |
| variance_ratio = cv * cv | |
| sigma2 = math.log(1.0 + variance_ratio) | |
| sigma = math.sqrt(sigma2) | |
| mu = math.log(max(mean, 1e-6)) - sigma2 / 2.0 | |
| return max(minimum, int(round(rng.lognormvariate(mu, sigma)))) | |
| def _arrival_times(cfg: SimulationConfig, rng: random.Random) -> list[float]: | |
| rate = max(cfg.request_rate_rps, 1e-9) | |
| arrivals: list[float] = [] | |
| t = 0.0 | |
| if cfg.arrival_process == "constant": | |
| step = 1.0 / rate | |
| while t < cfg.duration_s: | |
| arrivals.append(t) | |
| t += step | |
| return arrivals | |
| if cfg.arrival_process == "bursty": | |
| while t < cfg.duration_s: | |
| phase = int(t // max(cfg.burst_period_s, 0.1)) % 2 | |
| local_rate = rate * (cfg.burst_multiplier if phase else 0.55) | |
| t += rng.expovariate(max(local_rate, 1e-9)) | |
| if t < cfg.duration_s: | |
| arrivals.append(t) | |
| return arrivals | |
| if cfg.arrival_process != "poisson": | |
| raise ValueError(f"Unknown arrival process: {cfg.arrival_process}") | |
| while t < cfg.duration_s: | |
| t += rng.expovariate(rate) | |
| if t < cfg.duration_s: | |
| arrivals.append(t) | |
| return arrivals | |
| def generate_workload(cfg: SimulationConfig) -> list[Request]: | |
| rng = random.Random(cfg.seed) | |
| cache_rng = random.Random(cfg.seed ^ 0x5A17CACE) | |
| requests: list[Request] = [] | |
| for idx, arrival in enumerate(_arrival_times(cfg, rng)): | |
| prompt = _sample_lognormal(cfg.prompt_tokens_mean, cfg.prompt_tokens_cv, rng) | |
| output = _sample_lognormal(cfg.output_tokens_mean, cfg.output_tokens_cv, rng) | |
| cached = 0 | |
| if cfg.prefix_cache_enabled and cfg.shared_prefix_tokens > 0 and cfg.prefix_reuse_fraction > 0: | |
| if cache_rng.random() < min(max(cfg.prefix_reuse_fraction, 0.0), 1.0): | |
| cached = min(cfg.shared_prefix_tokens, max(prompt - 1, 0)) | |
| requests.append( | |
| Request( | |
| request_id=idx, | |
| arrival_time=arrival, | |
| prompt_tokens=prompt, | |
| output_tokens=output, | |
| deadline_time=arrival + cfg.slo_e2e_ms / 1000.0, | |
| remaining_prefill=max(0, prompt - cached), | |
| cached_prefix_tokens=cached, | |
| ) | |
| ) | |
| return requests | |