Download harness/scripts/compare_evals.py from agentic-ptb/sol-max-record: direct link, hf CLI and curl.
- Browser
- Download file 6.2 kB
-
https://huggingface.co/agentic-ptb/sol-max-record/resolve/main/harness/scripts/compare_evals.py
- Command line
-
hf download hf://agentic-ptb/sol-max-record/harness/scripts/compare_evals.py
-
curl -L -o compare_evals.py https://huggingface.co/agentic-ptb/sol-max-record/resolve/main/harness/scripts/compare_evals.py
6.2 kB
| #!/usr/bin/env python3 | |
| """Compare two paired v1 eval runs, conservatively counting scheduled episodes.""" | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import math | |
| import tomllib | |
| from collections import Counter | |
| from pathlib import Path | |
| def wilson(successes: int, total: int, z: float = 1.959963984540054) -> list[float] | None: | |
| if total == 0: | |
| return None | |
| p = successes / total | |
| d = 1 + z * z / total | |
| c = (p + z * z / (2 * total)) / d | |
| r = z * math.sqrt(p * (1 - p) / total + z * z / (4 * total * total)) / d | |
| return [max(0.0, c - r), min(1.0, c + r)] | |
| def read_traces(path: Path) -> list[dict]: | |
| path = path / "traces.jsonl" if path.is_dir() else path | |
| by_id: dict[str, dict] = {} | |
| for line in path.read_text().splitlines(): | |
| record = json.loads(line) | |
| for trace in record.get("traces", []): | |
| by_id[trace["id"]] = trace | |
| return list(by_id.values()) | |
| def task_key(trace: dict) -> str: | |
| data = (trace.get("task") or {}).get("data") or {} | |
| return str(data.get("name") or data.get("instance_id") or data.get("idx") or trace["id"]) | |
| def clean(trace: dict) -> bool: | |
| return bool(trace.get("ok") and trace.get("is_completed") and not trace.get("errors")) | |
| def solved(trace: dict) -> bool: | |
| return float(((trace.get("rewards") or {}).get("solved") or {}).get("score", 0)) > 0 | |
| def has_reward(trace: dict) -> bool: | |
| return isinstance((trace.get("rewards") or {}).get("solved"), dict) | |
| def exact_two_sided_sign_p(a_only: int, b_only: int) -> float | None: | |
| """Exact paired sign-test p-value over discordant outcomes. | |
| This is deliberately dependency-free and conditions only on tasks where the | |
| two harnesses/checkpoints disagree. It is diagnostic rather than a reason | |
| to hide either run's conservative Wilson interval. | |
| """ | |
| discordant = a_only + b_only | |
| if discordant == 0: | |
| return None | |
| tail = sum(math.comb(discordant, k) for k in range(min(a_only, b_only) + 1)) | |
| return min(1.0, 2.0 * tail / (2**discordant)) | |
| def expected_episodes(path: Path, observed: int) -> int: | |
| run_dir = path if path.is_dir() else path.parent | |
| config_path = run_dir / "config.toml" | |
| if not config_path.is_file(): | |
| return observed | |
| config = tomllib.loads(config_path.read_text()) | |
| num_tasks = config.get("num_tasks") | |
| num_rollouts = config.get("num_rollouts", 1) | |
| if not isinstance(num_tasks, int) or not isinstance(num_rollouts, int): | |
| return observed | |
| return max(observed, num_tasks * num_rollouts) | |
| def summary(traces: list[dict], path: Path) -> dict: | |
| clean_traces = [trace for trace in traces if clean(trace)] | |
| scored = [trace for trace in traces if has_reward(trace)] | |
| successes = sum(solved(trace) for trace in traces) | |
| calls = [call for trace in traces for call in trace.get("calls", [])] | |
| prompt_tokens = sum(int((call.get("usage") or {}).get("prompt_tokens", 0)) for call in calls) | |
| completion_tokens = sum( | |
| int((call.get("usage") or {}).get("completion_tokens", 0)) for call in calls | |
| ) | |
| categories = Counter( | |
| str(((trace.get("task") or {}).get("data") or {}).get("category") or "unknown") | |
| for trace in traces | |
| if solved(trace) | |
| ) | |
| scheduled = expected_episodes(path, len(traces)) | |
| return { | |
| "scheduled_episodes": scheduled, | |
| "observed_trace_episodes": len(traces), | |
| "missing_trace_episodes": scheduled - len(traces), | |
| "clean_completed": len(clean_traces), | |
| "reward_bearing": len(scored), | |
| "errored_or_unscored": scheduled - len(scored), | |
| "successes": successes, | |
| "score_scheduled": successes / scheduled if scheduled else None, | |
| "ci95_wilson_scheduled": wilson(successes, scheduled), | |
| "diagnostic_score_reward_bearing": successes / len(scored) if scored else None, | |
| "diagnostic_ci95_reward_bearing": wilson(successes, len(scored)), | |
| "stop_conditions": dict(Counter(trace.get("stop_condition", "unknown") for trace in traces)), | |
| "model_calls": len(calls), | |
| "prompt_tokens": prompt_tokens, | |
| "completion_tokens": completion_tokens, | |
| "success_categories": dict(sorted(categories.items())), | |
| } | |
| def main() -> None: | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("a", type=Path) | |
| parser.add_argument("b", type=Path) | |
| parser.add_argument("--label-a", default="a") | |
| parser.add_argument("--label-b", default="b") | |
| args = parser.parse_args() | |
| a_traces = read_traces(args.a) | |
| b_traces = read_traces(args.b) | |
| a = {task_key(trace): trace for trace in a_traces} | |
| b = {task_key(trace): trace for trace in b_traces} | |
| common = sorted(a.keys() & b.keys()) | |
| paired = Counter() | |
| for key in common: | |
| sa, sb = solved(a[key]), solved(b[key]) | |
| paired[ | |
| "both" if sa and sb else "a_only" if sa else "b_only" if sb else "neither" | |
| ] += 1 | |
| paired_delta = ( | |
| (paired["b_only"] - paired["a_only"]) / len(common) if common else None | |
| ) | |
| print( | |
| json.dumps( | |
| { | |
| args.label_a: summary(a_traces, args.a), | |
| args.label_b: summary(b_traces, args.b), | |
| "paired": { | |
| "common_scheduled_tasks": len(common), | |
| "both_solve": paired["both"], | |
| f"{args.label_a}_only": paired["a_only"], | |
| f"{args.label_b}_only": paired["b_only"], | |
| "neither": paired["neither"], | |
| f"score_delta_{args.label_b}_minus_{args.label_a}": paired_delta, | |
| "discordant_tasks": paired["a_only"] + paired["b_only"], | |
| "exact_two_sided_sign_test_p": exact_two_sided_sign_p( | |
| paired["a_only"], paired["b_only"] | |
| ), | |
| f"missing_{args.label_a}": len(b.keys() - a.keys()), | |
| f"missing_{args.label_b}": len(a.keys() - b.keys()), | |
| "both_clean_completed": sum(clean(a[key]) and clean(b[key]) for key in common), | |
| }, | |
| }, | |
| indent=2, | |
| ) | |
| ) | |
| if __name__ == "__main__": | |
| main() | |