SPB Git

spb/forge-studio Public

The Instruments of LLM training — a native macOS cockpit for Forge. Train language models from scratch on Apple Silicon without a terminal.

Swift 95.7% Shell 4.3%

Add README

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
simon-pierre boucher committed 5 days ago (Aug 5, 2026) parent 8c30961

Showing 1 changed file with +128 and −0

added README.md +128 −0
@@ -0,0 +1,128 @@
1 +<!-- Author: Simon-Pierre Boucher — contact@spboucher.ai -->
2 +
3 +<div align="center">
4 +
5 +# 🔥 Forge Studio
6 +
7 +### The Instruments of LLM training — a native macOS cockpit for [Forge](https://github.com/spboucher-ai/forge)
8 +
9 +**Train language models from scratch on Apple Silicon without ever opening a terminal.**
10 +Pick a dataset, shape an architecture, hit Start — and watch the loss fall on a
11 +silky live dashboard.
12 +
13 +Swift + SwiftUI + Swift Charts · macOS 14+ · Apple Silicon · zero third-party dependencies
14 +
15 +</div>
16 +
17 +---
18 +
19 +## ✨ What it is
20 +
21 +[Forge](https://github.com/spboucher-ai/forge) is a from-scratch C++20 + Metal LLM
22 +training framework: its own tensors, autograd, flash attention, Muon optimizer,
23 +MoE, QAT, and the `.forge` zero-copy weight format. **Forge Studio is its native
24 +GUI companion** — the whole train-a-model workflow, end to end, as a first-party-feeling
25 +Mac app:
26 +
27 +1. **Prepare data** — TinyStories or streamed Hugging Face mixtures
28 + (FineWeb-Edu, DCLM, Cosmopedia, research presets), with a live console
29 +2. **Design a model** — every Forge config field, from `n_layers` to
30 + DeepSeek-style MoE routing, with live validation
31 +3. **Train** — launch, monitor, stop; runs survive app crashes without lying
32 +4. **Understand** — a loss dashboard built to the TensorBoard/W&B standard, native
33 +5. **Compare** — multi-run overlays on the *tokens* axis, the honest one
34 +6. **Use the model** — generate and evaluate from any checkpoint, in-app
35 +
36 +Forge Studio never reimplements training. It drives the real `forge` binary and
37 +reads its structured metrics — what you see is exactly what the framework did.
38 +
39 +## 📊 The dashboard
40 +
41 +The centerpiece. Built on Swift Charts, fed by an actor-isolated metrics store:
42 +
43 +- **Raw + smoothed loss** — low-opacity raw train line under a bias-corrected EMA
44 + (TensorBoard semantics, 0→0.99 slider), val loss as connected points
45 +- **Hover crosshair** with a full callout: step, train, EMA, perplexity, val
46 +- **Pinch-zoom & pan** on X, double-click to reset, and a **"follow live ⏵" pill**
47 + that re-pins the window to incoming data after you've panned away mid-run
48 +- **Best-val marker** — dashed rule + `best val 2.146 @ step 999` annotation
49 +- **Log/linear Y**, secondary charts for LR schedule (watch warmup + cosine/WSD
50 + actually happen), tokens/sec, grad norm with the `grad_clip` threshold drawn
51 +- **Scale discipline**: raw data is never discarded; the UI reads LTTB-downsampled
52 + snapshots (~2× pixel width). Measured: 200,000 CSV rows ingest in ~1.1 s and
53 + snapshot to chart width in <250 ms — hover stays hitch-free on 100k-step runs
54 +
55 +## 🛡️ Runs that can't lie
56 +
57 +- Single-writer **state machine** (`queued → launching → running → … → finished |
58 + failed | stopped`) with an explicit legal-transition table — illegal transitions
59 + are unrepresentable
60 +- **Atomic persistence** (temp-file-then-rename) for the registry: `kill -9` the
61 + app whenever you like
62 +- **Crash recovery**: runs persisted as active at launch are truthfully resolved —
63 + including the case where the forge process is *still alive* — with an honest
64 + explanation and the recovery path (`ckpt_latest.bin`)
65 +- **Watchdog**: a "possibly stalled" badge when metrics stop flowing for 30 s
66 +- Stop is SIGTERM and the UI tells you exactly what that means (Forge doesn't
67 + checkpoint on signals; you lose at most `checkpoint_every` steps)
68 +- Local **notifications** with the final loss when a run finishes or fails
69 +
70 +## 🧪 Ground truth, tested
71 +
72 +`RESEARCH.md` documents the full Forge contract (config schema, CLI, `log.csv`
73 +grammar, checkpoint/resume, signal behavior) extracted from the source. The test
74 +suite enforces it:
75 +
76 +- `ForgeConfig` round-trips the **real** `configs/*.json` from the forge repo,
77 + byte-compatible field names
78 +- The Swift param-count formula matches `forge info` for every shipped config
79 +- CSV/stdout parsers are exercised against real and mutated lines (legacy
80 + 6-column headers, garbage, truncation)
81 +- LTTB invariants (endpoints exact, monotonic X), EMA bias correction,
82 + state-machine table, LR-preview math vs `scheduler.h`, 200k-point stress test
83 +
84 +## 🚀 Quick start
85 +
86 +```bash
87 +# 1. Build Forge (once)
88 +git clone https://github.com/spboucher-ai/forge && cd forge
89 +cmake -B build && cmake --build build -j
90 +
91 +# 2. Run Forge Studio
92 +# — from the DMG on the Releases page, or from source:
93 +git clone https://github.com/spboucher-ai/forge-studio && cd forge-studio
94 +./scripts/package-app.sh release && open dist/ForgeStudio.app
95 +```
96 +
97 +In **Settings**: point to `forge/build/forge` (validated live via `forge info`) and
98 +pick a workspace. Then **Datasets → New dataset** (TinyStories at vocab 4096 takes
99 +a few minutes), **+ New run**, pick the `gpt-10m` preset, Start — first loss point
100 +lands within seconds.
101 +
102 +## 🏗️ Architecture
103 +
104 +| Layer | What lives there |
105 +|:--|:--|
106 +| `Models/` | `ForgeConfig` (Codable mirror of every Forge field + validation + derived math), `Run` (state machine), `MetricPoint`, `Dataset` (bin-header readers) |
107 +| `Services/` | `ProcessRunner` (actor, incremental line streaming), `LogParser` (header-driven CSV + stdout events), `MetricsStore` (actor, incremental tail, LTTB snapshots), `RunStore` (atomic registry), `RunSupervisor`, `ForgeBinaryLocator`, `SystemInfo` |
108 +| `Charts/` | `TrainingChartView` (the interactive dashboard), `Downsampler` (LTTB), `Smoothing` (bias-corrected EMA) |
109 +| `Views/` | Navigation shell, run dashboard, New Run editor (presets, derived panel, LR preview), Compare, Datasets, Checkpoints/Generate/Eval, Settings |
110 +| `scripts/` | `package-app.sh` (SwiftPM → .app), `generate-icon.sh`, `notarize.sh` (Developer ID + hardened runtime + DMG + notarytool + stapler) |
111 +
112 +Swift Concurrency throughout: the process I/O and metrics paths never touch the
113 +main thread; the UI observes debounced snapshots. No third-party packages.
114 +
115 +## 🗺️ Roadmap
116 +
117 +- Linked axes across secondary charts + synchronized crosshair
118 +- Clickable checkpoint annotations on the loss chart
119 +- Exhaustive form for every architecture-variant knob (today: JSON import covers them)
120 +- PNG/CSV chart export, run queue for sequential trainings
121 +- `.forge` repo browser (weight history as commits — the format already does git-style deltas)
122 +
123 +## 👤 Author
124 +
125 +**Simon-Pierre Boucher** — contact@spboucher.ai
126 +
127 +Built alongside [Forge](https://github.com/spboucher-ai/forge). If Forge is the
128 +engine, Studio is the cockpit.
129