Spaces:
Paused
Paused
Download training/eval_before_after.py from laterabhi/SQL-Query-Env: direct link, hf CLI and curl.
- Browser
- Download file 4.73 kB
-
https://huggingface.co/spaces/laterabhi/SQL-Query-Env/resolve/main/training/eval_before_after.py
- Command line
-
hf download hf://spaces/laterabhi/SQL-Query-Env/training/eval_before_after.py
-
curl -L -o eval_before_after.py https://huggingface.co/spaces/laterabhi/SQL-Query-Env/resolve/main/training/eval_before_after.py
4.73 kB
| """ | |
| Before / after evaluation for README and judges. | |
| "Before" = same structured suggestions as the fallback policy but an empty | |
| optimized_query (no DuckDB comparison — analysis-only). | |
| "After" = full deterministic fallback with real optimized SQL. | |
| No API keys required. | |
| Usage: | |
| python training/eval_before_after.py --save-dir results | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import os | |
| import sys | |
| ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| sys.path.insert(0, ROOT) | |
| from baseline_runner import FALLBACK_SOLUTIONS, TASK_IDS # noqa: E402 | |
| from graders import grade # noqa: E402 | |
| from models import Action # noqa: E402 | |
| from tasks import TASKS # noqa: E402 | |
| def _before_action(task_id: str) -> Action: | |
| sol = FALLBACK_SOLUTIONS[task_id] | |
| return Action( | |
| suggestions=sol["suggestions"], | |
| optimized_query="", | |
| summary=sol["summary"], | |
| estimated_improvement=sol["estimated_improvement"], | |
| approved=sol["approved"], | |
| ) | |
| def _after_action(task_id: str) -> Action: | |
| sol = FALLBACK_SOLUTIONS[task_id] | |
| return Action( | |
| suggestions=sol["suggestions"], | |
| optimized_query=sol["optimized_query"], | |
| summary=sol["summary"], | |
| estimated_improvement=sol["estimated_improvement"], | |
| approved=sol["approved"], | |
| ) | |
| def run_eval() -> dict: | |
| rows = [] | |
| for task_id in TASK_IDS: | |
| td = TASKS[task_id] | |
| b = grade(td, _before_action(task_id)) | |
| a = grade(td, _after_action(task_id)) | |
| rows.append( | |
| { | |
| "task_id": task_id, | |
| "task_name": td["task_name"], | |
| "difficulty": td["difficulty"], | |
| "before_score": b.score, | |
| "after_score": a.score, | |
| "delta": round(a.score - b.score, 4), | |
| } | |
| ) | |
| return {"rows": rows} | |
| def write_table(path: str, data: dict) -> None: | |
| lines = [ | |
| "# Before / after — execution-grounded reward", | |
| "", | |
| "| Task | Difficulty | Before (no SQL) | After (fallback) | Δ |", | |
| "|------|------------|-----------------|------------------|---|", | |
| ] | |
| for r in data["rows"]: | |
| lines.append( | |
| f"| {r['task_name'][:40]} | {r['difficulty']} | " | |
| f"{r['before_score']:.4f} | {r['after_score']:.4f} | {r['delta']:+.4f} |" | |
| ) | |
| b_avg = sum(r["before_score"] for r in data["rows"]) / len(data["rows"]) | |
| a_avg = sum(r["after_score"] for r in data["rows"]) / len(data["rows"]) | |
| lines += [ | |
| "", | |
| f"**Mean before:** {b_avg:.4f} ", | |
| f"**Mean after:** {a_avg:.4f} ", | |
| f"**Mean Δ:** {a_avg - b_avg:+.4f}", | |
| "", | |
| "_Before = non-empty suggestions but `optimized_query` empty — no speedup/correctness signal._", | |
| ] | |
| with open(path, "w", encoding="utf-8") as f: | |
| f.write("\n".join(lines)) | |
| def write_chart(path: str, data: dict) -> None: | |
| try: | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt | |
| except ImportError: | |
| print("[WARN] matplotlib not installed — skipping chart", flush=True) | |
| return | |
| labels = [r["task_id"].replace("task_", "") for r in data["rows"]] | |
| before = [r["before_score"] for r in data["rows"]] | |
| after = [r["after_score"] for r in data["rows"]] | |
| x = range(len(labels)) | |
| w = 0.35 | |
| fig, ax = plt.subplots(figsize=(10, 5)) | |
| ax.bar([i - w / 2 for i in x], before, width=w, label="Before (no optimized SQL)") | |
| ax.bar([i + w / 2 for i in x], after, width=w, label="After (fallback + DuckDB)") | |
| ax.set_xticks(list(x)) | |
| ax.set_xticklabels(labels, rotation=25, ha="right") | |
| ax.set_ylim(0, 1.0) | |
| ax.set_ylabel("Reward") | |
| ax.legend() | |
| ax.set_title("Reward spread: analysis-only vs execution-grounded") | |
| fig.tight_layout() | |
| fig.savefig(path, dpi=150) | |
| plt.close(fig) | |
| print(f"[OK] Chart → {path}", flush=True) | |
| def main() -> None: | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument( | |
| "--save-dir", | |
| default="results", | |
| help="Directory for before_after_table.md and JSON", | |
| ) | |
| args = ap.parse_args() | |
| save_dir = args.save_dir | |
| os.makedirs(save_dir, exist_ok=True) | |
| data = run_eval() | |
| json_path = os.path.join(save_dir, "before_after_eval.json") | |
| with open(json_path, "w", encoding="utf-8") as f: | |
| json.dump(data, f, indent=2) | |
| md_path = os.path.join(save_dir, "before_after_table.md") | |
| write_table(md_path, data) | |
| png_path = os.path.join(save_dir, "before_after_chart.png") | |
| write_chart(png_path, data) | |
| print(f"[OK] {json_path}", flush=True) | |
| print(f"[OK] {md_path}", flush=True) | |
| if __name__ == "__main__": | |
| main() | |