File size: 6,083 Bytes
22aa3d8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python3
"""Simple status server for the overnight ablation run.
Serves monitor dashboards for whichever training is currently active.
"""

import http.server
import json
import os
import time

VAP_DIR = "/home/deployer/laion/Voice-Acting-Pipeline"

ABLATIONS = [
    ("A_nat_quality", "finetune_output/ablation_nat_quality", 8768),
    ("B_nat_centroid", "finetune_output/ablation_nat_centroid", 8769),
    ("C_nat_quality_speaker", "finetune_output/ablation_nat_quality_speaker", 8770),
    ("D_nat_speaker", "finetune_output/ablation_nat_speaker", 8771),
]


class StatusHandler(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == "/" or self.path == "/status":
            self.send_response(200)
            self.send_header("Content-Type", "text/html")
            self.end_headers()

            html = """<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Ablation Study Status</title>
<meta http-equiv="refresh" content="30">
<style>
body{font-family:system-ui;background:#0d1117;color:#c9d1d9;padding:20px}
h1{color:#58a6ff}
.card{background:#161b22;border:1px solid #30363d;border-radius:8px;padding:15px;margin:10px 0}
.active{border-color:#3fb950}
.done{border-color:#8b949e}
.pending{border-color:#30363d;opacity:0.5}
.name{font-size:1.2em;font-weight:bold;color:#f0883e}
.status{font-size:0.9em;color:#8b949e;margin-top:5px}
.metrics{font-family:monospace;font-size:0.85em;margin-top:8px;color:#c9d1d9}
a{color:#58a6ff}
</style></head><body>
<h1>Ablation Study — Overnight Runner</h1>
<p style="color:#8b949e">Auto-refreshes every 30s. """ + time.strftime("%Y-%m-%d %H:%M:%S UTC") + """</p>
"""
            for name, output_dir, port in ABLATIONS:
                status_path = os.path.join(VAP_DIR, output_dir, "status.json")
                metrics_path = os.path.join(VAP_DIR, output_dir, "metrics.jsonl")

                if os.path.exists(status_path):
                    try:
                        with open(status_path) as f:
                            st = json.load(f)
                        step = st.get("step", 0)
                        total = st.get("total_steps", 234)
                        loss = st.get("flow_loss", st.get("loss", "?"))
                        best = st.get("best_loss", "?")
                        elapsed = st.get("elapsed_sec", 0)
                        eta = st.get("eta_sec", 0)
                        pct = int(100 * step / total) if total else 0

                        if step >= total:
                            cls = "done"
                            status_text = f"COMPLETED — {step}/{total} steps in {elapsed/60:.0f}min"
                        else:
                            age = time.time() - os.path.getmtime(status_path)
                            if age < 120:
                                cls = "active"
                                status_text = f"RUNNING — {step}/{total} ({pct}%) — ETA {eta/60:.0f}min"
                            else:
                                cls = "done"
                                status_text = f"COMPLETED — {step}/{total} steps"

                        metrics_text = f"flow_loss={loss}  best_loss={best}  elapsed={elapsed/60:.0f}min"

                        # Get last naturalness from metrics
                        if os.path.exists(metrics_path):
                            try:
                                with open(metrics_path) as mf:
                                    lines = mf.readlines()
                                if lines:
                                    last = json.loads(lines[-1])
                                    nat = last.get("naturalness_reward")
                                    if nat is not None:
                                        metrics_text += f"  nat={nat:.4f}"
                            except Exception:
                                pass

                        html += f"""<div class="card {cls}">
<div class="name">{name}</div>
<div class="status">{status_text}</div>
<div class="metrics">{metrics_text}</div>
<div style="margin-top:5px"><a href="http://localhost:{port}" target="_blank">Monitor Dashboard (port {port})</a></div>
</div>"""
                    except Exception as e:
                        html += f'<div class="card done"><div class="name">{name}</div><div class="status">Error reading status: {e}</div></div>'
                else:
                    html += f'<div class="card pending"><div class="name">{name}</div><div class="status">PENDING — not started yet</div></div>'

            # Check for eval
            eval_log = "/tmp/ablation_eval.log"
            if os.path.exists(eval_log):
                html += '<div class="card active"><div class="name">Evaluation</div>'
                try:
                    with open(eval_log) as f:
                        lines = f.readlines()
                    last_lines = lines[-5:] if lines else ["No output yet"]
                    html += '<div class="metrics">' + "<br>".join(l.strip() for l in last_lines) + '</div>'
                except Exception:
                    html += '<div class="status">Running...</div>'
                html += '</div>'

            # Check for overall log
            html += '<div class="card"><div class="name">Overall Log (last 10 lines)</div><div class="metrics">'
            try:
                with open("/tmp/ablation_overnight.log") as f:
                    lines = f.readlines()
                for line in lines[-10:]:
                    html += line.strip() + "<br>"
            except Exception:
                html += "Log not available yet"
            html += '</div></div>'

            html += "</body></html>"
            self.wfile.write(html.encode())
        else:
            self.send_response(404)
            self.end_headers()

    def log_message(self, format, *args):
        pass  # Suppress logs


if __name__ == "__main__":
    server = http.server.HTTPServer(("0.0.0.0", 8775), StatusHandler)
    print("Status server on http://0.0.0.0:8775")
    server.serve_forever()