--- 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 ---
MicroMixer-4 Logo # MicroMixer-4-50K-TinyStories Parameters Architecture Pretrain

Micro Language Model
Attention-Free β€’ MLP-Only β€’ Byte-Level β€’ Content-Gated Dilated Convolution
[![GitHub](https://img.shields.io/badge/GitHub-MicroMixer--4-blue?style=for-the-badge&logo=github&color=%23007BFF)](https://github.com/llaa33219/MicroMixer-4)
## πŸ“‹ 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.
## πŸ—οΈ Architecture
```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
dilations 1Β·2Β·4Β·8, k=65"] M --> G["Per-position 4-way gate
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 ```
### Model Configuration
Parameter Value
Hidden Dimension (d_model)32
Number of Blocks4
Token-MixGLCTokenMixCCD (content-gated mixture of shared-weight dilated causal conv)
Dilations(1, 2, 4, 8) β€” one shared depthwise kernel, zero extra conv params
Depthwise Kernel Size65
RoPEFull RoPE on both v and g (V76 "RPG" pattern)
Channel-MixSwiGLU
SidecarReMixerLayer per block (label_dim 16, pool_heads 4)
Max Sequence Length1024
Vocabulary Size256 (byte-level)
Position EncodingRoPE inside token-mix only; no position embedding table
NormalizationRMSNorm (pre-norm)
Output HeadTied with input embedding
Zero-InitW_o, dil_gate, log_Ο„ β€” silent at init
### 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
**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… ``` coherent β€” on-topic story continuation in the TinyStories register ``` [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… ``` coherent β€” on-topic story continuation in the TinyStories register ``` [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… ``` drifts β€” starts as story but falls into a repetitive loop ``` [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… ``` coherent β€” on-topic story continuation in the TinyStories register
--- ## πŸ“Š Results
### 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** | 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.
--- ## πŸ“š Training Data
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.
--- ## πŸ”§ 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
| 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 |
--- ## 🧬 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). ---
[![GitHub](https://img.shields.io/badge/Back_to_Repository-MicroMixer--4-blue?style=for-the-badge&logo=github&color=%23007BFF)](https://github.com/llaa33219/MicroMixer-4) Part of the MicroMixer-4 research project β€” V87 Final (CCD-Mixer) family, 50K preset, TinyStories pretraining (pretrain-only)