-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate_scores.py
More file actions
115 lines (92 loc) · 3.34 KB
/
Copy pathgenerate_scores.py
File metadata and controls
115 lines (92 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env python3
import argparse
import json
from pathlib import Path
def discover_evaluation_files(repo_root: Path) -> list[Path]:
experiment_files = sorted(repo_root.glob("experiments/*/evaluation_stats.json"))
if experiment_files:
return experiment_files
# Backward compatibility for legacy root-level experiment folders.
return sorted(repo_root.glob("*/evaluation_stats.json"))
def format_mean(value: object) -> str:
if isinstance(value, (int, float)):
return f"{value:.4f}"
return "-"
def build_markdown_table(rows: list[dict], metric_names: list[str]) -> str:
headers = ["experiment", *metric_names]
divider = ["---"] * len(headers)
lines = [
"| " + " | ".join(headers) + " |",
"| " + " | ".join(divider) + " |",
]
for row in rows:
line = [row["experiment"]]
for metric in metric_names:
line.append(format_mean(row["means"].get(metric)))
lines.append("| " + " | ".join(line) + " |")
return "\n".join(lines)
def main() -> None:
parser = argparse.ArgumentParser(
description=(
"Collect metrics_summary mean values from all evaluation_stats.json "
"files and export a markdown table."
)
)
parser.add_argument(
"--repo-root",
default=".",
help="Repository root to scan (default: current directory).",
)
parser.add_argument(
"--output",
default="Scores.MD",
help="Path to output markdown file (default: Scores.MD).",
)
args = parser.parse_args()
repo_root = Path(args.repo_root).resolve()
output_path = Path(args.output)
if not output_path.is_absolute():
output_path = repo_root / output_path
rows: list[dict] = []
metric_names: set[str] = set()
skipped: list[str] = []
for stats_path in discover_evaluation_files(repo_root):
experiment = stats_path.parent.name
try:
with stats_path.open("r", encoding="utf-8") as f:
payload = json.load(f)
except (json.JSONDecodeError, OSError):
skipped.append(experiment)
continue
metrics_summary = payload.get("metrics_summary")
if not isinstance(metrics_summary, dict):
skipped.append(experiment)
continue
means = {}
for metric_name, summary in metrics_summary.items():
if isinstance(summary, dict):
means[metric_name] = summary.get("mean")
else:
means[metric_name] = None
metric_names.update(means.keys())
rows.append({"experiment": experiment, "means": means})
ordered_metrics = sorted(metric_names)
rows.sort(key=lambda row: row["experiment"])
lines = ["# Scores", "", "## metrics_summary (mean)", ""]
lines.append(build_markdown_table(rows, ordered_metrics))
if skipped:
lines.extend(
[
"",
"## Skipped",
"",
"These experiments were skipped because `metrics_summary` is missing or invalid:",
"",
]
)
for experiment in sorted(skipped):
lines.append(f"- {experiment}")
output_path.write_text("\n".join(lines).rstrip() + "\n", encoding="utf-8")
print(f"Wrote {output_path}")
if __name__ == "__main__":
main()