Skip to content

Commit ad0f19e

Browse files
committed
docs(VisualBuilderPlan): JSON+runner architecture, F-A.2 CLI runner, Раschka gallery coverage section
JSON+runner architecture changes (per user feedback): - GUI НИКОГДА не генерит .py codegen — emits canonical model_spec.json + pipeline.yaml. Generic cppmega-run runner consume's both. - 'Build & Step' button → 'Run pipeline' split-button dropdown (Smoke / Full validate / Train). - 'Export Python' modal → 'Export JSON spec' + 'Export Pipeline YAML' + 'Export shareable URL' (JupyterLite-mode base64 в query string). - New §5.3: generic runner contract — 11 built-in stages (parse / verify_build_spec / apply_rewrites / resolve_shapes / estimate_memory / check_gotchas / build_model / dry_forward / input_parity_check / loss_smoke / optimizer_smoke / train), each configurable as skip/run/strict, continue-on-failure flag, CLI 'cppmega-run spec.json --pipeline pipeline.yaml --stages a,b,c'. - Mapping table updated: each 'Run pipeline' variant → exact cppmega-run invocation. - Single source of truth: same JSON, same stages, same diagnostics, different backend (Jupyter Mac vs H100 cluster). New Этап F-A.2 — CLI runner cppmega-run + pipeline.yaml stages (1 неделя): - cppmega_v4.runner module (~250 строк): Pipeline + Stage + StageResult dataclasses, PipelineRunner orchestrator - CLI entry point с --pipeline / --stages / --json flags, exit 0/1 - Built-in pipeline configs smoke.yaml / full.yaml / train.yaml - Performance gate: <1s smoke per preset (12 presets) - Inserted between F-A and F-B in execution order New §10 Покрытие Раschka LLM Architecture Gallery (71 моделей): - 12 наших presets прямо покрывают ~22 entries (31%) - ~45 entries trivially addable через новые preset factories (НОЛЬ новых бриков, только композиции 22 существующих) - ~5 истинных гэпов: xLSTM mLSTM brick, abs_pos_embed brick, per_layer_embed brick, parallel-block composition в preset DSL (Tiny Aya), Mamba-2 explicit (опц) - 100% coverage plan = отдельный bd-эпик cppmega-mlx-1t0 (Gallery Coverage Completion, 4 stage children) Бюджет обновлён: 8 недель (F-A + F-A.2 + F-B..F-E).
1 parent 61cf01f commit ad0f19e

1 file changed

Lines changed: 217 additions & 26 deletions

File tree

VisualBuilderPlan.md

Lines changed: 217 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ Exa neural + content / Perplexity reasoning Gemini 3.1; Tavily вылетел
1414
0. TL;DR
1515

1616
Стек: **anywidget + React Flow 12 + Rust/WASM core + ELK.js layout + Python
17-
JSON-RPC backend**. Шипается двумя путями из одного codebase:
17+
JSON-RPC backend + `cppmega-run` CLI**. GUI **никогда не генерит .py
18+
codegen** — эмитит canonical `model_spec.json` + `pipeline.yaml`,
19+
которые consume generic runner. Single source of truth, diffable в git,
20+
A/B compareable, CI-friendly. Researcher copies `spec.json` из GUI
21+
session → ML engineer запускает identical pipeline на H100 cluster.
22+
23+
Шипается двумя путями из одного codebase:
1824

1925
(a) Jupyter widget — anywidget traitlets, backend = реальный
2026
cppmega_v4.* в notebook'е (instantiate=True, MLX runtime).
@@ -250,8 +256,18 @@ engram; etc.).
250256
- green если total < device_hbm * 0.7
251257
- yellow если 0.7..0.9
252258
- red если >0.9 (включая duplication, kernel_boundary)
253-
7. **Build & Step** button (primary): запускает `build_model(spec)` +
254-
один forward+loss+optimizer.update.
259+
7. **Run pipeline** split-button dropdown (primary):
260+
- "**Smoke**" (default) — parse → verify_build_spec → apply_rewrites
261+
→ resolve_shapes → estimate_memory → check_gotchas → build_model
262+
→ dry_forward (1, 8, H synthetic). <1s. Returns shape parity report.
263+
- "**Full validate**" — adds input_parity_check (load N rows from
264+
parquet, run tokenizer, verify shape match at every brick boundary)
265+
+ loss_smoke + optimizer_smoke. <30s.
266+
- "**Train**" — full pipeline + actual training loop. Only enabled
267+
in Jupyter widget mode (real MLX runtime).
268+
Each click POSTs the spec JSON + pipeline.yaml to the runner. The
269+
runner is `cppmega-run spec.json --pipeline pipeline.yaml --stages
270+
<selected>` — see §5.3 below.
255271

