model card overhaul
Browse files
README.md
CHANGED
|
@@ -1,64 +1,130 @@
|
|
| 1 |
---
|
|
|
|
|
|
|
| 2 |
license: apache-2.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
datasets:
|
| 4 |
- roneneldan/TinyStories
|
| 5 |
-
language:
|
| 6 |
-
- en
|
| 7 |
pipeline_tag: text-generation
|
| 8 |
-
tags:
|
| 9 |
-
- ASCII
|
| 10 |
-
- BINARY
|
| 11 |
-
- RNN
|
| 12 |
---
|
| 13 |
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
language:
|
| 3 |
+
- en
|
| 4 |
license: apache-2.0
|
| 5 |
+
tags:
|
| 6 |
+
- text-generation
|
| 7 |
+
- rnn
|
| 8 |
+
- gru
|
| 9 |
+
- char-level
|
| 10 |
+
- ascii
|
| 11 |
+
- binary
|
| 12 |
+
- tiny-stories
|
| 13 |
+
- pytorch
|
| 14 |
datasets:
|
| 15 |
- roneneldan/TinyStories
|
|
|
|
|
|
|
| 16 |
pipeline_tag: text-generation
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
---
|
| 18 |
|
| 19 |
+
# Notio-3.7M-RNN-v1
|
| 20 |
+
|
| 21 |
+
A deliberately minimal **char-level language model** (3.7M params, 2-layer GRU) trained on TinyStories.
|
| 22 |
+
Notio's core idea: the model learns **only the binary u8 token-id stream** — all human-readable
|
| 23 |
+
"english/symbols" rendering happens at runtime through a decoder that maps special tags
|
| 24 |
+
(`<spc>`, `<nwl>`, `<bos>`, `<eos>`...) to their effects and drops them from display.
|
| 25 |
+
|
| 26 |
+
> **Status:** v1 training in progress (27,000-step cosine run on a single GTX 1660 SUPER).
|
| 27 |
+
> Milestone checkpoints uploaded: `notio1ksteps.pt`, `notio5k.pt`, `notio10k.pt`.
|
| 28 |
+
> Card reflects step ~11,000 and will be updated at completion.
|
| 29 |
+
|
| 30 |
+
## Design
|
| 31 |
+
|
| 32 |
+
- **Vocabulary:** 109 tokens — 8 specials + 94 printable ASCII + 7 smart punctuation.
|
| 33 |
+
Every token id fits in **one byte**, so the entire corpus is a plain u8 stream.
|
| 34 |
+
- **Boundary tags:** each story is wrapped `<bos> … <nwl><eos>`; whitespace inside the stream
|
| 35 |
+
is explicit (`<spc>`, `<nwl>`, `<tab>`).
|
| 36 |
+
- **Runtime decoder:** tags map to effects at decode time (`<nwl>`→newline, `<spc>`→space,
|
| 37 |
+
`<bos>/<eos>/<pad>/<msk>`→dropped). Tags are data in the stream, never shown to humans.
|
| 38 |
+
|
| 39 |
+
## Architecture
|
| 40 |
+
|
| 41 |
+
| component | detail |
|
| 42 |
+
|---|---|
|
| 43 |
+
| embedding | wte (109×512) + wpe (1024×512) |
|
| 44 |
+
| core | 2 × GRU blocks, d_model=512, pre-LayerNorm + residual |
|
| 45 |
+
| head | LayerNorm + lm_head (109-way), **weights tied to wte** |
|
| 46 |
+
| total params | **3,735,040** (fp32, ~15 MB weights) |
|
| 47 |
+
| context | block_size 1024, **stateful truncated BPTT** (k1 = k2 = 1024) |
|
| 48 |
+
|
| 49 |
+
The stack is modular: layer 0 (data) → layer 1 (embedding) → 2× layer 2 (GRU block) → layer 11 (head).
|
| 50 |
+
A transformer-block variant exists in the repo and can be swapped in without touching other layers.
|
| 51 |
+
|
| 52 |
+
## Data
|
| 53 |
+
|
| 54 |
+
- **roneneldan/TinyStories** (TinyStoriesV2-GPT4-train), cleaned and filtered to stories
|
| 55 |
+
containing only in-vocab characters: **2,118,989 stories**.
|
| 56 |
+
- Char-level u8 id stream: **1,799,636,685 train ids / 95,696,324 val ids** (95/5,
|
| 57 |
+
split on a story boundary — train ends `<eos>`, val starts `<bos>`, concat hash-verified).
|
| 58 |
+
- Pipeline: tag → purge → tokenize; every stage parallelized and byte-exact verified
|
| 59 |
+
(sha256 manifest, tokenizer round-trip `ids identical: True`, `display identical: True`).
|
| 60 |
+
|
| 61 |
+
## Training
|
| 62 |
+
|
| 63 |
+
| hyperparameter | value |
|
| 64 |
+
|---|---|
|
| 65 |
+
| optimizer | AdamW, grad-clip 1.0 |
|
| 66 |
+
| schedule | lr 4e-4, warmup 500 steps, cosine → 4e-5 over 27k steps |
|
| 67 |
+
| batch | B=32, T=1024 (32,768 tokens/step) |
|
| 68 |
+
| BPTT | gradients truncated per 1024-window, RNN state carried & detached, reset only at sweep end |
|
| 69 |
+
| hardware | single GTX 1660 SUPER (6 GB), ~105k tok/s, ~2.3 h/run |
|
| 70 |
+
| checkpoints | every 1,000 steps: train/val loss, lr, weights, + 2 sampled stories (resumable) |
|
| 71 |
+
|
| 72 |
+
### Training progress
|
| 73 |
+
|
| 74 |
+
| step | train loss | val loss | sample quality |
|
| 75 |
+
|---|---|---|---|
|
| 76 |
+
| 1,000 | 0.910 | 0.930 | mostly-correct words, grammar errors |
|
| 77 |
+
| 3,000 | 0.756 | 0.803 | real story skeleton, semantic drift |
|
| 78 |
+
| 5,000 | 0.692 | 0.768 | plot beats + dialogue, entity drift |
|
| 79 |
+
| 7,000 | 0.708 | 0.740 | vocabulary expanding, still dreamy |
|
| 80 |
+
| 10,000 | 0.683 | 0.719 | clean grammar, occasional noun swaps |
|
| 81 |
+
| 11,000 | ~0.70 | **0.714** | **first story holding its protagonist end-to-end** |
|
| 82 |
+
|
| 83 |
+
## Sample output
|
| 84 |
+
|
| 85 |
+
Step 11,000, temperature 0.9, prompted with `<bos>`:
|
| 86 |
+
|
| 87 |
+
> Once upon a time, there was a young boy named Timmy. Timmy loved to play outside with his
|
| 88 |
+
> little bird. One day, Timmy started to rain, and his doggy came by. He waited until his mommy
|
| 89 |
+
> finally back away and they became friends. They had fun playing together
|
| 90 |
+
|
| 91 |
+
(Remaining errors at this stage: occasional subject swaps — "Timmy started to rain" — and
|
| 92 |
+
invented words. Generation stops at `<eos>` once the model emits it.)
|
| 93 |
+
|
| 94 |
+
## Usage
|
| 95 |
+
|
| 96 |
+
Checkpoints embed the model config (load with `weights_only=False`). Repo tools:
|
| 97 |
+
`src/sampler.py` (load/generate/decode) and `src/complete.py` (CLI).
|
| 98 |
+
|
| 99 |
+
```bash
|
| 100 |
+
# CLI: prompt in natural text, N completions, temperature/top-k control
|
| 101 |
+
python3 complete.py "Once upon a time, there was" \
|
| 102 |
+
--checkpoint notio10k.pt --n 3 --temp 0.9 --top-k 40 --max-tokens 256
|
| 103 |
+
```
|
| 104 |
+
|
| 105 |
+
```python
|
| 106 |
+
import sys
|
| 107 |
+
sys.path.insert(0, "path/to/repo") # repo root: notio.py, complete.py, sampler.py
|
| 108 |
+
from sampler import load_model, encode_prompt, generate, ids_to_display
|
| 109 |
+
|
| 110 |
+
model, device, ck = load_model("notio10k.pt")
|
| 111 |
+
ids = generate(model, device, encode_prompt("Once upon a time"),
|
| 112 |
+
max_tokens=256, temperature=0.9, top_k=0)
|
| 113 |
+
print(ids_to_display(ids)) # human text; boundary tags dropped/mapped
|
| 114 |
+
```
|
| 115 |
+
|
| 116 |
+
## Verification scoreboard
|
| 117 |
+
|
| 118 |
+
- Data files: sha256 manifest check (all OK)
|
| 119 |
+
- train/val split: concat hash == source hash, boundary-aligned
|
| 120 |
+
- Tokenizer: full-corpus round-trip byte-exact (ids + display)
|
| 121 |
+
- BPTT: truncation (detached state is a graph leaf), statefulness, and tape continuity formally asserted
|
| 122 |
+
- GRU vs LSTM bake-off at equal settings: LSTM −1.5% loss, GRU +14% throughput → GRU chosen
|
| 123 |
+
|
| 124 |
+
## Limitations
|
| 125 |
+
|
| 126 |
+
- Char-level: occasional misspellings and invented words (e.g. "spaceshimane")
|
| 127 |
+
- Small capacity: dream-logic entity swaps persist at this scale ("a small birthday who loved to shiver")
|
| 128 |
+
- Occasionally repeats loops near low temperature; sample with temperature/top-k
|
| 129 |
+
- Trained on synthetic GPT-4-generated children's stories — style is narrow and young-reader oriented
|
| 130 |
+
- English only, 109-token fixed vocabulary
|