Spaces:
Runtime error
Runtime error
Upload 18 files
Browse files- app.py +30 -13
- finetune_data.py +2 -1
app.py
CHANGED
|
@@ -158,16 +158,31 @@ _SELFTEST = {"done": False, "result": ""}
|
|
| 158 |
|
| 159 |
|
| 160 |
def _export_dataset():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
path = finetune_data.export()
|
| 162 |
if not path:
|
| 163 |
-
return ("
|
| 164 |
-
"a few tickers first — each run is saved automatically.",
|
| 165 |
gr.update(visible=False))
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
|
| 172 |
|
| 173 |
def _run_selftest():
|
|
@@ -348,12 +363,11 @@ with gr.Blocks(title="Chan Compass · US", **_style_kw) as demo:
|
|
| 348 |
"few hundred, export the JSONL, then follow `FINETUNE_GUIDE.md` "
|
| 349 |
"to LoRA-tune Qwen3-1.7B and publish it.")
|
| 350 |
ft_status = gr.Markdown(finetune_data.status_line())
|
| 351 |
-
|
| 352 |
-
ft_refresh = gr.Button("↻ Count pairs")
|
| 353 |
-
ft_export = gr.Button("⬇ Export dataset (JSONL)", variant="primary")
|
| 354 |
ft_out = gr.Markdown()
|
| 355 |
ft_file = gr.File(label="Download training data", visible=False)
|
| 356 |
-
|
|
|
|
| 357 |
ft_export.click(_export_dataset, None, [ft_out, ft_file])
|
| 358 |
|
| 359 |
gr.Markdown("Chan Compass · educational tool, not investment advice · "
|
|
@@ -403,7 +417,10 @@ if os.environ.get("AUTO_LOAD_MODEL", "1") == "1":
|
|
| 403 |
threading.Thread(target=_auto_load_model, daemon=True).start()
|
| 404 |
|
| 405 |
if __name__ == "__main__":
|
|
|
|
|
|
|
|
|
|
| 406 |
if _GR_MAJOR >= 6:
|
| 407 |
-
demo.launch(theme=theme, css=S2_CSS)
|
| 408 |
else:
|
| 409 |
-
demo.launch()
|
|
|
|
| 158 |
|
| 159 |
|
| 160 |
def _export_dataset():
|
| 161 |
+
n = finetune_data.count()
|
| 162 |
+
if n == 0:
|
| 163 |
+
return ("⚠️ **0 training pairs captured yet.** Pairs are saved only when "
|
| 164 |
+
"the **Signals → AI summary** finishes with a model loaded. Steps: "
|
| 165 |
+
"1) Model tab — wait for the Translator sub-agent to show ✅; "
|
| 166 |
+
"2) Signals — Run analysis, pick a ticker, click **AI summary**, "
|
| 167 |
+
"let it finish; repeat a few times; 3) come back and Export.",
|
| 168 |
+
gr.update(visible=False))
|
| 169 |
path = finetune_data.export()
|
| 170 |
if not path:
|
| 171 |
+
return ("⚠️ Export failed to write the file (storage error). Try again.",
|
|
|
|
| 172 |
gr.update(visible=False))
|
| 173 |
+
# Copy to a folder under the app's working dir, which Gradio serves
|
| 174 |
+
# reliably (the /data bucket and /tmp are not in Gradio's allowed paths).
|
| 175 |
+
import shutil
|
| 176 |
+
served_dir = os.path.join(os.getcwd(), "exports")
|
| 177 |
+
os.makedirs(served_dir, exist_ok=True)
|
| 178 |
+
served = os.path.join(served_dir, os.path.basename(path))
|
| 179 |
+
try:
|
| 180 |
+
shutil.copy(path, served)
|
| 181 |
+
except OSError:
|
| 182 |
+
served = path
|
| 183 |
+
msg = (f"✅ Exported **{n}** captured pair(s). Download below, then follow "
|
| 184 |
+
f"`finetune/FINETUNE_GUIDE.md` to LoRA-tune Qwen3-1.7B and publish it.")
|
| 185 |
+
return msg, gr.update(value=served, visible=True)
|
| 186 |
|
| 187 |
|
| 188 |
def _run_selftest():
|
|
|
|
| 363 |
"few hundred, export the JSONL, then follow `FINETUNE_GUIDE.md` "
|
| 364 |
"to LoRA-tune Qwen3-1.7B and publish it.")
|
| 365 |
ft_status = gr.Markdown(finetune_data.status_line())
|
| 366 |
+
ft_export = gr.Button("⬇ Export dataset (JSONL)", variant="primary")
|
|
|
|
|
|
|
| 367 |
ft_out = gr.Markdown()
|
| 368 |
ft_file = gr.File(label="Download training data", visible=False)
|
| 369 |
+
ft_timer = gr.Timer(3.0)
|
| 370 |
+
ft_timer.tick(lambda: finetune_data.status_line(), None, ft_status)
|
| 371 |
ft_export.click(_export_dataset, None, [ft_out, ft_file])
|
| 372 |
|
| 373 |
gr.Markdown("Chan Compass · educational tool, not investment advice · "
|
|
|
|
| 417 |
threading.Thread(target=_auto_load_model, daemon=True).start()
|
| 418 |
|
| 419 |
if __name__ == "__main__":
|
| 420 |
+
import paths as _p
|
| 421 |
+
_allowed = [os.path.join(os.getcwd(), "exports"), _p.DATASET_DIR]
|
| 422 |
+
os.makedirs(_allowed[0], exist_ok=True)
|
| 423 |
if _GR_MAJOR >= 6:
|
| 424 |
+
demo.launch(theme=theme, css=S2_CSS, allowed_paths=_allowed)
|
| 425 |
else:
|
| 426 |
+
demo.launch(allowed_paths=_allowed)
|
finetune_data.py
CHANGED
|
@@ -33,8 +33,9 @@ INSTRUCTION = ("You are an equity analyst. Based only on this factual read of a
|
|
| 33 |
|
| 34 |
|
| 35 |
def _clean(text: str) -> str:
|
| 36 |
-
# strip
|
| 37 |
text = re.sub(r"<think>.*?</think>", "", text, flags=re.S)
|
|
|
|
| 38 |
text = text.replace("🤖 **AI narrative (Translator sub-agent · Qwen3-1.7B):**", "")
|
| 39 |
return text.strip()
|
| 40 |
|
|
|
|
| 33 |
|
| 34 |
|
| 35 |
def _clean(text: str) -> str:
|
| 36 |
+
# strip stray think tags and any "AI narrative ..." UI prefix
|
| 37 |
text = re.sub(r"<think>.*?</think>", "", text, flags=re.S)
|
| 38 |
+
text = re.sub(r"^🤖\s*\*\*AI narrative[^\n]*\*\*\s*", "", text)
|
| 39 |
text = text.replace("🤖 **AI narrative (Translator sub-agent · Qwen3-1.7B):**", "")
|
| 40 |
return text.strip()
|
| 41 |
|