Skip to content

Commit 13d9514

Browse files
committed
docs(VisualBuilderPlan): add §9.5 Tokenizer Visualizer screen + F-G stage
New §9.5 Tokenizer Visualizer screen — based on 4-agent research scan (1 code-extract across 3 repos + Brave/Exa/Perplexity deep web research). Documents our non-standard BPE surface (cpp_tokenizer.py:33-100): - <SPACE>(46) / <NL>(47) whitespace sentinels (lossy round-trip) - FIM tokens (4/5/6/45) + CODE_START (7) - Custom regex split (\p{N}{1,2} vs GPT-4 {1,3}) - 65,536 fixed vocab + fail-closed contract validation - nanochat extras: conversation tokens, train/eval mask, AST/symbol-ID per-token attributes from enriched parquet - doc_ids per-token from packing layer Component stack picks (from web research): - Runtime: @huggingface/tokenizers (tokenizers.js) — 8.3 kB gzip, Apache-2.0, accepts our tokenizer.json 1:1, exposes encoding.offsets natively. NO WASM needed, JupyterLite-friendly trivially. - React scaffold: fork huggingface/transformers.js-examples/ the-tokenizer-playground Token.jsx (~30 LoC) - Hover-link pattern: from dqbd/tiktokenizer (MIT) — hover token → highlight all occurrences + byte tooltip - Doc-packing rendering: CodeMirror 6 Decoration.mark (handles 100k+ decorations smoothly) - Fallback runtime: tiktoken/lite WASM (~300-700 KB) for custom BPE ranks paths Greenfield slots (~600 LoC, not solved by any of 20+ surveyed tools): 1. Round-trip diff with whitespace-sentinel awareness 2. Special-token registry с 6+ hue families 3. doc_ids overlay (multi-document packing) 4. Train/eval mask overlay (nanochat) 5. Lossy-whitespace highlight (tooltip с оригиналом) 6. Per-token AST depth / symbol-ID badges (опционально) New JSON-RPC endpoint: tokenizer.encode_visualize (added to F-A schema, implemented as Python wrapper over CppTokenizer). Implementation: - F-G ticket cppmega-mlx-o0k.7 created under Visual Builder GUI epic - Can be done in PARALLEL with F-C/F-D (depends only on F-A schema + F-B React shell) - Wall-clock budget remains ~8 weeks (parallel execution) Updated §11 budget: 9-9.5 weeks effort (was 8); wall-clock ~8 unchanged due to parallelism.
1 parent ad0f19e commit 13d9514

1 file changed

Lines changed: 146 additions & 3 deletions

File tree

VisualBuilderPlan.md

Lines changed: 146 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
789931
10. Покрытие Раschka LLM Architecture Gallery (71 модель)
790932
791933
Прогнал список галереи против наших 22 bricks + 12 presets.
@@ -829,9 +971,10 @@ bricks, parallel-block topology, gallery coverage tests.
829971
830972
11. Бюджет + риски
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
837980
coverage), §11 (бюджет+риски, был §10).

0 commit comments

Comments
 (0)