#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 09_big_suite.py - the large four-domain task set behind `07_domain_eval.py run --suite big --hard-n N` (N tasks per domain, up to the pool size). Public benchmarks, English only, every answer checked by code; the tasks of a smaller N are the FIRST N of a bigger one (nested), so a quick run (--hard-n 60) is a prefix of the full run (--hard-n 300) and the two can be pooled: code HumanEval+ (164) and MBPP sanitized test (257), 2:3 mix; the model writes the function, the unit tests run on it math MATH-500 integer answers of level 2-5 (278) and AIME (90, AI-MO/aimo-validation-aime), 3:1 mix; final line "#### " reason MMLU-Pro (240, 14 subjects round-robin, 10 options) and BIG-Bench Hard (120, 8 tasks), 2:1 mix; final line "Answer: " en RACE-high reading comprehension (120), CoLA grammar acceptability (120, half acceptable), and 120 writing prompts with machine-checked constraints (word counts, paragraphs, bullets, case, keywords, start/end text, quotes, title, commas, P.S.), 1:1:1 mix Needs `pip install datasets` and network access; the model-written code is EXECUTED (see 07). Selftest (same needs): python 09_big_suite.py selftest reference answers pass, garbage fails, every constraint checker passes its own good/bad example python 09_big_suite.py validate runs EVERY reference solution (421 code tasks) and prints the ids to put in BAD_CODE """ import random import re import sys from fractions import Fraction as Fr HOW = "\n\nThink step by step, then give the final answer on the last line as: #### " LETTERS = "ABCDEFGHIJ" BAD_CODE = {"code_he32"} # code task ids whose own reference solution fails its tests (`validate`: HumanEval/32 find_zero is float-sensitive) def mix(pools, pattern): """The pools interleaved by the digits of `pattern` ("00101" = two from pool 0, one from pool 1, ...) until every pool is used up.""" pos, out, i = [0] * len(pools), [], 0 while any(pos[k] < len(pools[k]) for k in range(len(pools))) and i < 10 ** 6: k = int(pattern[i % len(pattern)]) i += 1 if pos[k] < len(pools[k]): out.append(pools[k][pos[k]]) pos[k] += 1 return out def letter(L, k): """check: the last 'Answer: X' of the response is the letter L (X among the first k letters).""" pat = rf"Answer:[\s*(]*([{LETTERS[:k]}])\b" return lambda resp: (re.findall(pat, resp) or [None])[-1] == L def token(target): """check: the last 'Answer: X' of the response has the single word/number X equal to the target (case-insensitive, '(A)' = 'a').""" want = re.sub(r"[^a-z0-9\-]", "", target.casefold()) return lambda resp: bool((got := re.findall(r"Answer:[\s*(\[]*([A-Za-z0-9\-]+)", resp))) and got[-1].casefold() == want # ---------------------------------------------------------------------------------------------------------------------------------- code def pool_code(rnd, run_code, code_of): from datasets import load_dataset he, mb = [], [] for r in load_dataset("evalplus/humanevalplus", split="test"): tests = r["test"] + f"\n\ncheck({r['entry_point']})" he.append((f"code_he{r['task_id'].split('/')[-1]}", "code", "Complete this Python function. Reply with one Python code block containing the whole function (and any imports it needs).\n\n" f"```python\n{r['prompt']}```", (lambda t: lambda resp: run_code(code_of(resp), t, 20))(tests), f"```python\n{r['prompt']}{r['canonical_solution']}\n```")) for r in load_dataset("google-research-datasets/mbpp", "sanitized", split="test"): tests = "\n".join(r["test_imports"]) + "\n" + "\n".join(r["test_list"]) mb.append((f"code_mbpp{r['task_id']}", "code", "Write a Python function for the task below. Reply with one Python code block containing the whole function (and any imports it " f"needs).\n\nTask: {r['prompt']}\n\nYour function must pass these tests (they fix its name and signature):\n" + "\n".join(r["test_list"]), (lambda t: lambda resp: run_code(code_of(resp), t, 20))(tests), f"```python\n{r['code']}\n```")) he, mb = [t for t in he if t[0] not in BAD_CODE], [t for t in mb if t[0] not in BAD_CODE] rnd.shuffle(he) rnd.shuffle(mb) return mix([he, mb], "00111") # 2 HumanEval+ : 3 MBPP per cycle of five # ---------------------------------------------------------------------------------------------------------------------------------- math def pool_math(rnd, num): from datasets import load_dataset ma, ai = [], [] for r in load_dataset("HuggingFaceH4/MATH-500", split="test"): if re.fullmatch(r"-?\d+", str(r["answer"]).strip()) and int(r["level"]) >= 2: ans = Fr(str(r["answer"]).strip()) ma.append((f"math_{r['unique_id'].replace('/', '_').removesuffix('.json')}", "math", r["problem"] + HOW, num(ans), f"#### {ans}")) for r in load_dataset("AI-MO/aimo-validation-aime", split="train"): if re.fullmatch(r"-?\d+", str(r["answer"]).strip()): ans = Fr(str(r["answer"]).strip()) ai.append((f"math_aime{r['id']}", "math", r["problem"] + HOW, num(ans), f"#### {ans}")) rnd.shuffle(ma) rnd.shuffle(ai) return mix([ma, ai], "0001") # 3 MATH-500 : 1 AIME # ---------------------------------------------------------------------------------------------------------------------------------- reasoning BBH = { # task -> the closing instruction that names the answer format "logical_deduction_five_objects": "Answer: