File size: 12,943 Bytes
38f1a42 | 1 2 3 4 5 6 7 8 9 10 11 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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | ---
license: apache-2.0
library_name: pytorch
language:
- en
pipeline_tag: text-generation
tags:
- mlp-mixer
- byte-level
- causal-lm
- attention-free
- ccd-mixer
- content-gated-dilated-conv
- tiny-stories
- pretrained-backbone
- micro-language-model
- sub-1m-parameters
model_name: MicroMixer-4-50K-TinyStories
datasets:
- roneneldan/TinyStories
metrics:
- perplexity
---
<div align="center">
<img src="https://raw.githubusercontent.com/llaa33219/MicroMixer-4/main/logo.svg" width="300" alt="MicroMixer-4 Logo"/>
# MicroMixer-4-50K-TinyStories
<img src="https://img.shields.io/badge/Parameters-48%2C684-blue?style=for-the-badge&logo=python&logoColor=white&color=%23007BFF" alt="Parameters"/>
<img src="https://img.shields.io/badge/Architecture-CCD--Mixer-purple?style=for-the-badge&color=%23AE00FF" alt="Architecture"/>
<img src="https://img.shields.io/badge/Stage-Pretrain-green?style=for-the-badge&color=%2300D620" alt="Pretrain"/>
<br/>
<br/>
<table>
<tr>
<td align="center" style="padding: 20px;">
<strong style="color: #007BFF; font-size: 1.2em;">Micro Language Model</strong><br/><em>Attention-Free β’ MLP-Only β’ Byte-Level β’ Content-Gated Dilated Convolution</em>
</td>
</tr>
</table>
[](https://github.com/llaa33219/MicroMixer-4)
</div>
<div style="background: linear-gradient(135deg, #007BFF22, #AE00FF22); padding: 20px; border-radius: 10px; border-left: 4px solid #007BFF;">
## π Overview
**MicroMixer-4-50K-TinyStories** is a **48,684-parameter** pure MLP-Mixer causal language model β **no attention, no recurrence, no SSM** β **pretrained on [TinyStories](https://huggingface.co/datasets/roneneldan/TinyStories)** as part of the MicroMixer-4 **dataset-efficiency comparison study** ([analysis](https://github.com/llaa33219/MicroMixer-4/blob/main/DATASET_COMPARISON_ANALYSIS.md)). TinyStories is a corpus of ~200K short synthetic children's stories (GPT-3.5/4-generated, constrained grammar and vocabulary).
β οΈ This repo is **pretrain-only** β it is **NOT FMSP-fine-tuned**. TinyStories contains free-flowing prose with no `User:`/`Assistant:` dialogue markers, so the FMSP answer-only cross-entropy recipe does not apply (there is no answer region to isolate). What you get is the **raw pretrained backbone** (seed 42, V76 recipe, 3 epochs). It continues stories; it does not answer questions or follow instructions.
The backbone is **V87 Final**, the project's champion CCD-Mixer architecture (the V83-RPG champion frozen and scaled to six budgets). The 50K preset reproduces the champion recipe at its budget.
</div>
## ποΈ Architecture
<div align="center">
```mermaid
graph TD
A[Byte Input] --> B[Embed 256β32 NoPE]
B --> C[CCD-Mixer Block Γ 4]
C --> D[RMSNorm]
D --> E[LM Head Tied with Embed]
E --> F[Byte Output]
subgraph "CCD-Mixer Block"
X[Input 32] --> U["Linear dβ2d β split v, g"]
U --> RP[Full RoPE on v AND g]
RP --> M["Shared-weight dilated conv<br/>dilations 1Β·2Β·4Β·8, k=65"]
M --> G["Per-position 4-way gate<br/>softmax(Linear_dil(x)/Ο)"]
G --> O["W_o(v β g) β zero-init"]
O --> SW[SwiGLU Channel-Mix]
SW --> RM[ReMixerLayer sidecar]
end
style A fill:#007BFF,color:#fff
style F fill:#00D620,color:#fff
style G fill:#AE00FF,color:#fff
style M fill:#FF6600,color:#fff
```
</div>
### Model Configuration
<table>
<tr>
<th style="background-color: #007BFF; color: white;">Parameter</th>
<th style="background-color: #AE00FF; color: white;">Value</th>
</tr>
<tr><td>Hidden Dimension (d_model)</td><td><code>32</code></td></tr>
<tr><td>Number of Blocks</td><td><code>4</code></td></tr>
<tr><td>Token-Mix</td><td><code>GLCTokenMixCCD</code> (content-gated mixture of shared-weight dilated causal conv)</td></tr>
<tr><td>Dilations</td><td><code>(1, 2, 4, 8)</code> β one shared depthwise kernel, zero extra conv params</td></tr>
<tr><td>Depthwise Kernel Size</td><td><code>65</code></td></tr>
<tr><td>RoPE</td><td>Full RoPE on <b>both</b> v and g (V76 "RPG" pattern)</td></tr>
<tr><td>Channel-Mix</td><td><code>SwiGLU</code></td></tr>
<tr><td>Sidecar</td><td><code>ReMixerLayer</code> per block (label_dim 16, pool_heads 4)</td></tr>
<tr><td>Max Sequence Length</td><td><code>1024</code></td></tr>
<tr><td>Vocabulary Size</td><td><code>256</code> (byte-level)</td></tr>
<tr><td>Position Encoding</td><td>RoPE inside token-mix only; no position embedding table</td></tr>
<tr><td>Normalization</td><td><code>RMSNorm</code> (pre-norm)</td></tr>
<tr><td>Output Head</td><td>Tied with input embedding</td></tr>
<tr><td>Zero-Init</td><td><code>W_o</code>, <code>dil_gate</code>, <code>log_Ο</code> β silent at init</td></tr>
</table>
### Core Components
```
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CCD-Mixer Block (Γ4) β
β u = Linear(d β 2d)(x) β
β v, g = u.chunk(2) β
β v = RoPE(v) g = RoPE(g) β full-RoPE (RPG) β
β y_d = CausalDSConv(v, dilation=d) for d β (1,2,4,8) β
β βββ ONE shared depthwise kernel β
β w(t) = softmax(Linear_dil(x)_t / Ο) β per-position β
β v = Ξ£_d w_d(t) Β· y_d(t) time-varying filter β
β out = W_o(v β g) β W_o zero-init β
β then SwiGLU channel-mix + ReMixerLayer sidecar β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
The token-mix is **non-LTI** (time-varying): the per-position gate remixes four dilated views of the same kernel at every byte, which is the mechanism that breaks the periodic-orbit collapse that pure LTI mixers fall into β without attention and without a position table.
---
## π― Generation Examples
<div style="background-color: #FF050515; padding: 15px; border-radius: 8px; border-left: 4px solid #FF6600;">
**Story-continuation probes** (raw text β no `User:/Assistant:` prefix, since TinyStories is a plain LM; greedy decoding, `repetition_penalty=1.2`, `no_repeat_ngram_size=4`, `max_new_tokens=200`):
```
[Prompt] Once upon a time, there was a little girl named Lily.
[Output] She loved to play with her friends. One day, Lily was very happy and saw a big box of the storeβ¦
```
<sub>coherent β on-topic story continuation in the TinyStories register</sub>
```
[Prompt] One day, a boy named Tom found a big red balloon.
[Output] They were very happy and he was so happy. One day, he was so happy to help him and said, "I wanβ¦
```
<sub>coherent β on-topic story continuation in the TinyStories register</sub>
```
[Prompt] The sun was shining and the birds were singing.
[Output] The bird was so happy and said, "I want to see the store with the store with the store with theβ¦
```
<sub>drifts β starts as story but falls into a repetitive loop</sub>
```
[Prompt] A little dog ran into the garden and saw
[Output] a big box of fun. He was so happy and he wanted to see the box and said, "I want to see the beaβ¦
```
<sub>coherent β on-topic story continuation in the TinyStories register</sub>
</div>
---
## π Results
<div style="background-color: #007BFF15; padding: 15px; border-radius: 8px; border-left: 4px solid #007BFF;">
### Pretraining (TinyStories, V76 recipe, 3 epochs)
| Metric | 1 ep | 2 ep | 3 ep |
|--------|------|------|------|
| Val PPL | 2.83 | 2.75 | **2.60** |
AdamW lr 3e-3 Β· WSD (warmup 500) Β· wd 0.01 Β· bs 16 Β· seq 1024 Β· seed 42 Β· plain CE on non-pad bytes.
### MicroMixer-4 TinyStories family (pretrain-only, all sizes)
| Size | Params | 3ep Val PPL |
|------|--------|------------|
| 1M | 996,873 | **1.78** |
| 500K | 491,742 | **1.90** |
| 300K | 292,525 | **2.00** |
| 100K | 95,084 | **2.31** |
| **50K** | 48,684 | **2.60** |
| 10K | 9,666 | **4.06** |
<sub>Pretrain-only family β FMSP-based axes (chatter fluency, full-988 EM, q-relevance, OOD, unanswerable fabrication) are N/A: TinyStories has no `User:/Assistant:` markers, so the answer-only-CE recipe does not apply.</sub>
</div>
---
## π Training Data
<div style="background-color: #00D62015; padding: 15px; border-radius: 8px; border-left: 4px solid #00D620;">
1. **Pretraining**: [TinyStories](https://huggingface.co/datasets/roneneldan/TinyStories) β synthetic short stories generated by GPT-3.5/4 with a constrained vocabulary and simple grammar, ~200K stories sampled, flattened to 1024-byte sequences, 3 epochs. No `User:/Assistant:` dialogue structure.
</div>
---
## π§ Usage
### Files in this repository
- `epoch_{0,1,2}.safetensors` β per-epoch pretrained backbone weights (pickle-free safetensors). **`epoch_2.safetensors` is the final (3rd-epoch) checkpoint.** No FMSP adapter β this is the plain backbone.
### Load and generate (local clone)
```python
import torch
from safetensors.torch import load_file
from src.model_v87_final import MicroMixerV87Final, v87_final_50k
from src.tokenizer import ByteTokenizer
# Clone the code repository first:
# git clone https://github.com/llaa33219/MicroMixer-4.git && cd MicroMixer-4
cfg = v87_final_50k()
model = MicroMixerV87Final(cfg) # plain backbone β NO attach_adapter (pretrain-only)
model.load_state_dict(load_file("epoch_2.safetensors"), strict=True)
model.eval()
tok = ByteTokenizer()
prompt = "Once upon a time, there was a little girl named Lily."
ids = tok.encode(prompt)
if ids and ids[-1] == tok.eos_token_id:
ids = ids[:-1] # ByteTokenizer appends EOS; the prompt must end open
ids = torch.tensor([ids])
with torch.no_grad():
out = model.generate(
ids, max_new_tokens=200,
temperature=0.0, # greedy
repetition_penalty=1.2,
no_repeat_ngram_size=4,
eos_token_id=tok.eos_token_id,
)
print(prompt + tok.decode(out[0].tolist()[len(ids):]))
```
> Note the differences from the FMSP cards: (1) **no `attach_adapter`** β the backbone is loaded
> as-is; (2) the prompt is **raw story text**, not the `User: β¦\n\nAssistant: ` dialogue format.
### Load from Hugging Face Hub (no clone of the weights needed)
```python
import torch
from huggingface_hub import hf_hub_download
from safetensors.torch import load_file
from src.model_v87_final import MicroMixerV87Final, v87_final_50k
REPO = "llaa33219/MicroMixer-4-50K-TinyStories"
cfg = v87_final_50k()
model = MicroMixerV87Final(cfg)
model.load_state_dict(
load_file(hf_hub_download(REPO, "epoch_2.safetensors")), strict=True)
model.eval()
# ... continue a story as above
```
---
## β οΈ Limitations
<div style="background-color: #FF050515; padding: 15px; border-radius: 8px; border-left: 4px solid #FF0505;">
| Limitation | Description |
|------------|-------------|
| **Pretrain-only β no instruction/QA ability** | Not FMSP-fine-tuned; it only continues TinyStories-style prose. It cannot answer questions or follow instructions. |
| **Micro parameters** | 48,684 parameters; capacity is the binding constraint |
| **Knows only TinyStories** | Distribution is synthetic children's stories; no real-world knowledge |
| **Byte-level noise** | 256-vocab byte tokenizer; PPL not comparable to BPE baselines |
| **Research use only** | Architecture/pretraining research artifact, not a production model |
</div>
---
## 𧬠Context
This is the **50K** TinyStories-pretrained arm of the **dataset-efficiency comparison study** in the [MicroMixer-4](https://github.com/llaa33219/MicroMixer-4) project β the pretrain-only third corpus alongside the UltraChat and SmolTalk2 FMSP arms (TinyStories is excluded from the FMSP/eval battery because it has no `User:/Assistant:` markers). Sibling repos: `llaa33219/{MicroMixer-4,MicroT-test1}-{1M..10K}-TinyStories`, plus the UltraChat/SmolTalk2 arms `β¦-{UltraChat,SmolTalk2}` and the discord-pretrained baselines `llaa33219/{MicroMixer-4,MicroT-test1}-{1M..10K}`. Full analysis: [DATASET_COMPARISON_ANALYSIS.md](https://github.com/llaa33219/MicroMixer-4/blob/main/DATASET_COMPARISON_ANALYSIS.md).
---
<div align="center">
[](https://github.com/llaa33219/MicroMixer-4)
<sub>Part of the <a href="https://github.com/llaa33219/MicroMixer-4">MicroMixer-4</a> research project β V87 Final (CCD-Mixer) family, 50K preset, TinyStories pretraining (pretrain-only)</sub>
</div>
|