Percy3822 commited on
Commit
d71f85c
Β·
verified Β·
1 Parent(s): 69cca4e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -15
app.py CHANGED
@@ -1,10 +1,10 @@
1
  # app.py
2
- import os, shutil, subprocess, zipfile, traceback
3
  from pathlib import Path
4
  from datetime import datetime
5
  import gradio as gr
6
 
7
- ROOT = Path(__file__).resolve().parent
8
  DATA = ROOT / "dataset.jsonl"
9
  LOG = ROOT / "train.log"
10
  RUNS = ROOT / "runs"
@@ -55,8 +55,12 @@ def upload_dataset(file):
55
  return f"βœ… Uploaded β†’ {DATA.name}", ls_workspace()
56
  return "⚠ Unexpected item; please upload a .jsonl file.", ls_workspace()
57
 
58
- # -------- training --------
59
- def start_training(run_name):
 
 
 
 
60
  run_id = (run_name or "").strip() or datetime.now().strftime("run_%Y%m%d_%H%M%S")
61
  out_dir = RUNS / run_id
62
  zip_path = RUNS / f"{run_id}.zip"
@@ -67,7 +71,9 @@ def start_training(run_name):
67
  if zip_path.exists():
68
  zip_path.unlink()
69
 
 
70
  LOG.write_text(f"πŸ”₯ Training started…\nRun: {run_id}\n", encoding="utf-8")
 
71
 
72
  cmd = [
73
  "python", str(ROOT / "train.py"),
@@ -81,21 +87,62 @@ def start_training(run_name):
81
  "--learning_rate", "5e-5",
82
  ]
83
  append_log("β–Ά " + " ".join(cmd))
84
- with open(LOG, "a", encoding="utf-8") as lf:
85
- code = subprocess.Popen(cmd, stdout=lf, stderr=subprocess.STDOUT).wait()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
  models = list_models()
88
  model_update = dropdown_update_safe(models, prefer=str(out_dir) if out_dir.exists() else None)
 
89
 
90
  if code == 0 and zip_path.exists():
91
  info = f"βœ… Training complete. Saved: {out_dir.name} | Zip: {zip_path.name}"
92
- dl_update = gr.update(value=str(zip_path), visible=True)
 
93
  else:
94
  info = f"❌ Training failed (exit {code}). Check logs below."
95
- dl_update = gr.update(value=None, visible=False)
96
-
97
- append_log(info)
98
- return info, dl_update, ls_workspace(), read_logs(), model_update
99
 
100
  def refresh_download():
101
  zips = sorted(RUNS.glob("*.zip"), key=lambda p: p.stat().st_mtime, reverse=True)
@@ -165,6 +212,7 @@ def generate(model_path, prompt):
165
  if not model_path:
166
  return "❌ Select a model from the dropdown first."
167
  if not isinstance(model_path, str):
 
168
  return f"❌ Invalid model path type: {type(model_path)._name_}"
169
  if not Path(model_path).exists():
170
  return f"❌ Model folder not found: {model_path}"
@@ -193,7 +241,7 @@ def generate(model_path, prompt):
193
 
194
  # -------- UI --------
195
  with gr.Blocks(title="Python AI β€” Train & Test") as app:
196
- gr.Markdown("## 🧠 Python AI β€” Train & Test\nβ€’ Unique runs β€’ Safe download β€’ Cached generation\n")
197
 
198
  # Test first (so Train can update its dropdown)
199
  with gr.Tab("Test"):
@@ -218,19 +266,22 @@ with gr.Blocks(title="Python AI β€” Train & Test") as app:
218
  ws = gr.Textbox(label="Workspace", lines=16, value=ls_workspace())
219
  run_name = gr.Textbox(label="Run name (optional)", placeholder="e.g., python_small_v1")
220
  up_status = gr.Textbox(label="Upload Status", interactive=False)
221
- start = gr.Button("πŸš€ Start Training", variant="primary")
222
- logs = gr.Textbox(label="πŸ“œ Training Logs", lines=18, value=read_logs())
223
  status = gr.Textbox(label="Status", interactive=False)
224
  download_file = gr.File(label="πŸ“¦ Latest trained zip", visible=False)
225
  refresh_dl_btn = gr.Button("Refresh Download")
226
 
227
  # wiring
228
  ds.change(upload_dataset, inputs=ds, outputs=[up_status, ws])
 
 
229
  start.click(
230
- start_training,
231
  inputs=[run_name],
232
  outputs=[status, download_file, ws, logs, model_list]
233
  )
 