256272
### 4.3 Right sidebar (320px)
257273

@@ -317,13 +333,22 @@ Tabbed: **Loss** / **Optim** / **Rewriters** / **Sharding** / **Gotchas**.
317333
- **DeviceTopology builder**: text inputs for device kind / hbm / count
318334
/ interconnect / bandwidth + mesh-axis table (axis name + degree) +
319335
validation hint when product != device count.
320-
- **Build & Step results**: после нажатия Build & Step — modal с loss
321-
scalar (finite/NaN), shape of head output, optimizer state-bytes
322-
delta, error stack trace если что-то упало.
323-
- **Save / Load**: graph + loss/optim/rewrites/sharding → JSON file.
324-
- **Export**: код на Python (MLX) — generates a complete
325-
`cppmega_v4.buildspec.build_model(spec, ...)` invocation как .py
326-
file. (TorchStack-style Graph2Code.)
336+
- **Pipeline run results**: после клика "Run pipeline" — modal с
337+
per-stage status (✓/✗), per-stage elapsed_ms, и для каждой failed
338+
stage — конкретный diagnostic (shape mismatch на ребре X, loss=NaN
339+
на step Y, OOM на rank Z, etc.). Можно download полный JSON report.
340+
- **Save / Load**: graph + loss/optim/rewrites/sharding → JSON file
341+
(canonical ModelBuildSpec serialisation — diffable в git).
342+
- **Export**:
343+
- "**Export JSON spec**" — текущая спека как `model_spec.json` (то
344+
что `cppmega-run` consume). Это и есть единственный source of truth.
345+
- "**Export Pipeline YAML**" — `pipeline.yaml` с выбранными stages
346+
(smoke / full validate / train). Reviewer может скопировать и
347+
запустить `cppmega-run spec.json --pipeline pipeline.yaml`.
348+
- "**Export shareable URL**" (только JupyterLite mode) — base64-encoded
349+
spec в query string, шарится одной ссылкой.
350+
Никакого `.py` codegen — generic runner consume JSON напрямую,
351+
меньше surface area для дрейфа.
327352

328353
### 4.6 Empty state
329354

@@ -366,7 +391,7 @@ Tabbed: **Loss** / **Optim** / **Rewriters** / **Sharding** / **Gotchas**.
366391
| `sharding.update` | ShardingSpec change | 0ms | <100ms | Yes |
367392
| `verify.request` | follows graph/param/etc | 150ms coalesced | <100ms | Yes |
368393
| `sharding.request` | explicit "Suggest sharding" | n/a | <2s | Yes |
369-
| `build.request` | "Build & Step" button | n/a | <5s | Yes |
394+
| `pipeline.run` | "Run pipeline" button | n/a | smoke <1s / full <30s / train: open | Yes (runner) |
370395
| `backend.status` | heartbeat 1Hz ||| Server-push |
371396

