Spaces:
Sleeping
Sleeping
| """ | |
| benchmarks/base.py | |
| βββββββββββββββββββ | |
| Abstract base class every benchmark extends. | |
| """ | |
| from __future__ import annotations | |
| import time | |
| from abc import ABC, abstractmethod | |
| from typing import Any | |
| class BaseBenchmark(ABC): | |
| """ | |
| Subclass this for each benchmark. | |
| Concrete subclasses must implement: | |
| load_dataset() β list of sample dicts | |
| evaluate_sample(sample, prediction) β dict with keys: | |
| passed (bool), score (float 0-1), note (str) | |
| build_prompt(sample) β str | |
| """ | |
| name: str = "base" | |
| def __init__( | |
| self, | |
| model_bundle: dict[str, Any], | |
| max_samples: int | None = None, | |
| max_new_tokens: int = 512, | |
| temperature: float = 0.0, | |
| benchmark_cfg: dict | None = None, | |
| ): | |
| self.model_bundle = model_bundle | |
| self.generate = model_bundle["generate_fn"] | |
| self.max_samples = max_samples | |
| self.max_new_tokens = max_new_tokens | |
| self.temperature = temperature | |
| self.cfg = benchmark_cfg or {} | |
| # ββ Must implement ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def load_dataset(self) -> list[dict]: | |
| """Return a list of sample dicts.""" | |
| def build_prompt(self, sample: dict) -> str: | |
| """Convert a sample dict into the prompt string sent to the model.""" | |
| def evaluate_sample(self, sample: dict, prediction: str) -> dict: | |
| """ | |
| Score one prediction. | |
| Returns dict: | |
| passed (bool) | |
| score (float, 0β1) | |
| note (str, optional explanation) | |
| """ | |
| # ββ Orchestration β override if needed βββββββββββββββββββββββββββββββββββ | |
| def run(self) -> dict[str, Any]: | |
| """Run all samples and aggregate results.""" | |
| dataset = self.load_dataset() | |
| if self.max_samples: | |
| dataset = dataset[: self.max_samples] | |
| samples_out = [] | |
| total_latency = 0.0 | |
| errors = 0 | |
| for sample in dataset: | |
| prompt = self.build_prompt(sample) | |
| t0 = time.perf_counter() | |
| try: | |
| prediction = self.generate( | |
| prompt, | |
| max_new_tokens=self.max_new_tokens, | |
| temperature=self.temperature, | |
| ) | |
| latency = time.perf_counter() - t0 | |
| eval_result = self.evaluate_sample(sample, prediction) | |
| except Exception as exc: | |
| latency = time.perf_counter() - t0 | |
| errors += 1 | |
| eval_result = { | |
| "passed": False, | |
| "score": 0.0, | |
| "note": f"ERROR: {exc}", | |
| } | |
| prediction = "" | |
| samples_out.append( | |
| { | |
| "id": sample.get("id", ""), | |
| "prediction": prediction, | |
| "latency_s": round(latency, 3), | |
| **eval_result, | |
| } | |
| ) | |
| total_latency += latency | |
| passed = sum(1 for s in samples_out if s["passed"]) | |
| total = len(samples_out) | |
| score = (passed / total) if total else 0.0 | |
| avg_lat = round(total_latency / total, 3) if total else 0.0 | |
| return { | |
| "benchmark": self.name, | |
| "passed": passed, | |
| "total": total, | |
| "score": score, | |
| "error_count": errors, | |
| "avg_latency_s": avg_lat, | |
| "samples": samples_out, | |
| } | |