234
  refresh_dl_btn.click(
235
  refresh_download,
236
  outputs=[download_file, ws, model_list]
 
1
  # app.py
2
+ import os, shutil, subprocess, zipfile, traceback, time, io
3
  from pathlib import Path
4
  from datetime import datetime
5
  import gradio as gr
6
 
7
+ ROOT = Path(_file_).resolve().parent
8
  DATA = ROOT / "dataset.jsonl"
9
  LOG = ROOT / "train.log"
10
  RUNS = ROOT / "runs"
 
55
  return f"βœ… Uploaded β†’ {DATA.name}", ls_workspace()
56
  return "⚠ Unexpected item; please upload a .jsonl file.", ls_workspace()
57
 
58
+ # -------- training (LIVE LOGS) --------
59
+ def start_training_live(run_name):
60
+ """
61
+ Streams training logs to the UI while the subprocess runs.
62
+ Yields tuples for outputs: [status, download_file, workspace, logs, model_dropdown]
63
+ """
64
  run_id = (run_name or "").strip() or datetime.now().strftime("run_%Y%m%d_%H%M%S")
65
  out_dir = RUNS / run_id
66
  zip_path = RUNS / f"{run_id}.zip"
 
71
  if zip_path.exists():
72
  zip_path.unlink()
73
 
74
+ # init log
75
  LOG.write_text(f"πŸ”₯ Training started…\nRun: {run_id}\n", encoding="utf-8")
76
+ append_log(f"Workspace:\n{ls_workspace()}")
77
 
78
  cmd = [
79
  "python", str(ROOT / "train.py"),
 
87
  "--learning_rate", "5e-5",
88
  ]
89
  append_log("β–Ά " + " ".join(cmd))
90
+
91
+ # start subprocess with live stdout
92
+ proc = subprocess.Popen(
93
+ cmd,
94
+ stdout=subprocess.PIPE,
95
+ stderr=subprocess.STDOUT,
96
+ bufsize=1,
97
+ universal_newlines=True,
98
+ encoding="utf-8",
99
+ errors="replace",
100
+ )
101
+
102
+ live_log = io.StringIO()
103
+ status_msg = f"πŸš€ Training run '{run_id}' in progress…"
104
+ # stream loop
105
+ while True:
106
+ line = proc.stdout.readline()
107
+ if line == "" and proc.poll() is not None:
108
+ break
109
+ if line:
110
+ append_log(line.rstrip("\n"))
111
+ live_log.write(line)
112
+ # Trim to last ~20k chars for UI
113
+ text = live_log.getvalue()[-20000:]
114
+ # yield with download hidden (until zip exists)
115
+ yield (
116
+ status_msg,
117
+ gr.update(value=None, visible=False),
118
+ ls_workspace(),
119
+ text,
120
+ dropdown_update_safe(list_models(), prefer=None),
121
+ )
122
+ # if zip appears during training (e.g., early save), surface it
123
+ if zip_path.exists():
124
+ yield (
125
+ "πŸ“¦ Model zip created during run.",
126
+ gr.update(value=str(zip_path), visible=True),
127
+ ls_workspace(),
128
+ text,
129
+ dropdown_update_safe(list_models(), prefer=None),
130
+ )
131
+
132
+ code = proc.wait()
133
 
134
  models = list_models()
135
  model_update = dropdown_update_safe(models, prefer=str(out_dir) if out_dir.exists() else None)
136
+ final_logs = read_logs()
137
 
138
  if code == 0 and zip_path.exists():
139
  info = f"βœ… Training complete. Saved: {out_dir.name} | Zip: {zip_path.name}"
140
+ append_log(info)
141
+ yield (info, gr.update(value=str(zip_path), visible=True), ls_workspace(), final_logs, model_update)
142
  else:
143
  info = f"❌ Training failed (exit {code}). Check logs below."
144
+ append_log(info)
145
+ yield (info, gr.update(value=None, visible=False), ls_workspace(), final_logs, model_update)
 
 
146
 
147
  def refresh_download():
148
  zips = sorted(RUNS.glob("*.zip"), key=lambda p: p.stat().st_mtime, reverse=True)
 
212
  if not model_path:
213
  return "❌ Select a model from the dropdown first."
214
  if not isinstance(model_path, str):
215
+ # fix minor bug: _name_ not name
216
  return f"❌ Invalid model path type: {type(model_path)._name_}"
217
  if not Path(model_path).exists():
218
  return f"❌ Model folder not found: {model_path}"
 
241
 
242
  # -------- UI --------
243
  with gr.Blocks(title="Python AI β€” Train & Test") as app:
244
+ gr.Markdown("## 🧠 Python AI β€” Train & Test\nβ€’ Unique runs β€’ Safe download β€’ Cached generation β€’ Live logs\n")
245
 
246
  # Test first (so Train can update its dropdown)
247
  with gr.Tab("Test"):
 
266
  ws = gr.Textbox(label="Workspace", lines=16, value=ls_workspace())
267
  run_name = gr.Textbox(label="Run name (optional)", placeholder="e.g., python_small_v1")
268
  up_status = gr.Textbox(label="Upload Status", interactive=False)
269
+ start = gr.Button("πŸš€ Start Training (Live Logs)", variant="primary")
270
+ logs = gr.Textbox(label="πŸ“œ Training Logs (live)", lines=18, value=read_logs())
271
  status = gr.Textbox(label="Status", interactive=False)
272
  download_file = gr.File(label="πŸ“¦ Latest trained zip", visible=False)
273
  refresh_dl_btn = gr.Button("Refresh Download")
274
 
275
  # wiring
276
  ds.change(upload_dataset, inputs=ds, outputs=[up_status, ws])
277
+
278
+ # STREAMED training: function yields updates
279
  start.click(
280
+ start_training_live,
281
  inputs=[run_name],
282
  outputs=[status, download_file, ws, logs, model_list]
283
  )
284
+
285
  refresh_dl_btn.click(
286
  refresh_download,
287
  outputs=[download_file, ws, model_list]