scrubdata / eval /run_finetuned.py
OpenAI Codex
deploy: add sponsor:openai tag (Best Use of Codex) + Codex-hardened build
16dc556
Raw
History Blame Contribute Delete
3.33 kB
"""Evaluate the fine-tuned model (local Ollama GGUF) on BOTH layers vs the goalposts.
ollama pull hf.co/ricalanis/scrubdata-qwen3-4b-gguf
uv run eval/run_finetuned.py --model hf.co/ricalanis/scrubdata-qwen3-4b-gguf --n 40
Prints the synthetic matrix (vs heuristic + oracle) and the real-data row, then checks
each goalpost (eval/README.md): recovery≥0.95, canon_f1≥0.85, op_f1≥0.95, json_valid≥0.99
(synthetic) and recovery≥0.985, repair_recall≥0.30, broken≤50 (real).
"""
from __future__ import annotations
import argparse
from scrubdata.executor import apply_plan
from scrubdata.model_planner import make_batched_planner, make_local_ollama_planner
from scrubdata.planner import mock_plan
from .gold import load_gold
from .run_eval import evaluate
from .run_real import _ensure_data, _load, _score
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("--model", required=True, help="local ollama model id (the FT GGUF)")
ap.add_argument("--n", type=int, default=40)
ap.add_argument("--seed", type=int, default=4242)
args = ap.parse_args()
ft = make_local_ollama_planner(args.model)
# ---- Layer 1: synthetic held-out matrix (frozen gold) ----
gold = load_gold()[:args.n]
systems = {
"ORACLE (gold)": lambda df, gp: gp,
"HEURISTIC": lambda df, gp: mock_plan(df),
f"FT {args.model.split('/')[-1]}": ft,
}
rows = {name: evaluate(fn, gold) for name, fn in systems.items()}
cols = ["json_valid", "op_f1", "canon_f1", "canon_r", "recovery"]
print(f"\n=== Layer 1: synthetic ({args.n} held-out, seed {args.seed}) ===")
print(f"{'system':<26}" + "".join(f"{c:>11}" for c in cols))
print("-" * (26 + 11 * len(cols)))
for name, m in rows.items():
print(f"{name:<26}" + "".join(f"{m[c]:>11.3f}" for c in cols))
ftm = rows[f"FT {args.model.split('/')[-1]}"]
gp1 = {"recovery": 0.95, "canon_f1": 0.85, "op_f1": 0.95, "json_valid": 0.99}
print("\nGoalpost check (synthetic):")
for k, t in gp1.items():
ok = "✅" if ftm[k] >= t else "❌"
print(f" {ok} {k}: {ftm[k]:.3f} (target ≥{t})")
# ---- Layer 2: real OOD (Raha hospital, 20 cols → batched planner) ----
_ensure_data()
dirty, clean = _load()
ft_plan = make_batched_planner(ft, batch_size=6)(dirty)
cleaned, _ = apply_plan(dirty, ft_plan)
noop = _score(dirty, clean, dirty)
ftr = _score(dirty, clean, cleaned)
print(f"\n=== Layer 2: real OOD (Raha hospital, {noop['_errors']} errors) ===")
rcols = ["recovery", "repair_recall", "repair_prec", "broken"]
print(f"{'system':<26}" + "".join(f"{c:>14}" for c in rcols))
print("-" * (26 + 14 * len(rcols)))
for name, m in [("NO-OP", noop), (f"FT {args.model.split('/')[-1]}", ftr)]:
print(f"{name:<26}" + "".join(
f"{m[c]:>14.3f}" if isinstance(m[c], float) else f"{m[c]:>14}" for c in rcols))
print("\nGoalpost check (real — repair_recall is the real test; recovery is "
"convention-sensitive, report-only):")
for k, t in [("repair_recall", 0.30), ("repair_prec", 0.70)]:
ok = "✅" if ftr[k] >= t else "❌"
print(f" {ok} {k}: {ftr[k]:.3f} (target ≥{t})")
print(f" (report-only) recovery: {ftr['recovery']:.3f}")
if __name__ == "__main__":
main()