@@ -14,7 +14,13 @@ Exa neural + content / Perplexity reasoning Gemini 3.1; Tavily вылетел
14140 . 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:
649840collapse repeated-layer stacks в один " ×N" node (UI-side abstraction);
0 commit comments