372397
Ключ кеша: `sha256(canonical_json(spec))`, исключая позиции узлов.
@@ -480,22 +505,120 @@ Frontend держит LRU(50). Backend держит per-step LRU.
480505
}
481506
```
482507

483-
**`build.request` response:**
508+
**`pipeline.run` request (JSON spec + pipeline.yaml):**
509+
```json
510+
{
511+
"jsonrpc": "2.0", "id": "p_99", "method": "pipeline.run",
512+
"params": {
513+
"spec": { /* full ModelBuildSpec serialised, see verify.request */ },
514+
"pipeline": {
515+
"stages": ["parse", "verify_build_spec", "apply_rewrites",
516+
"resolve_shapes", "estimate_memory", "check_gotchas",
517+
"build_model", "dry_forward"],
518+
"stage_options": {
519+
"dry_forward": {"B": 1, "S": 8},
520+
"input_parity_check": {
521+
"parquet_path": "/data/sample.parquet",
522+
"num_rows": 32, "tokenizer": "tiktoken-cl100k"
523+
}
524+
}
525+
}
526+
}
527+
}
528+
```
529+
530+
**`pipeline.run` response (per-stage results):**
484531
```json
485532
{
486533
"result": {
487-
"built": true,
488-
"spec_applied": { "graph": {/*post-rewrite*/}, "loss": {/*post-rewrite*/} },
489-
"forward_step": {
490-
"loss_scalar": 10.42, "finite": true,
491-
"output_shape": [1, 4096, 32000],
492-
"optim_state_delta_bytes": 4096
493-
},
494-
"elapsed_ms": 1234
534+
"stages": [
535+
{"name": "parse", "status": "ok", "elapsed_ms": 0.4},
536+
{"name": "verify_build_spec", "status": "ok", "elapsed_ms": 1.2,
537+
"warnings": 0, "errors": 0},
538+
{"name": "apply_rewrites", "status": "ok", "elapsed_ms": 0.8,
539+
"rewrites_applied": ["MTPRewriter(k=2)"]},
540+
{"name": "resolve_shapes", "status": "ok", "elapsed_ms": 2.1},
541+
{"name": "estimate_memory", "status": "ok", "elapsed_ms": 1.5,
542+
"worst_rank_bytes": 2233445566, "fits": true},
543+
{"name": "check_gotchas", "status": "ok", "elapsed_ms": 0.3,
544+
"fired": 1, "errors": 0},
545+
{"name": "build_model", "status": "ok", "elapsed_ms": 234},
546+
{"name": "dry_forward", "status": "fail", "elapsed_ms": 12,
547+
"error": {
548+
"type": "ShapeMismatch",
549+
"detail": "brick 'attn' expected (1,8,4096), got (1,8,2048) from producer 'g0'",
550+
"node_id": "g0", "edge": ["g0","attn"]
551+
}}
552+
],
553+
"overall_status": "fail",
554+
"total_elapsed_ms": 252.3
495555
}
496556
}
497557
```
498558

559+
### 5.3 Generic runner contract
560+
561+
GUI **никогда не генерит .py файл**. Вместо этого она эмитит:
562+
563+
1. **`model_spec.json`** — canonical serialisation `ModelBuildSpec`
564+
(graph + loss + optim + rewrites + dim_env + sharding). Diffable
565+
в git, версионируется, A/B сравнивается trivially.
566+
567+
2. **`pipeline.yaml`** — какие stages в каком порядке запускать +
568+
per-stage options. Built-in stages (определены в
569+
`cppmega_v4.runner`):
570+
571+
| Stage | Что делает | Bytes / latency |
572+
|-------------------------|-----------------------------------------------------|-----------------|
573+
| `parse` | JSON → ModelBuildSpec (Pydantic validation) | <1 KB / <1ms |
574+
| `verify_build_spec` | head_outputs/optim matchers/rewrite chain coherence | 0 / <5ms |
575+
| `apply_rewrites` | MTPRewriter / IFIMRewriter / MHCRewriter | 0 / <10ms |
576+
| `resolve_shapes` | strict=True, every edge resolves under dim_env | 0 / <20ms |
577+
| `estimate_memory` | single-device + distributed reports | 0 / <10ms |
578+
| `check_gotchas` | 15 footguns | 0 / <5ms |
579+
| `build_model` | instantiate nn.Module | full params / 100-500ms |
580+
| `dry_forward` | synthetic input (1, 8, H), assert shape propagates | tiny / <100ms |
581+
| `input_parity_check` | parquet sample → tokenizer → shape match per brick | small / <2s |
582+
| `loss_smoke` | compute loss on dry-forward, assert finite | tiny / <50ms |
583+
| `optimizer_smoke` | one optim.update, assert no NaN, state delta > 0 | tiny / <100ms |
584+
| `train` | actual training loop (`num_steps`, `dataset`) | depends |
585+
586+
Каждая stage configurable as `skip` / `run` / `strict`. Failed
587+
stage stops pipeline unless `continue_on_failure=true`.
588+
589+
3. **CLI runner**: `cppmega-run`
590+
591+
```bash
592+
# smoke (default) — для быстрой итерации
593+
cppmega-run spec.json
594+
# → 8 stages parse..dry_forward, ~1s, exit 0/1
595+
596+
# full validation — для CI
597+
cppmega-run spec.json --pipeline pipeline.yaml --stages all
598+
# → 11 stages, parquet check, ~30s
599+
600+
# custom stages — пропустить build_model если только sizing-test
601+
cppmega-run spec.json --stages parse,verify,resolve,estimate
602+
603+
# full train — для реального запуска
604+
cppmega-run spec.json --pipeline train.yaml --stages train
605+
606+
# JSON output для CI integration
607+
cppmega-run spec.json --json > report.json
608+
```
609+
610+
Runner живёт в `cppmega_v4.runner` (новый модуль). Wraps уже
611+
существующих `cppmega_v4.buildspec.build_model`, `verify_build_spec`,
612+
`verify_distributed_plan` — добавляет только pipeline orchestrator
613+
+ parquet input check + CLI shim. ~250 строк.
614+
615+
4. **Single source of truth**: GUI shows what `cppmega-run` would do.
616+
CI runs `cppmega-run spec.json --stages parse,verify,resolve,estimate,check_gotchas`
617+
on every PR с changed spec. Researcher copies spec.json + pipeline.yaml
618+
out of GUI session, commits to git, hands off to ML engineer who
619+
re-runs identical pipeline on H100 cluster — **same JSON, same
620+
stages, same diagnostics, different backend**.
621+
499622
### 5.3 Error envelope
500623

501624
```json
@@ -548,8 +671,12 @@ UI poсредник: ошибки кода маппит на in-place toast + no
548671
| master_weights toggle | `sharding.update``verify`| `ShardingSpec.master_weights_fp32` |
549672
| activation_checkpointing | `sharding.update``verify` | `ShardingSpec.activation_checkpointing` |
550673
| Auto-fix gotcha | `sharding.update` | `ShardingSpec.compile_mode='regional'` |
551-
| Build & Step button | `build.request` | `build_model(spec)``BuiltModel` |
552-
| Export button | (local download) | `python_codegen(spec)` → .py file |
674+
| Run pipeline (Smoke)| `pipeline.run` (8 stages) | `cppmega-run spec.json --stages parse,..,dry_forward` |
675+
| Run pipeline (Full) | `pipeline.run` (11 stages) | `cppmega-run spec.json --pipeline pipeline.yaml --stages all` |
676+
| Run pipeline (Train)| `pipeline.run` (train stage) | `cppmega-run spec.json --pipeline train.yaml --stages train` |
677+
| Export JSON spec | (local download) | canonical `model_spec.json` serialisation |
678+
| Export Pipeline YAML| (local download) | `pipeline.yaml` with selected stages |
679+
| Export shareable URL| (clipboard, JupyterLite only) | base64-encoded spec в URL query string |
553680

