feat: add summary generation and visualization for model evaluation results
Browse filesIntroduced new functions in plot_results.py to generate a summary of evaluation results, including average rewards and success rates, and output them to CSV and Markdown formats. Enhanced plotting functions to visualize model performance across tasks with improved styling and labeling. Added new images for reward curves and success rates, facilitating better analysis of model behavior in CORP-ENV scenarios.
- notebook466c72b6cd.ipynb +0 -0
- plot_results.py +177 -16
- results/model_compare/comparison_summary.csv +10 -0
- results/model_compare/comparison_summary.md +15 -0
- results/model_compare/invalid_action_rate.png +3 -0
- results/model_compare/model_comparison.png +3 -0
- results/model_compare/reward_curve.png +3 -0
- results/model_compare/success_by_task.png +3 -0
notebook466c72b6cd.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
plot_results.py
CHANGED
|
@@ -3,12 +3,28 @@
|
|
| 3 |
from __future__ import annotations
|
| 4 |
|
| 5 |
import argparse
|
|
|
|
| 6 |
import json
|
| 7 |
from collections import defaultdict
|
| 8 |
from pathlib import Path
|
| 9 |
from typing import Any, Dict, Iterable, List
|
| 10 |
|
| 11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
def expand_inputs(inputs: Iterable[str]) -> List[Path]:
|
| 13 |
paths: List[Path] = []
|
| 14 |
for raw in inputs:
|
|
@@ -48,6 +64,31 @@ def read_rows(paths: Iterable[str]) -> List[Dict[str, Any]]:
|
|
| 48 |
return rows
|
| 49 |
|
| 50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
def grouped_mean(rows: List[Dict[str, Any]], metric: str) -> Dict[str, Dict[str, float]]:
|
| 52 |
grouped: Dict[str, Dict[str, List[float]]] = defaultdict(lambda: defaultdict(list))
|
| 53 |
for row in rows:
|
|
@@ -60,6 +101,83 @@ def grouped_mean(rows: List[Dict[str, Any]], metric: str) -> Dict[str, Dict[str,
|
|
| 60 |
}
|
| 61 |
|
| 62 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
def plot_grouped_bars(
|
| 64 |
data: Dict[str, Dict[str, float]],
|
| 65 |
title: str,
|
|
@@ -70,24 +188,46 @@ def plot_grouped_bars(
|
|
| 70 |
) -> None:
|
| 71 |
import matplotlib.pyplot as plt
|
| 72 |
|
| 73 |
-
|
|
|
|
| 74 |
tasks = sorted({task for by_task in data.values() for task in by_task})
|
| 75 |
x = list(range(len(tasks)))
|
| 76 |
width = 0.8 / max(len(stages), 1)
|
| 77 |
|
| 78 |
-
fig, ax = plt.subplots(figsize=(10, 5))
|
| 79 |
for idx, stage in enumerate(stages):
|
| 80 |
vals = [data[stage].get(task, 0.0) for task in tasks]
|
| 81 |
offsets = [pos - 0.4 + width / 2 + idx * width for pos in x]
|
| 82 |
-
|
| 83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
ax.set_xlabel("Task")
|
| 85 |
ax.set_ylabel(ylabel)
|
| 86 |
ax.set_xticks(x)
|
| 87 |
-
ax.set_xticklabels(tasks, rotation=
|
| 88 |
if clamp_unit:
|
| 89 |
ax.set_ylim(0, 1.05)
|
| 90 |
-
ax.
|
|
|
|
| 91 |
fig.tight_layout()
|
| 92 |
fig.savefig(output, dpi=160)
|
| 93 |
plt.close(fig)
|
|
@@ -96,22 +236,41 @@ def plot_grouped_bars(
|
|
| 96 |
def plot_reward_curve(rows: List[Dict[str, Any]], output: Path) -> None:
|
| 97 |
import matplotlib.pyplot as plt
|
| 98 |
|
| 99 |
-
|
| 100 |
-
|
| 101 |
for row in rows:
|
| 102 |
-
trace = row.get("reward_trace") or []
|
| 103 |
-
if
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
if not plotted:
|
| 109 |
ax.text(0.5, 0.5, "No reward traces found", ha="center", va="center")
|
| 110 |
-
ax.
|
|
|
|
| 111 |
ax.set_xlabel("Environment step")
|
| 112 |
ax.set_ylabel("Step reward")
|
|
|
|
| 113 |
if plotted:
|
| 114 |
-
ax.legend(fontsize=
|
| 115 |
fig.tight_layout()
|
| 116 |
fig.savefig(output, dpi=160)
|
| 117 |
plt.close(fig)
|
|
@@ -151,7 +310,9 @@ def main() -> None:
|
|
| 151 |
clamp_unit=True,
|
| 152 |
)
|
| 153 |
plot_reward_curve(rows, out / "reward_curve.png")
|
|
|
|
| 154 |
print(f"Wrote plots to {out}")
|
|
|
|
| 155 |
|
| 156 |
|
| 157 |
if __name__ == "__main__":
|
|
|
|
| 3 |
from __future__ import annotations
|
| 4 |
|
| 5 |
import argparse
|
| 6 |
+
import csv
|
| 7 |
import json
|
| 8 |
from collections import defaultdict
|
| 9 |
from pathlib import Path
|
| 10 |
from typing import Any, Dict, Iterable, List
|
| 11 |
|
| 12 |
|
| 13 |
+
STAGE_ORDER = ("baseline", "base", "sft", "grpo", "oracle")
|
| 14 |
+
TASK_LABELS = {
|
| 15 |
+
"e1_launch_readiness": "E1 Launch",
|
| 16 |
+
"m1_budget_reallocation": "M1 Budget",
|
| 17 |
+
"h1_acquisition_defence": "H1 Acquisition",
|
| 18 |
+
}
|
| 19 |
+
COLORS = {
|
| 20 |
+
"baseline": "#8c8c8c",
|
| 21 |
+
"base": "#4C78A8",
|
| 22 |
+
"sft": "#54A24B",
|
| 23 |
+
"grpo": "#F58518",
|
| 24 |
+
"oracle": "#B279A2",
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
|
| 28 |
def expand_inputs(inputs: Iterable[str]) -> List[Path]:
|
| 29 |
paths: List[Path] = []
|
| 30 |
for raw in inputs:
|
|
|
|
| 64 |
return rows
|
| 65 |
|
| 66 |
|
| 67 |
+
def stage_family(stage: str) -> str:
|
| 68 |
+
low = stage.lower()
|
| 69 |
+
for family in STAGE_ORDER:
|
| 70 |
+
if family in low:
|
| 71 |
+
return family
|
| 72 |
+
return low
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def stage_sort_key(stage: str) -> tuple:
|
| 76 |
+
family = stage_family(stage)
|
| 77 |
+
try:
|
| 78 |
+
family_idx = STAGE_ORDER.index(family)
|
| 79 |
+
except ValueError:
|
| 80 |
+
family_idx = len(STAGE_ORDER)
|
| 81 |
+
return (family_idx, stage)
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def task_label(task_id: str) -> str:
|
| 85 |
+
return TASK_LABELS.get(task_id, task_id.replace("_", " "))
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def stage_label(stage: str) -> str:
|
| 89 |
+
return stage.replace("_", " ").replace("-", " ")
|
| 90 |
+
|
| 91 |
+
|
| 92 |
def grouped_mean(rows: List[Dict[str, Any]], metric: str) -> Dict[str, Dict[str, float]]:
|
| 93 |
grouped: Dict[str, Dict[str, List[float]]] = defaultdict(lambda: defaultdict(list))
|
| 94 |
for row in rows:
|
|
|
|
| 101 |
}
|
| 102 |
|
| 103 |
|
| 104 |
+
def summary_rows(rows: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
| 105 |
+
grouped: Dict[tuple, List[Dict[str, Any]]] = defaultdict(list)
|
| 106 |
+
for row in rows:
|
| 107 |
+
grouped[(str(row.get("model_stage", "unknown")), str(row.get("task_id", "unknown")))].append(row)
|
| 108 |
+
|
| 109 |
+
out: List[Dict[str, Any]] = []
|
| 110 |
+
for (stage, task), vals in sorted(grouped.items(), key=lambda x: (stage_sort_key(x[0][0]), x[0][1])):
|
| 111 |
+
steps = [float(v.get("steps", 0) or 0) for v in vals]
|
| 112 |
+
invalid_rates = [
|
| 113 |
+
float(v.get("invalid_action_count", 0) or 0) / max(float(v.get("steps", 0) or 0), 1.0)
|
| 114 |
+
for v in vals
|
| 115 |
+
]
|
| 116 |
+
out.append(
|
| 117 |
+
{
|
| 118 |
+
"model_stage": stage,
|
| 119 |
+
"task_id": task,
|
| 120 |
+
"episodes": len(vals),
|
| 121 |
+
"avg_terminal_reward": round(sum(float(v.get("terminal_reward", 0.0)) for v in vals) / len(vals), 6),
|
| 122 |
+
"avg_total_reward": round(sum(float(v.get("total_reward", 0.0)) for v in vals) / len(vals), 6),
|
| 123 |
+
"avg_verifier_pass_rate": round(sum(float(v.get("verifier_pass_rate", 0.0)) for v in vals) / len(vals), 6),
|
| 124 |
+
"success_rate": round(sum(1 for v in vals if v.get("success")) / len(vals), 6),
|
| 125 |
+
"avg_invalid_action_rate": round(sum(invalid_rates) / len(invalid_rates), 6),
|
| 126 |
+
"avg_steps": round(sum(steps) / len(steps), 3),
|
| 127 |
+
}
|
| 128 |
+
)
|
| 129 |
+
return out
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
def write_summary(rows: List[Dict[str, Any]], output_dir: Path) -> None:
|
| 133 |
+
summary = summary_rows(rows)
|
| 134 |
+
csv_path = output_dir / "comparison_summary.csv"
|
| 135 |
+
md_path = output_dir / "comparison_summary.md"
|
| 136 |
+
if not summary:
|
| 137 |
+
return
|
| 138 |
+
with csv_path.open("w", newline="", encoding="utf-8") as f:
|
| 139 |
+
writer = csv.DictWriter(f, fieldnames=list(summary[0].keys()))
|
| 140 |
+
writer.writeheader()
|
| 141 |
+
writer.writerows(summary)
|
| 142 |
+
|
| 143 |
+
headers = [
|
| 144 |
+
"Model Stage",
|
| 145 |
+
"Task",
|
| 146 |
+
"Episodes",
|
| 147 |
+
"Terminal Reward",
|
| 148 |
+
"Verifier Pass",
|
| 149 |
+
"Success",
|
| 150 |
+
"Invalid Rate",
|
| 151 |
+
"Avg Steps",
|
| 152 |
+
]
|
| 153 |
+
lines = [
|
| 154 |
+
"# CORP-ENV Result Comparison",
|
| 155 |
+
"",
|
| 156 |
+
"| " + " | ".join(headers) + " |",
|
| 157 |
+
"| " + " | ".join(["---"] * len(headers)) + " |",
|
| 158 |
+
]
|
| 159 |
+
for row in summary:
|
| 160 |
+
lines.append(
|
| 161 |
+
"| "
|
| 162 |
+
+ " | ".join(
|
| 163 |
+
[
|
| 164 |
+
str(row["model_stage"]),
|
| 165 |
+
task_label(str(row["task_id"])),
|
| 166 |
+
str(row["episodes"]),
|
| 167 |
+
f"{row['avg_terminal_reward']:.3f}",
|
| 168 |
+
f"{row['avg_verifier_pass_rate']:.3f}",
|
| 169 |
+
f"{row['success_rate']:.3f}",
|
| 170 |
+
f"{row['avg_invalid_action_rate']:.3f}",
|
| 171 |
+
f"{row['avg_steps']:.1f}",
|
| 172 |
+
]
|
| 173 |
+
)
|
| 174 |
+
+ " |"
|
| 175 |
+
)
|
| 176 |
+
lines.append("")
|
| 177 |
+
lines.append("Generated by `plot_results.py` from eval JSONL files.")
|
| 178 |
+
md_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
| 179 |
+
|
| 180 |
+
|
| 181 |
def plot_grouped_bars(
|
| 182 |
data: Dict[str, Dict[str, float]],
|
| 183 |
title: str,
|
|
|
|
| 188 |
) -> None:
|
| 189 |
import matplotlib.pyplot as plt
|
| 190 |
|
| 191 |
+
plt.style.use("seaborn-v0_8-whitegrid")
|
| 192 |
+
stages = sorted(data.keys(), key=stage_sort_key)
|
| 193 |
tasks = sorted({task for by_task in data.values() for task in by_task})
|
| 194 |
x = list(range(len(tasks)))
|
| 195 |
width = 0.8 / max(len(stages), 1)
|
| 196 |
|
| 197 |
+
fig, ax = plt.subplots(figsize=(max(10, len(tasks) * 2.2), 5.8))
|
| 198 |
for idx, stage in enumerate(stages):
|
| 199 |
vals = [data[stage].get(task, 0.0) for task in tasks]
|
| 200 |
offsets = [pos - 0.4 + width / 2 + idx * width for pos in x]
|
| 201 |
+
family = stage_family(stage)
|
| 202 |
+
bars = ax.bar(
|
| 203 |
+
offsets,
|
| 204 |
+
vals,
|
| 205 |
+
width,
|
| 206 |
+
label=stage_label(stage),
|
| 207 |
+
color=COLORS.get(family),
|
| 208 |
+
edgecolor="white",
|
| 209 |
+
linewidth=0.8,
|
| 210 |
+
)
|
| 211 |
+
for bar, val in zip(bars, vals):
|
| 212 |
+
if val > 0:
|
| 213 |
+
ax.text(
|
| 214 |
+
bar.get_x() + bar.get_width() / 2,
|
| 215 |
+
bar.get_height() + (0.015 if clamp_unit else 0.02),
|
| 216 |
+
f"{val:.2f}",
|
| 217 |
+
ha="center",
|
| 218 |
+
va="bottom",
|
| 219 |
+
fontsize=8,
|
| 220 |
+
rotation=0,
|
| 221 |
+
)
|
| 222 |
+
ax.set_title(title, fontsize=15, weight="bold", pad=14)
|
| 223 |
ax.set_xlabel("Task")
|
| 224 |
ax.set_ylabel(ylabel)
|
| 225 |
ax.set_xticks(x)
|
| 226 |
+
ax.set_xticklabels([task_label(t) for t in tasks], rotation=0, ha="center")
|
| 227 |
if clamp_unit:
|
| 228 |
ax.set_ylim(0, 1.05)
|
| 229 |
+
ax.spines[["top", "right"]].set_visible(False)
|
| 230 |
+
ax.legend(loc="upper center", bbox_to_anchor=(0.5, -0.12), ncol=max(1, min(len(stages), 4)), frameon=False)
|
| 231 |
fig.tight_layout()
|
| 232 |
fig.savefig(output, dpi=160)
|
| 233 |
plt.close(fig)
|
|
|
|
| 236 |
def plot_reward_curve(rows: List[Dict[str, Any]], output: Path) -> None:
|
| 237 |
import matplotlib.pyplot as plt
|
| 238 |
|
| 239 |
+
plt.style.use("seaborn-v0_8-whitegrid")
|
| 240 |
+
grouped: Dict[tuple, List[List[float]]] = defaultdict(list)
|
| 241 |
for row in rows:
|
| 242 |
+
trace = [float(x) for x in (row.get("reward_trace") or [])]
|
| 243 |
+
if trace:
|
| 244 |
+
grouped[(str(row.get("model_stage", "model")), str(row.get("task_id", "task")))].append(trace)
|
| 245 |
+
|
| 246 |
+
fig, ax = plt.subplots(figsize=(12, 6.5))
|
| 247 |
+
plotted = bool(grouped)
|
| 248 |
+
for (stage, task), traces in sorted(grouped.items(), key=lambda x: (stage_sort_key(x[0][0]), x[0][1])):
|
| 249 |
+
max_len = max(len(t) for t in traces)
|
| 250 |
+
means: List[float] = []
|
| 251 |
+
mins: List[float] = []
|
| 252 |
+
maxs: List[float] = []
|
| 253 |
+
for idx in range(max_len):
|
| 254 |
+
vals = [trace[idx] for trace in traces if idx < len(trace)]
|
| 255 |
+
means.append(sum(vals) / len(vals))
|
| 256 |
+
mins.append(min(vals))
|
| 257 |
+
maxs.append(max(vals))
|
| 258 |
+
xs = list(range(1, max_len + 1))
|
| 259 |
+
family = stage_family(stage)
|
| 260 |
+
label = f"{stage_label(stage)} · {task_label(task)}"
|
| 261 |
+
color = COLORS.get(family)
|
| 262 |
+
ax.plot(xs, means, marker="o", linewidth=2.2, markersize=4, label=label, color=color)
|
| 263 |
+
if len(traces) > 1:
|
| 264 |
+
ax.fill_between(xs, mins, maxs, alpha=0.12, color=color)
|
| 265 |
if not plotted:
|
| 266 |
ax.text(0.5, 0.5, "No reward traces found", ha="center", va="center")
|
| 267 |
+
ax.axhline(0, color="#666666", linewidth=0.9, alpha=0.5)
|
| 268 |
+
ax.set_title("Episode Reward Curve By Model Stage", fontsize=15, weight="bold", pad=14)
|
| 269 |
ax.set_xlabel("Environment step")
|
| 270 |
ax.set_ylabel("Step reward")
|
| 271 |
+
ax.spines[["top", "right"]].set_visible(False)
|
| 272 |
if plotted:
|
| 273 |
+
ax.legend(fontsize=8, ncol=2, frameon=False, loc="upper center", bbox_to_anchor=(0.5, -0.12))
|
| 274 |
fig.tight_layout()
|
| 275 |
fig.savefig(output, dpi=160)
|
| 276 |
plt.close(fig)
|
|
|
|
| 310 |
clamp_unit=True,
|
| 311 |
)
|
| 312 |
plot_reward_curve(rows, out / "reward_curve.png")
|
| 313 |
+
write_summary(rows, out)
|
| 314 |
print(f"Wrote plots to {out}")
|
| 315 |
+
print(f"Wrote summaries to {out / 'comparison_summary.md'} and {out / 'comparison_summary.csv'}")
|
| 316 |
|
| 317 |
|
| 318 |
if __name__ == "__main__":
|
results/model_compare/comparison_summary.csv
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
model_stage,task_id,episodes,avg_terminal_reward,avg_total_reward,avg_verifier_pass_rate,success_rate,avg_invalid_action_rate,avg_steps
|
| 2 |
+
base-qwen2.5-7b,e1_launch_readiness,1,0.91,1.39,1.0,1.0,0.0,3.0
|
| 3 |
+
base-qwen2.5-7b,h1_acquisition_defence,1,0.753333,2.283333,0.666667,0.0,0.0,8.0
|
| 4 |
+
base-qwen2.5-7b,m1_budget_reallocation,1,0.806667,2.056667,0.666667,0.0,0.0,6.0
|
| 5 |
+
sft-qwen2.5-7b,e1_launch_readiness,1,0.91,1.58,1.0,1.0,0.0,4.0
|
| 6 |
+
sft-qwen2.5-7b,h1_acquisition_defence,1,0.515,2.915,0.5,0.0,0.0,15.0
|
| 7 |
+
sft-qwen2.5-7b,m1_budget_reallocation,1,0.943333,2.093333,1.0,1.0,0.0,6.0
|
| 8 |
+
grpo-qwen2.5-7b,e1_launch_readiness,1,0.91,1.58,1.0,1.0,0.0,4.0
|
| 9 |
+
grpo-qwen2.5-7b,h1_acquisition_defence,1,-0.01,1.54,0.416667,0.0,0.783333,60.0
|
| 10 |
+
grpo-qwen2.5-7b,m1_budget_reallocation,1,0.548333,1.508333,0.5,0.0,0.0,5.0
|
results/model_compare/comparison_summary.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# CORP-ENV Result Comparison
|
| 2 |
+
|
| 3 |
+
| Model Stage | Task | Episodes | Terminal Reward | Verifier Pass | Success | Invalid Rate | Avg Steps |
|
| 4 |
+
| --- | --- | --- | --- | --- | --- | --- | --- |
|
| 5 |
+
| base-qwen2.5-7b | E1 Launch | 1 | 0.910 | 1.000 | 1.000 | 0.000 | 3.0 |
|
| 6 |
+
| base-qwen2.5-7b | H1 Acquisition | 1 | 0.753 | 0.667 | 0.000 | 0.000 | 8.0 |
|
| 7 |
+
| base-qwen2.5-7b | M1 Budget | 1 | 0.807 | 0.667 | 0.000 | 0.000 | 6.0 |
|
| 8 |
+
| sft-qwen2.5-7b | E1 Launch | 1 | 0.910 | 1.000 | 1.000 | 0.000 | 4.0 |
|
| 9 |
+
| sft-qwen2.5-7b | H1 Acquisition | 1 | 0.515 | 0.500 | 0.000 | 0.000 | 15.0 |
|
| 10 |
+
| sft-qwen2.5-7b | M1 Budget | 1 | 0.943 | 1.000 | 1.000 | 0.000 | 6.0 |
|
| 11 |
+
| grpo-qwen2.5-7b | E1 Launch | 1 | 0.910 | 1.000 | 1.000 | 0.000 | 4.0 |
|
| 12 |
+
| grpo-qwen2.5-7b | H1 Acquisition | 1 | -0.010 | 0.417 | 0.000 | 0.783 | 60.0 |
|
| 13 |
+
| grpo-qwen2.5-7b | M1 Budget | 1 | 0.548 | 0.500 | 0.000 | 0.000 | 5.0 |
|
| 14 |
+
|
| 15 |
+
Generated by `plot_results.py` from eval JSONL files.
|
results/model_compare/invalid_action_rate.png
ADDED
|
Git LFS Details
|
results/model_compare/model_comparison.png
ADDED
|
Git LFS Details
|
results/model_compare/reward_curve.png
ADDED
|
Git LFS Details
|
results/model_compare/success_by_task.png
ADDED
|
Git LFS Details
|