@@ -732,6 +732,28 @@ UI poсредник: ошибки кода маппит на in-place toast + no
732732 - Example notebook
733733 - JupyterLab + JupyterLite compatibility test
734734
735+ ** Этап F-G — Tokenizer Visualizer screen (1-1.5 недели)**
736+ - Новый React route/tab ` /tokenizer` в Visual Builder
737+ - Runtime: ` @huggingface/tokenizers` (8.3 kB gzip! ) принимает наш
738+ ` tokenizer.json` напрямую
739+ - Fork ` huggingface/transformers.js-examples/the-tokenizer-playground`
740+ ` Token.jsx` component (~30 LoC) как scaffold
741+ - Greenfield слои: round-trip diff с whitespace-sentinel awareness,
742+ special-token registry (6+ hue families: FIM/CODE/CONVERSATION/
743+ DOC_SEP/MTP/Engram), doc_ids overlay (CodeMirror 6 Decoration.mark),
744+ train/eval mask overlay (nanochat conversation render), lossy-
745+ whitespace highlight с tooltip оригинала
746+ - Hover-link pattern из ` dqbd/tiktokenizer` (MIT) — hover token →
747+ highlight все occurrences + byte tooltip
748+ - Новый JSON-RPC endpoint ` tokenizer.encode_visualize` (добавляется
749+ в F-A schema, реализуется как Python wrapper над ` CppTokenizer` )
750+ - Тесты: unit (каждый special class рендерит distinct hue), system
751+ (paste typical training text, verify все ` < SPACE> /< NL> ` visible с
752+ lossy-warn badges; pack 3 docs, verify boundaries shown)
753+ - Можно делать ПАРАЛЛЕЛЬНО с F-C/F-D (после F-A schema lock + F-B
754+ React shell)
755+ - Cм. cppmega-mlx-o0k.7
756+
735757** Этап F-E — JupyterLite/Pyodide static bundle + GH Pages deploy (1 неделя)**
736758 - Pyodide preload ` cppmega_v4` (отделить от MLX runtime)
737759 - GitHub Pages auto-deploy on main commit
@@ -786,6 +808,126 @@ UI poсредник: ошибки кода маппит на in-place toast + no
786808
787809---
788810
811+ 9.5 Tokenizer Visualizer screen (F-G)
812+
813+ Отдельная вкладка/route в Visual Builder для визуализации ** нашего
814+ нестандартного BPE-токенизатора** . Что нестандартного (см.
815+ ` cpp_tokenizer.py:33-100` ):
816+
817+ 1. ** ` < SPACE> ` (46) + ` < NL> ` (47) сентинели** — ` [ \t ]+` и ` [\r\n ]+`
818+ collapse до BPE → round-trip ** lossy** для whitespace runs > 1
819+ 2. ** FIM tokens** — ` < FIM_PREFIX> ` (4), ` < FIM_MIDDLE> ` (5),
820+ ` < FIM_SUFFIX> ` (6), ` < FIM_INSTRUCTION> ` (45)
821+ 3. ** CODE_START** (7) для code-block delineation
822+ 4. ** Custom regex split** — ` \p {N}{1,2}` вместо GPT-4 ` {1,3}`
823+ 5. ** 65,536 fixed vocab** с fail-closed contract validation
824+ 6. ** (nanochat only)** conversation tokens, train/eval mask, AST/symbol-ID
825+ per-token attributes (enriched parquet)
826+ 7. ** doc_ids per-token** assigned during packing (data layer, не tokenizer)
827+
828+ Стек (из 4-агентного research):
829+
830+ - ** Runtime** : ` @huggingface/tokenizers` (tokenizers.js) — ** 8.3 kB
831+ gzip! ** , Apache-2.0, принимает наш ` tokenizer.json` 1:1, exposes
832+ ` encoding.offsets` нативно. ** No WASM нужен** , JupyterLite-friendly.
833+ Fallback: ` tiktoken/lite` WASM (~300-700 KB) если custom BPE ranks.
834+ - ** React scaffold** : fork
835+ ` huggingface/transformers.js-examples/the-tokenizer-playground`
836+ (Apache-2.0, ` Token.jsx` ~ 30 LoC) — готовый Web Worker pattern +
837+ per-token color chips.
838+ - ** Hover-link pattern** : steal из ` dqbd/tiktokenizer` (MIT) — hover
839+ token → highlight все occurrences того же ID + byte-string tooltip.
840+ - ** Doc-packing rendering** : CodeMirror 6 ` Decoration.mark` (handles
841+ 100k+ decorations smooth) — нужно для multi-document packed views.
842+
843+ Greenfield слои (~600 строк новых, не существует ни у одного из 20+
844+ surveyed tools):
845+
846+ 1. ** Round-trip diff** с whitespace-sentinel awareness — стрелка
847+ " input → encode → decode → result" с inline diff подсвечивающим
848+ где ` \n\n\n ` collapsed в ` < NL> ` (lossy warn badge).
849+ 2. ** Special-token registry** с distinct hue families per class
850+ (FIM red-family / CODE blue-family / CONVERSATION violet-family /
851+ DOC_SEP green-family / MTP amber-family / Engram cyan-family).
852+ 3. ** doc_ids overlay** — packed sequence с bracketed regions per doc;
853+ hover doc boundary показывает doc_id + length.
854+ 4. ** Train/eval mask overlay** (nanochat conversation render — GREEN
855+ supervised, RED non-supervised).
856+ 5. ** Lossy-whitespace highlight** — token с sentinel показывает
857+ оригинальный raw run через hover tooltip.
858+ 6. ** Per-token AST depth / symbol-ID badges** (nanochat enriched
859+ parquet, опционально).
860+
861+ API endpoint (новый в F-A JSON schema):
862+
863+ ` ` ` json
864+ {
865+ " method" : " tokenizer.encode_visualize" ,
866+ " params" : {
867+ " text" : " def foo():\n\n\n return 1\n" ,
868+ " tokenizer_path" : " cppmega_mlx/tokenizer/tokenizer.json" ,
869+ " show" : [" offsets" , " specials" , " doc_ids" , " round_trip" , " mask" ]
870+ }
871+ }
872+ ` ` `
873+
874+ ` ` ` json
875+ {
876+ " result" : {
877+ " token_ids" : [4, 1234, 567, 47, 7, 89, ...],
878+ " offsets" : [[0,0], [0,3], [4,7], [11,14], [14,14], [15,21], ...],
879+ " special_classes" : [
880+ {" id" : 4, " name" : " <FIM_PREFIX>" , " class" : " fim" },
881+ {" id" : 47, " name" : " <NL>" , " class" : " whitespace_sentinel" ,
882+ " original_run" : " \n\n\n" , " lossy" : true},
883+ {" id" : 7, " name" : " <CODE_START>" , " class" : " code" }
884+ ],
885+ " doc_ids" : [0, 0, 0, 0, 0, 1, 1, 1, ...],
886+ " round_trip" : " def foo():\n return 1\n" ,
887+ " round_trip_diff" : {
888+ " equal" : false,
889+ " diffs" : [{" input_span" : [11,14], " result_span" : [11,12],
890+ " reason" : " <NL>(47) sentinel collapsed \\ n\\ n\\ n → \\ n" }]
891+ },
892+ " mask" : [1, 1, 1, 0, 0, 1, 1, 1, ...]
893+ }
894+ }
895+ ` ` `
896+
897+ UI layout вкладки:
898+
899+ ```
900+ ┌─────────────────────────────────────────────────────────────────────┐
901+ │ Tab: Architecture / Loss / Optim / [ Tokenizer] / Sharding / Gotchas │
902+ ├─────────────────────────────────────────────────────────────────────┤
903+ │ ┌─ Input ─────────────────────┐ ┌─ Tokenizer ──────────────────┐ │
904+ │ │ <textarea editable > │ │ tokenizer.json: [ ▼ load] │ │
905+ │ │ def foo(): │ │ Vocab: 65,536 │ │
906+ │ │ │ │ Special class filters: │ │
907+ │ │ return 1 │ │ [ ✓ FIM] [ ✓ CODE] [ ✓ NL/SPACE] │
908+ │ │ │ │ [ ✓ DOC] [ ✓ MTP] [ ✓ Engram] │ │
909+ │ └─────────────────────────────┘ └──────────────────────────────┘ │
910+ │ ┌─ Tokens (147) ────────────────────────────────────────────────┐ │
911+ │ │ ░░░def░░░ ░░░ foo░░ ▒(▒ ▒)▒ ▒:▒ █<NL >█ █<NL >█ ░░░return░░░ │ │
912+ │ │ ░░░ 1░░░ ▒<EOS >▒ │ │
913+ │ │ (hover any token → tooltip: id=1234, bytes=" foo", class=word)│ │
914+ │ └───────────────────────────────────────────────────────────────┘ │
915+ │ ┌─ Round-trip ──────────────────────────────────────────────────┐ │
916+ │ │ Input: "def foo():\n\n\n return 1\n" [ 147 chars] │ │
917+ │ │ Output: "def foo():\n return 1\n" [ 145 chars] │ │
918+ │ │ ⚠ LOSSY: 1 collapse event at char 11 [ view diff] │ │
919+ │ └───────────────────────────────────────────────────────────────┘ │
920+ │ ┌─ Doc packing ─────────────────────────────────────────────────┐ │
921+ │ │ [ doc_0──────────] [ doc_1────────────── ] [ doc_2──────] (3 docs) │ │
922+ │ │ CodeMirror with vertical brackets per doc boundary │ │
923+ │ └───────────────────────────────────────────────────────────────┘ │
924+ └─────────────────────────────────────────────────────────────────────┘
925+ ```
926+
927+ См. F-G ticket (`cppmega-mlx-o0k.7`).
928+
929+ ---
930+
78993110. Покрытие Раschka LLM Architecture Gallery (71 модель)
790932
791933Прогнал список галереи против наших 22 bricks + 12 presets.
@@ -829,9 +971,10 @@ bricks, parallel-block topology, gallery coverage tests.
829971
83097211. Бюджет + риски
831973
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 месяцев.
974+ Бюджет: 9-9.5 недель (F-A + F-A.2 + F-B..F-E + F-G) для v1 production-ready
975+ Jupyter widget + static demo + CLI runner + tokenizer visualizer.
976+ F-G можно делать параллельно с F-C/F-D, поэтому wall-clock остаётся
977+ ~8 недель. Phase 2 опционально через 3-6 месяцев.
835978
836979**Нумерация секций после правок**: §1-9 как раньше, §10 (gallery
837980coverage), §11 (бюджет+риски, был §10).
0 commit comments