554681
---
555682

@@ -559,11 +686,30 @@ UI poсредник: ошибки кода маппит на in-place toast + no
559686

560687
**Этап F-A — JSON-RPC contract + Python jsonrpc server (1 неделя)**
561688
- Зафиксировать JSON schema (TypeScript + Pydantic в shared package)
689+
- Canonical ModelBuildSpec ↔ JSON serialisation (round-trip identity test)
562690
- FastAPI standalone server обёртка над `verify_distributed_plan`,
563-
`suggest_sharding`, `build_model`, `verify_and_estimate`
691+
`suggest_sharding`, `verify_and_estimate`, `pipeline.run`
564692
- Test suite: golden round-trip JSON для каждого endpoint
565693
- Cache layer с LRU(50)
566694

695+
**Этап F-A.2 — CLI runner `cppmega-run` + pipeline.yaml stages (1 неделя)**
696+
- Новый модуль `cppmega_v4.runner` (~250 строк):
697+
* `Pipeline` dataclass: ordered list of `Stage`s, per-stage options
698+
* 11 built-in stages: parse / verify_build_spec / apply_rewrites /
699+
resolve_shapes / estimate_memory / check_gotchas / build_model /
700+
dry_forward / input_parity_check / loss_smoke / optimizer_smoke /
701+
train
702+
* `StageResult` dataclass: name + status + elapsed_ms + diagnostics
703+
* `PipelineRunner.run(spec, pipeline)` orchestrator с continue-on-failure flag
704+
- CLI shim `cppmega-run` (entry point via setup.py):
705+
* `--pipeline pipeline.yaml` (default = built-in "smoke" pipeline)
706+
* `--stages a,b,c` (override)
707+
* `--json` (machine-readable output для CI)
708+
* Exit code 0 = all green, 1 = any failed
709+
- Built-in pipeline configs shipped: `smoke.yaml`, `full.yaml`, `train.yaml`
710+
- Tests: per-stage unit + system "every preset passes smoke pipeline"
711+
perf gate < 1s per preset (12 presets)
712+
567713
**Этап F-B — React Flow canvas + 22 brick custom nodes (2 недели)**
568714
- Vite + React 18 + xyflow scaffolding
569715
- 22 brick custom node components (color-coded, inline param editor,
@@ -640,10 +786,55 @@ UI poсредник: ошибки кода маппит на in-place toast + no
640786

641787
---
642788

643-
10. Бюджет + риски
789+
10. Покрытие Раschka LLM Architecture Gallery (71 модель)
790+
791+
Прогнал список галереи против наших 22 bricks + 12 presets.
792+
793+
**12 наших пресетов прямо покрывают ~22 entries (31%)**:
794+
qwen3_next ← Qwen3 Next/3.5/3.6 (35B); kimi_linear ← Kimi Linear;
795+
kimi_k2 ← K2/K2.5/K2.6; deepseek_v3 ← V3/R1/V3.2/Mistral Large 3;
796+
deepseek_v4_flash ← V4-Flash/V4-Pro; gemma4 ← 26B-A4B; mistral4 ←
797+
Small 4; ling26 ← 2.6; longcat ← Flash-Lite; nemotron3 ← Nano/Super/Nano 4B;
798+
zaya1 ← 8B; arcee_trinity ← Large.
799+
800+
**~45 entries trivially addable** через новые preset factories — НОЛЬ
801+
новых бриков, только композиции существующих:
802+
- LLaMA-style (`attention` + `mlp`): #2, #3, #38, #49 (Phi-4),
803+
#42, #71 (Granite 4.1)
804+
- OLMo-style (`attention` QK-norm + `mlp`): #4, #26, #27
805+
- Qwen3 dense: #10, #13, #14, #15, #66
806+
- Mixtral-style (`attention` + `moe`): #9 Llama 4 Maverick, #11/#12 Qwen3,
807+
#22 Grok 2.5, #39, #43, #56, #67, #68, #70
808+
- GLM-style (+ shared expert): #18, #32, #47, #51, #52
809+
- DeepSeek-style (`mla` + `moe`): #34, #48, #63
810+
- Sliding+global+MoE: #19/#20 GPT-OSS, #24, #31, #41, #44, #45, #61
811+
- Gemma 3 dense: #7, #21, #36
812+
- SmolLM3 (#16) — нужен per-layer NoPE toggle
813+
814+
**~5 entries требуют новых бриков или архитектурных расширений** (true gaps):
815+
- **#50 xLSTM 7B** — `mlstm` brick (matrix-memory LSTM, no self-attention)
816+
- **#1 GPT-2 XL** — `abs_pos_embed` brick (learned absolute positions)
817+
- **#57/#58 Gemma 4 E2B/E4B** — `per_layer_embed` brick
818+
- **#44 Tiny Aya** — parallel-block topology (GQA‖MLP параллельно,
819+
sum results); BrickGraph DAG поддерживает, но preset DSL exposes
820+
только linear chains — нужен parallel composer
821+
- **Mamba-2 explicit brick** — debatable (mamba3 brick покрывает похожую
822+
топологию); можно alias `mamba2 → mamba3` или добавить explicit
823+
824+
**План доведения до 100% покрытия — отдельный bd-эпик `cppmega-mlx-cov1`**
825+
(заведён параллельно с этим планом). 4 стадии: missing presets, new
826+
bricks, parallel-block topology, gallery coverage tests.
827+
828+
---
829+
830+
11. Бюджет + риски
831+
832+
Бюджет: 8 недель (F-A + F-A.2 + F-B..F-E) для v1 production-ready
833+
Jupyter widget + static demo + CLI runner. Phase 2 опционально через
834+
3-6 месяцев.
644835

645-
Бюджет: 7 недель (F-A..F-E) для v1 production-ready Jupyter widget +
646-
static demo. Phase 2 опционально через 3-6 месяцев.
836+
**Нумерация секций после правок**: §1-9 как раньше, §10 (gallery
837+
coverage), §11 (бюджет+риски, был §10).
647838

648839
**Главный риск**: React Flow DOM ceiling ~1000 nodes. Mitigation:
649840
collapse repeated-layer stacks в один "×N" node (UI-side abstraction);

0 commit comments

Comments
 (0)