Jedi / build.py
podstack's picture
Jedi v1.0
7a74082 verified
Raw History Blame Contribute Delete
3.67 kB
"""Stage 2: turn graded answers into Jedi's verifier dataset.
One example per (task, agent answer): Jedi reads `judge_view(...)` and must reply `accept` (the answer was graded
correct) or `escalate` (graded wrong). Splits are by task, never by answer, so no task leaks across splits:
* test - the in-domain Shaktimaan-routing test tasks (text + code) plus 10% of the new-domain tasks;
* ood - every BIG-Bench Hard task (never trained on: measures generalisation to unseen task families);
* val - 6% of the remaining tasks, used only to calibrate confidence (Platt scaling);
* train - the rest. Wrong answers are the minority, so they are oversampled in train to ~40% of examples.
Extra samples from the borderline pass (gen.py BORDERLINE=1) are used for train only, so held-out splits keep the
same, unselected sampling for every task.
"""
import json, random
from collections import Counter
from datasets import Dataset, DatasetDict, load_dataset
from common import JEDI_SYSTEM, judge_view
random.seed(0)
WRONG_SHARE = 0.40
BASE_SAMPLES = {"glm-5.3-flash": 2, "qwen3.8-27b": 1, "kimi-vl": 1}
def main():
tasks = {t["id"]: t for t in map(json.loads, open("data/tasks.jsonl"))}
answers = [a for a in map(json.loads, open("data/answers.jsonl")) if not a.get("error") and not a.get("skipped")]
shak_test = set(load_dataset("podstack/Shaktimaan-routing", split="test")["id"])
split = {}
for tid, t in tasks.items():
if t["source"] == "bbh":
split[tid] = "ood"
elif tid in shak_test or (t["source"] in ("aqua", "csqa") and random.random() < 0.10):
split[tid] = "test"
else:
split[tid] = "val" if random.random() < 0.06 else "train"
rows = {k: [] for k in ("train", "val", "test", "ood")}
for a in answers:
t = tasks[a["task_id"]]
if split[t["id"]] != "train" and a["sample"] >= BASE_SAMPLES.get(a["agent"], 1):
continue
verdict = "accept" if a["correct"] else "escalate"
view = judge_view(t["prompt"], a["text"], a["agent"], t["kind"], a["finish"])
rows[split[t["id"]]].append(dict(
task_id=t["id"], source=t["source"], kind=t["kind"], agent=a["agent"], sample=a["sample"],
correct=bool(a["correct"]), finish=a["finish"] or "", completion_tokens=a["completion_tokens"],
latency=a["latency"], pred=a["pred"], gold=t["gold"], judge_input=view, verdict=verdict,
prompt=[{"role": "system", "content": JEDI_SYSTEM}, {"role": "user", "content": view}],
completion=[{"role": "assistant", "content": verdict}]))
train = rows["train"]
wrong = [r for r in train if not r["correct"]]
need = int(WRONG_SHARE * (len(train) - len(wrong)) / (1 - WRONG_SHARE)) - len(wrong)
train += random.choices(wrong, k=max(0, need))
random.shuffle(train)
dd = DatasetDict({k: Dataset.from_list(v) for k, v in rows.items()})
dd.save_to_disk("data/jedi_judge")
print(dd)
for k, v in rows.items():
print(f"{k:5s} tasks={len({r['task_id'] for r in v}):5d} answers={len(v):6d} "
f"wrong={sum(not r['correct'] for r in v) / len(v):.1%} "
f"agents={dict(Counter(r['agent'] for r in v))}")
print("solve rate by source x agent (all answers):")
by = Counter((tasks[a["task_id"]]["source"], a["agent"]) for a in answers)
ok = Counter((tasks[a["task_id"]]["source"], a["agent"]) for a in answers if a["correct"])
for src in sorted({s for s, _ in by}):
print(f" {src:10s} " + " ".join(f"{ag}={ok[src, ag] / by[src, ag]:.2f}" for s, ag in sorted(by) if s == src))
if __name__ == "__main__":
main()