V6.5-7ds cleanup: remove legacy scripts/parse_v6_log.py
Browse files- scripts/parse_v6_log.py +0 -263
scripts/parse_v6_log.py
DELETED
|
@@ -1,263 +0,0 @@
|
|
| 1 |
-
"""parse_v6_log.py — Parse v6_progressive.log and extract evolution data.
|
| 2 |
-
|
| 3 |
-
Extracts stage results from the log file since training was killed before
|
| 4 |
-
writing the final report.
|
| 5 |
-
"""
|
| 6 |
-
import json
|
| 7 |
-
import re
|
| 8 |
-
from pathlib import Path
|
| 9 |
-
from datetime import datetime
|
| 10 |
-
|
| 11 |
-
LOG_PATH = Path("/home/z/my-project/logs/v6_progressive.log")
|
| 12 |
-
REPORT_PATH = Path("/home/z/my-project/BiGRU_T_version/v6_progressive_report.json")
|
| 13 |
-
|
| 14 |
-
# Regex patterns
|
| 15 |
-
STAGE_RE = re.compile(r"STAGE: (\w+) \(n=(\d+), epoch=(\d+)\)")
|
| 16 |
-
STAGE_END_RE = re.compile(
|
| 17 |
-
r"STAGE END \| val_loss=([\d.]+) \| train_avg=([\d.]+) \| ppl=([\d.]+) "
|
| 18 |
-
r"\| gap=([+-]?[\d.]+) \| eval_acc=([\d.]+)% \| elapsed=([\d.]+)s \| n_steps=(\d+)"
|
| 19 |
-
)
|
| 20 |
-
SOM_RE = re.compile(r"SOM: σ=([\d.]+), α=([\d.]+), step=(\d+)")
|
| 21 |
-
STEP_RE = re.compile(
|
| 22 |
-
r"step\s+(\d+)\s+\|\s+loss=([\d.]+)\s+\|\s+tps=(\d+)\s+\|\s+tflops=([\d.]+)\s+\|\s+\|\|g\|\|=([\d.]+)\s+\|\s+cpu=(\d+)%\s+\|\s+rss=(\d+)MB"
|
| 23 |
-
)
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
def parse_log():
|
| 27 |
-
"""Parse the log file and return evolution data."""
|
| 28 |
-
if not LOG_PATH.exists():
|
| 29 |
-
print(f"[ERROR] Log file not found: {LOG_PATH}")
|
| 30 |
-
return None
|
| 31 |
-
|
| 32 |
-
with open(LOG_PATH) as f:
|
| 33 |
-
lines = f.readlines()
|
| 34 |
-
|
| 35 |
-
print(f"[INFO] Parsing {len(lines)} log lines from {LOG_PATH}")
|
| 36 |
-
|
| 37 |
-
evolution = []
|
| 38 |
-
current_stage = None
|
| 39 |
-
current_n = None
|
| 40 |
-
current_epoch = None
|
| 41 |
-
current_steps = []
|
| 42 |
-
som_data = {}
|
| 43 |
-
|
| 44 |
-
for line in lines:
|
| 45 |
-
# STAGE start
|
| 46 |
-
m = STAGE_RE.search(line)
|
| 47 |
-
if m:
|
| 48 |
-
# Save previous stage if any
|
| 49 |
-
if current_stage is not None:
|
| 50 |
-
# Compute summary
|
| 51 |
-
if current_steps:
|
| 52 |
-
losses = [s["loss"] for s in current_steps]
|
| 53 |
-
tps_arr = [s["tps"] for s in current_steps]
|
| 54 |
-
tflops_arr = [s["tflops"] for s in current_steps]
|
| 55 |
-
rss_arr = [s["rss_mb"] for s in current_steps]
|
| 56 |
-
avg_tflops = sum(tflops_arr) / len(tflops_arr)
|
| 57 |
-
avg_tps = sum(tps_arr) / len(tps_arr)
|
| 58 |
-
final_rss = rss_arr[-1]
|
| 59 |
-
max_rss = max(rss_arr)
|
| 60 |
-
else:
|
| 61 |
-
avg_tflops = 0
|
| 62 |
-
avg_tps = 0
|
| 63 |
-
final_rss = 0
|
| 64 |
-
max_rss = 0
|
| 65 |
-
# Look for STAGE END
|
| 66 |
-
evolution.append({
|
| 67 |
-
"stage": current_stage,
|
| 68 |
-
"n_samples": current_n,
|
| 69 |
-
"epoch": current_epoch,
|
| 70 |
-
"n_steps": len(current_steps),
|
| 71 |
-
"avg_tflops": avg_tflops,
|
| 72 |
-
"avg_tokens_per_sec": avg_tps,
|
| 73 |
-
"final_rss_mb": final_rss,
|
| 74 |
-
"max_rss_mb": max_rss,
|
| 75 |
-
"train_loss_mean": sum(losses) / len(losses) if current_steps else 0,
|
| 76 |
-
"val_loss": None, # filled below
|
| 77 |
-
"perplexity": None,
|
| 78 |
-
"overfitting_gap": None,
|
| 79 |
-
"eval_acc": None,
|
| 80 |
-
"elapsed_s": None,
|
| 81 |
-
"som": dict(som_data),
|
| 82 |
-
})
|
| 83 |
-
som_data = {}
|
| 84 |
-
current_stage = m.group(1)
|
| 85 |
-
current_n = int(m.group(2))
|
| 86 |
-
current_epoch = int(m.group(3))
|
| 87 |
-
current_steps = []
|
| 88 |
-
continue
|
| 89 |
-
|
| 90 |
-
# STAGE END
|
| 91 |
-
m = STAGE_END_RE.search(line)
|
| 92 |
-
if m and current_stage is not None:
|
| 93 |
-
val_loss = float(m.group(1))
|
| 94 |
-
train_avg = float(m.group(2))
|
| 95 |
-
ppl = float(m.group(3))
|
| 96 |
-
gap = float(m.group(4))
|
| 97 |
-
eval_acc = float(m.group(5)) / 100.0
|
| 98 |
-
elapsed = float(m.group(6))
|
| 99 |
-
n_steps_end = int(m.group(7))
|
| 100 |
-
# Update last entry's stage-end info
|
| 101 |
-
# Actually, save as a new "complete" entry
|
| 102 |
-
# If evolution has an entry for this stage without val_loss, update it
|
| 103 |
-
if evolution and evolution[-1]["stage"] == current_stage and evolution[-1]["n_samples"] == current_n and evolution[-1]["epoch"] == current_epoch:
|
| 104 |
-
evolution[-1].update({
|
| 105 |
-
"val_loss": val_loss,
|
| 106 |
-
"train_loss_mean": train_avg,
|
| 107 |
-
"perplexity": ppl,
|
| 108 |
-
"overfitting_gap": gap,
|
| 109 |
-
"eval_acc": eval_acc,
|
| 110 |
-
"elapsed_s": elapsed,
|
| 111 |
-
"n_steps": n_steps_end,
|
| 112 |
-
})
|
| 113 |
-
else:
|
| 114 |
-
evolution.append({
|
| 115 |
-
"stage": current_stage,
|
| 116 |
-
"n_samples": current_n,
|
| 117 |
-
"epoch": current_epoch,
|
| 118 |
-
"n_steps": n_steps_end,
|
| 119 |
-
"avg_tflops": 0,
|
| 120 |
-
"avg_tokens_per_sec": 0,
|
| 121 |
-
"final_rss_mb": 0,
|
| 122 |
-
"max_rss_mb": 0,
|
| 123 |
-
"train_loss_mean": train_avg,
|
| 124 |
-
"val_loss": val_loss,
|
| 125 |
-
"perplexity": ppl,
|
| 126 |
-
"overfitting_gap": gap,
|
| 127 |
-
"eval_acc": eval_acc,
|
| 128 |
-
"elapsed_s": elapsed,
|
| 129 |
-
"som": dict(som_data),
|
| 130 |
-
})
|
| 131 |
-
som_data = {}
|
| 132 |
-
continue
|
| 133 |
-
|
| 134 |
-
# SOM
|
| 135 |
-
m = SOM_RE.search(line)
|
| 136 |
-
if m and current_stage is not None:
|
| 137 |
-
som_data = {
|
| 138 |
-
"sigma": float(m.group(1)),
|
| 139 |
-
"alpha": float(m.group(2)),
|
| 140 |
-
"step": int(m.group(3)),
|
| 141 |
-
}
|
| 142 |
-
continue
|
| 143 |
-
|
| 144 |
-
# STEP
|
| 145 |
-
m = STEP_RE.search(line)
|
| 146 |
-
if m and current_stage is not None:
|
| 147 |
-
current_steps.append({
|
| 148 |
-
"step": int(m.group(1)),
|
| 149 |
-
"loss": float(m.group(2)),
|
| 150 |
-
"tps": int(m.group(3)),
|
| 151 |
-
"tflops": float(m.group(4)),
|
| 152 |
-
"grad_norm": float(m.group(5)),
|
| 153 |
-
"cpu_pct": int(m.group(6)),
|
| 154 |
-
"rss_mb": int(m.group(7)),
|
| 155 |
-
})
|
| 156 |
-
continue
|
| 157 |
-
|
| 158 |
-
# Save last stage if incomplete (no STAGE END)
|
| 159 |
-
if current_stage is not None and current_steps:
|
| 160 |
-
losses = [s["loss"] for s in current_steps]
|
| 161 |
-
tps_arr = [s["tps"] for s in current_steps]
|
| 162 |
-
tflops_arr = [s["tflops"] for s in current_steps]
|
| 163 |
-
rss_arr = [s["rss_mb"] for s in current_steps]
|
| 164 |
-
evolution.append({
|
| 165 |
-
"stage": current_stage,
|
| 166 |
-
"n_samples": current_n,
|
| 167 |
-
"epoch": current_epoch,
|
| 168 |
-
"n_steps": len(current_steps),
|
| 169 |
-
"avg_tflops": sum(tflops_arr) / len(tflops_arr) if tflops_arr else 0,
|
| 170 |
-
"avg_tokens_per_sec": sum(tps_arr) / len(tps_arr) if tps_arr else 0,
|
| 171 |
-
"final_rss_mb": rss_arr[-1] if rss_arr else 0,
|
| 172 |
-
"max_rss_mb": max(rss_arr) if rss_arr else 0,
|
| 173 |
-
"train_loss_mean": sum(losses) / len(losses) if losses else 0,
|
| 174 |
-
"val_loss": None,
|
| 175 |
-
"perplexity": None,
|
| 176 |
-
"overfitting_gap": None,
|
| 177 |
-
"eval_acc": None,
|
| 178 |
-
"elapsed_s": None,
|
| 179 |
-
"som": dict(som_data),
|
| 180 |
-
"incomplete": True,
|
| 181 |
-
})
|
| 182 |
-
|
| 183 |
-
# Filter out empty stages (no steps, no end)
|
| 184 |
-
evolution = [e for e in evolution if e.get("n_steps", 0) > 0 or e.get("val_loss") is not None]
|
| 185 |
-
|
| 186 |
-
# Merge duplicate entries (same stage+n+epoch): one has step stats, other has val_loss
|
| 187 |
-
merged = {}
|
| 188 |
-
order = []
|
| 189 |
-
for e in evolution:
|
| 190 |
-
key = (e["stage"], e["n_samples"], e["epoch"])
|
| 191 |
-
if key not in merged:
|
| 192 |
-
merged[key] = {}
|
| 193 |
-
order.append(key)
|
| 194 |
-
# Merge — later entries overwrite None
|
| 195 |
-
for k, v in e.items():
|
| 196 |
-
if v is not None and v != 0:
|
| 197 |
-
merged[key][k] = v
|
| 198 |
-
elif k not in merged[key]:
|
| 199 |
-
merged[key][k] = v
|
| 200 |
-
# Ensure all keys present
|
| 201 |
-
for k in ["stage", "n_samples", "epoch", "n_steps", "avg_tflops", "avg_tokens_per_sec",
|
| 202 |
-
"final_rss_mb", "max_rss_mb", "train_loss_mean", "val_loss", "perplexity",
|
| 203 |
-
"overfitting_gap", "eval_acc", "elapsed_s", "som"]:
|
| 204 |
-
if k not in merged[key]:
|
| 205 |
-
merged[key][k] = None
|
| 206 |
-
# Mark incomplete (no val_loss)
|
| 207 |
-
if merged[key].get("val_loss") is None:
|
| 208 |
-
merged[key]["incomplete"] = True
|
| 209 |
-
|
| 210 |
-
evolution = [merged[k] for k in order]
|
| 211 |
-
|
| 212 |
-
print(f"[INFO] Parsed {len(evolution)} stage entries (after merge)")
|
| 213 |
-
return evolution
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
def main():
|
| 217 |
-
evolution = parse_log()
|
| 218 |
-
if not evolution:
|
| 219 |
-
print("[ERROR] No evolution data parsed")
|
| 220 |
-
return
|
| 221 |
-
|
| 222 |
-
# Print summary
|
| 223 |
-
print(f"\n{'=' * 100}")
|
| 224 |
-
print(f" EVOLUÇÃO (parsed from log)")
|
| 225 |
-
print(f"{'=' * 100}")
|
| 226 |
-
print(f" {'#':<3} {'stage':<14} {'n':>4} {'ep':>3} {'val_loss':>10} {'ppl':>10} {'eval_acc':>10} {'rss_mb':>8} {'tflops':>8} {'incomp':>7}")
|
| 227 |
-
print(f" {'-'*3} {'-'*14} {'-'*4} {'-'*3} {'-'*10} {'-'*10} {'-'*10} {'-'*8} {'-'*8} {'-'*7}")
|
| 228 |
-
for i, e in enumerate(evolution):
|
| 229 |
-
val = f"{e['val_loss']:.4f}" if e.get("val_loss") is not None else "—"
|
| 230 |
-
ppl = f"{e['perplexity']:.2f}" if e.get("perplexity") is not None else "—"
|
| 231 |
-
acc = f"{e['eval_acc']*100:.2f}%" if e.get("eval_acc") is not None else "—"
|
| 232 |
-
rss = f"{e['final_rss_mb']:.0f}" if e.get("final_rss_mb") else "—"
|
| 233 |
-
tf = f"{e['avg_tflops']:.4f}" if e.get("avg_tflops") else "—"
|
| 234 |
-
incomp = "YES" if e.get("incomplete") else ""
|
| 235 |
-
print(f" {i+1:<3} {e['stage']:<14} {e['n_samples']:>4} {e['epoch']:>3} "
|
| 236 |
-
f"{val:>10} {ppl:>10} {acc:>10} {rss:>8} {tf:>8} {incomp:>7}")
|
| 237 |
-
|
| 238 |
-
# Save partial report
|
| 239 |
-
report = {
|
| 240 |
-
"version": "V6_progressive_partial",
|
| 241 |
-
"timestamp": datetime.now().isoformat(),
|
| 242 |
-
"note": "Partial report — training was killed before full completion. Evolution data extracted from log.",
|
| 243 |
-
"config": {
|
| 244 |
-
"epochs": 1,
|
| 245 |
-
"batch_size": 8,
|
| 246 |
-
"max_seq_len": 24,
|
| 247 |
-
"num_layers_hyp": 8,
|
| 248 |
-
"stages_punctuation": [100, 200, 300, 400, 500],
|
| 249 |
-
"stages_text": [100, 200, 300, 400, 500],
|
| 250 |
-
"stages_heavy": [10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
|
| 251 |
-
},
|
| 252 |
-
"evolution": evolution,
|
| 253 |
-
"n_stages_captured": len(evolution),
|
| 254 |
-
"n_stages_total_expected": 20, # 5 + 5 + 10
|
| 255 |
-
"completion_pct": len(evolution) / 20 * 100,
|
| 256 |
-
}
|
| 257 |
-
REPORT_PATH.write_text(json.dumps(report, indent=2, ensure_ascii=False, default=str))
|
| 258 |
-
print(f"\n[INFO] Partial report saved: {REPORT_PATH}")
|
| 259 |
-
print(f"[INFO] Captured {len(evolution)}/20 stages ({len(evolution)/20*100:.1f}%)")
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
if __name__ == "__main__":
|
| 263 |
-
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|