| |
|
|
| """ |
| GAIA Benchmark Runner — CLI |
| Usage: |
| python run_benchmark.py --level 1 --split validation --max 20 |
| python run_benchmark.py --level all --split validation --max 0 # run all |
| """ |
|
|
| from agent import gaia_benchmark_iter |
| import argparse, os, json, re, string, warnings |
| import numpy as np |
|
|
|
|
| |
|
|
| def normalize_number_str(number_str: str) -> float: |
| for char in ["$", "%", ","]: |
| number_str = number_str.replace(char, "") |
| try: |
| return float(number_str) |
| except ValueError: |
| return float("inf") |
|
|
|
|
| def split_string(s: str, char_list: list[str] = [",", ";"]) -> list[str]: |
| pattern = f"[{''.join(re.escape(c) for c in char_list)}]" |
| return [x.strip() for x in re.split(pattern, s)] |
|
|
|
|
| def normalize_str(input_str: str, remove_articles: bool = True) -> str: |
| input_str = str(input_str).strip() |
| if remove_articles: |
| input_str = re.sub(r"\b(a|an|the)\b", "", input_str, flags=re.IGNORECASE) |
| return " ".join(input_str.lower().translate(str.maketrans("", "", string.punctuation)).split()) |
|
|
|
|
| def question_scorer(model_answer: str, ground_truth: str) -> bool: |
| def is_float(s): |
| try: |
| float(s) |
| return True |
| except ValueError: |
| return False |
|
|
| if is_float(ground_truth): |
| try: |
| return abs(normalize_number_str(model_answer) - float(ground_truth)) <= 1e-6 |
| except Exception: |
| return False |
|
|
| if any(c in ground_truth for c in [",", ";"]): |
| gt_parts = split_string(ground_truth) |
| ma_parts = split_string(model_answer) |
| if len(gt_parts) != len(ma_parts): |
| return False |
| return all( |
| question_scorer(ma.strip(), gt.strip()) |
| for ma, gt in zip(ma_parts, gt_parts) |
| ) |
|
|
| return normalize_str(model_answer) == normalize_str(ground_truth) |
|
|
|
|
| def main(): |
| parser = argparse.ArgumentParser() |
| parser.add_argument("--level", default="1", choices=["1", "2", "3", "all"]) |
| parser.add_argument("--split", default="validation", choices=["validation", "test"]) |
| parser.add_argument("--max", type=int, default=20) |
| args = parser.parse_args() |
|
|
| hf_token = os.environ.get("HF_TOKEN", "") |
| if not hf_token: |
| print("ERROR: HF_TOKEN not set. export HF_TOKEN=hf_...") |
| return |
|
|
| serper = os.environ.get("SERPER_API_KEY") or os.environ.get("SERPER_API", "") |
| if not serper: |
| print("⚠ WARNING: SERPER_API not set — search_tool will fail. Set it first:") |
| print(" export SERPER_API=your_key") |
| print(" Continuing anyway...\n") |
|
|
| level_filter = "All" if args.level == "all" else f"Level {args.level}" |
| print( |
| f"\nStarting GAIA benchmark | Level: {level_filter} | Split: {args.split} | Max: {args.max or 'all'}\n" |
| ) |
|
|
| results = [] |
| for log_text, payload in gaia_benchmark_iter( |
| level_filter, args.split, args.max, hf_token |
| ): |
| last_line = log_text.strip().split("\n")[-1] |
| print(last_line) |
| if isinstance(payload, list): |
| results = payload |
|
|
| if not results: |
| print("No results — check errors above.") |
| return |
|
|
| |
| sub_file = f"gaia_submission_{args.split}.jsonl" |
| with open(sub_file, "w", encoding="utf-8") as f: |
| for r in results: |
| f.write( |
| json.dumps( |
| { |
| "task_id": r["task_id"], |
| "model_answer": r["model_answer"], |
| "reasoning_trace": r["reasoning_trace"], |
| }, |
| ensure_ascii=False, |
| ) |
| + "\n" |
| ) |
|
|
| |
| eval_file = None |
| if args.split == "validation": |
| correct, total = 0, 0 |
| eval_file = f"gaia_eval_{args.split}.jsonl" |
| with open(eval_file, "w", encoding="utf-8") as f: |
| for r in results: |
| gt = r.get("ground_truth", "") |
| is_correct = question_scorer(r["model_answer"], gt) if gt else None |
| if is_correct is not None: |
| total += 1 |
| correct += is_correct |
| f.write( |
| json.dumps( |
| { |
| "task_id": r["task_id"], |
| "level": r["level"], |
| "question": r["question"][:120], |
| "model_answer": r["model_answer"], |
| "ground_truth": gt, |
| "correct": is_correct, |
| }, |
| ensure_ascii=False, |
| ) |
| + "\n" |
| ) |
|
|
| score = correct / total * 100 if total else 0 |
| print(f"\n{'─' * 50}") |
| print(f"Score: {correct}/{total} ({score:.1f}%)") |
| print(f"{'─' * 50}") |
|
|
| print(f"\nSubmission → {sub_file}") |
| if eval_file: |
| print(f"Eval+GT → {eval_file}") |
|
|
|
|
| if __name__ == "__main__": |
| main() |