Text Generation
Transformers
Safetensors
English
gpt-s2.5
tiny
tiny-lm
tiny-model
slm
small-language-model
from-scratch
gpt
gqa
swiglu
rope
rmsnorm
cpu-trained
Instructions to use Compactbot/compacttest-5m with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Compactbot/compacttest-5m with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Compactbot/compacttest-5m")# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("Compactbot/compacttest-5m", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Compactbot/compacttest-5m with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Compactbot/compacttest-5m" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Compactbot/compacttest-5m", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/Compactbot/compacttest-5m
- SGLang
How to use Compactbot/compacttest-5m with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "Compactbot/compacttest-5m" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Compactbot/compacttest-5m", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "Compactbot/compacttest-5m" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Compactbot/compacttest-5m", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use Compactbot/compacttest-5m with Docker Model Runner:
docker model run hf.co/Compactbot/compacttest-5m
Make card self-contained after rename: fold in the full eval table (II=0.032) and rename note; the original gpt-s2.5-5m repo is being deleted
Browse files
README.md
CHANGED
|
@@ -17,69 +17,144 @@ tags:
|
|
| 17 |
- cpu-trained
|
| 18 |
library_name: transformers
|
| 19 |
metrics:
|
|
|
|
| 20 |
- accuracy
|
| 21 |
-
model-index:
|
| 22 |
-
- name: HellaSwag
|
| 23 |
-
type: text-generation
|
| 24 |
-
results: []
|
| 25 |
---
|
| 26 |
|
| 27 |
-
# compacttest-5m
|
| 28 |
|
| 29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
-
> This repo
|
| 32 |
-
>
|
| 33 |
-
>
|
|
|
|
|
|
|
|
|
|
| 34 |
|
| 35 |
-
##
|
| 36 |
|
| 37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
- **Trained:** on CPU, ~94M TinyStories tokens, cosine LR schedule with warmup.
|
| 45 |
|
| 46 |
-
##
|
| 47 |
|
| 48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
|
| 50 |
```python
|
| 51 |
import torch
|
| 52 |
from model import Model
|
|
|
|
| 53 |
|
| 54 |
m = Model()
|
| 55 |
-
|
| 56 |
-
sd = load_file("model.safetensors")
|
| 57 |
-
m.load_state_dict(sd)
|
| 58 |
m.eval()
|
| 59 |
|
| 60 |
# greedy generation
|
| 61 |
with torch.no_grad():
|
| 62 |
-
x = torch.tensor([[1]])
|
| 63 |
for _ in range(60):
|
| 64 |
logits = m(x[:, -512:])[:, -1, :]
|
| 65 |
x = torch.cat([x, logits.argmax(-1, keepdim=True)], dim=1)
|
| 66 |
```
|
| 67 |
|
| 68 |
-
|
|
|
|
|
|
|
| 69 |
|
| 70 |
-
|
| 71 |
-
prose under greedy decoding but degrades noticeably under sampling. That is the
|
| 72 |
-
expected behaviour at this scale, not a bug.
|
| 73 |
-
- **Intelligence index:** 0.032 (see the original card for the full eval breakdown).
|
| 74 |
-
- It is a reference build demonstrating that a 5M-param from-scratch subword LM is
|
| 75 |
-
trainable and coherent on CPU. It is not a chat model.
|
| 76 |
|
| 77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
|
|
|
|
|
| 17 |
- cpu-trained
|
| 18 |
library_name: transformers
|
| 19 |
metrics:
|
| 20 |
+
- perplexity
|
| 21 |
- accuracy
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
---
|
| 23 |
|
| 24 |
+
# compacttest-5m — 5.11M-param subword LM (from scratch)
|
| 25 |
|
| 26 |
+
A small subword language model trained **from scratch on CPU**, built to the
|
| 27 |
+
"GPT-X2.5" style spec requested in the [model-requests](https://huggingface.co/Compactbot/model-requests) board
|
| 28 |
+
(`gpt-S2.5-5m`). It is a deliberately minimal, self-contained GPT-2-style
|
| 29 |
+
transformer — small enough to fit on a floppy disk, honest about what it can
|
| 30 |
+
and cannot do.
|
| 31 |
|
| 32 |
+
> **Renamed.** This repo was originally published as
|
| 33 |
+
> [`Compactbot/gpt-s2.5-5m`](https://huggingface.co/Compactbot/gpt-s2.5-5m) and
|
| 34 |
+
> renamed to `compacttest-5m` at the request of @Datdanboi25. Weights, config
|
| 35 |
+
> and architecture are **byte-identical** to the original (verified by SHA-256
|
| 36 |
+
> of `model.safetensors`); the original repo has been deleted, so this is now
|
| 37 |
+
> the single canonical copy.
|
| 38 |
|
| 39 |
+
## Numbers (verified against the artifact)
|
| 40 |
|
| 41 |
+
| | |
|
| 42 |
+
|---|---|
|
| 43 |
+
| **Parameters** | **5,114,112** (exact; 38 tensors, F32) |
|
| 44 |
+
| Vocab | 8,192 (byte-level BPE) |
|
| 45 |
+
| Layers | 4 |
|
| 46 |
+
| Hidden | 256 |
|
| 47 |
+
| Heads | 8 q / 2 kv (GQA 4:1), head_dim 32 |
|
| 48 |
+
| FFN | SwiGLU, intermediate 768 |
|
| 49 |
+
| Norm | RMSNorm (eps 1e-6), pre-norm |
|
| 50 |
+
| Position | RoPE (base 10000), max 512 |
|
| 51 |
+
| Head | weight-tied (`tok.weight` reused as `lm_head`; no separate head tensor) |
|
| 52 |
+
| Biases | none |
|
| 53 |
+
| Checkpoint | 20,459,896 bytes = 8 + header + 5,114,112 × 4 (exact) |
|
| 54 |
+
|
| 55 |
+
The parameter count above is the **stored** element count in
|
| 56 |
+
`model.safetensors` (parsed from the file header), not a card claim. Because
|
| 57 |
+
the head is tied, stored == unique.
|
| 58 |
+
|
| 59 |
+
## Evaluations (measured, 2026-09-22)
|
| 60 |
+
|
| 61 |
+
Zero-shot loglikelihood accuracy, **Open SLM Leaderboard formula** (the same
|
| 62 |
+
one used for the published values — I reproduced all 10 of them to the cent
|
| 63 |
+
before running this, so the method is reproducible): per-task accuracy,
|
| 64 |
+
chance-normalized as `(acc − chance) / (100 − chance)`, then weighted.
|
| 65 |
+
500 items per task.
|
| 66 |
+
|
| 67 |
+
**Intelligence Index = 0.032**
|
| 68 |
+
|
| 69 |
+
| Task | Acc | Chance | Chance-norm |
|
| 70 |
+
|---|---|---|---|
|
| 71 |
+
| HellaSwag | 28.2% (141/500) | 25% | +0.043 |
|
| 72 |
+
| ARC-Easy | 26.8% (134/500) | 25% | — |
|
| 73 |
+
| ARC-Challenge | 21.6% (108/500) | 25% | — |
|
| 74 |
+
| → combined ARC (mean) | 24.2% | 25% | −0.011 |
|
| 75 |
+
| PIQA | 53.2% (266/500) | 50% | +0.064 |
|
| 76 |
+
|
| 77 |
+
II = (1.00·0.043 + 1.00·(−0.011) + 1.00·0.064) / 3.00 = **0.032**
|
| 78 |
+
|
| 79 |
+
Notes on the method:
|
| 80 |
+
- **ArithMark-3 was not available** (`arithmetic/ArithMark-3` is not
|
| 81 |
+
accessible on the Hub right now), so the 3-task formula (weights 1/1/1,
|
| 82 |
+
sum 3.00) was used instead of the full 4-task one (0.65 weight, sum 3.65).
|
| 83 |
+
If ArithMark-3 comes back I will re-run and update this section.
|
| 84 |
+
- Datasets: `Rowan/hellaswag` (validation), `allenai/ai2_arc`
|
| 85 |
+
ARC-Easy + ARC-Challenge (test), `gimmaru/piqa` (validation).
|
| 86 |
+
- The harness code is recorded verbatim against the result in the eval store.
|
| 87 |
|
| 88 |
+
**Interpretation:** this is what a 5M-param model actually gets — at or just
|
| 89 |
+
above chance on commonsense and reasoning, nowhere near the ~25 of the 135M
|
| 90 |
+
models. That is the honest expectation for 5M params on ~94M tokens of
|
| 91 |
+
stories, not a tuning failure. The index is a reproducible lower-bound data
|
| 92 |
+
point for the GPT-X lineage at the 5M scale, not a claim of quality.
|
|
|
|
| 93 |
|
| 94 |
+
## What it is and is not good at
|
| 95 |
|
| 96 |
+
- **Greedy decoding (temp=0) is coherent.** From a `<bos>` seed it produces
|
| 97 |
+
grammatical, TinyStories-style prose (see sample below). This is the intended
|
| 98 |
+
operating point for a 5M model.
|
| 99 |
+
- **Aggressive sampling is degenerate.** At temp 0.7 / top_p 0.5 it collapses
|
| 100 |
+
into `<eos>Ä was<bos>!`-style token loops — the classic small-model tail-noise
|
| 101 |
+
failure. If you sample, use a low temperature (~0.2–0.3) and a high top_p
|
| 102 |
+
(~0.9); even then it is fragile.
|
| 103 |
+
- **It is a toy.** 5M parameters sees ~4× more text per step than a char model
|
| 104 |
+
but is still far below the scale where benchmark scores are meaningful.
|
| 105 |
+
Perplexity on held-out TinyStories text is ~15.6 (val). The measured
|
| 106 |
+
benchmark scores above are at/near chance, as expected. This model is a
|
| 107 |
+
demonstration of a clean, from-scratch subword pipeline, not a benchmark
|
| 108 |
+
entry.
|
| 109 |
+
|
| 110 |
+
### Sample (greedy, temp=0, from `<bos>`)
|
| 111 |
+
|
| 112 |
+
> Once upon a time, there was a little girl named Lily. She loved to play
|
| 113 |
+
> outside in the sun. One day, she saw a big, scary dog. The dog was scared
|
| 114 |
+
> and wanted to play with Lily. Lily went to the dog and said, "Hello, dog!
|
| 115 |
+
> Can...
|
| 116 |
+
|
| 117 |
+
## How to run
|
| 118 |
+
|
| 119 |
+
This is **not** a transformers-native architecture. Load it with the included
|
| 120 |
+
`model.py`:
|
| 121 |
|
| 122 |
```python
|
| 123 |
import torch
|
| 124 |
from model import Model
|
| 125 |
+
from safetensors.torch import load_file
|
| 126 |
|
| 127 |
m = Model()
|
| 128 |
+
m.load_state_dict(load_file("model.safetensors"))
|
|
|
|
|
|
|
| 129 |
m.eval()
|
| 130 |
|
| 131 |
# greedy generation
|
| 132 |
with torch.no_grad():
|
| 133 |
+
x = torch.tensor([[1]]) # 1 = <bos>
|
| 134 |
for _ in range(60):
|
| 135 |
logits = m(x[:, -512:])[:, -1, :]
|
| 136 |
x = torch.cat([x, logits.argmax(-1, keepdim=True)], dim=1)
|
| 137 |
```
|
| 138 |
|
| 139 |
+
Tokenization: `tokenizer.json` is a standard BPE vocab (8192 tokens,
|
| 140 |
+
byte-level). It is **not** a HuggingFace `PreTrainedTokenizerFast` file — load
|
| 141 |
+
the `model.vocab` mapping directly (see `model.py` for the decode helper).
|
| 142 |
|
| 143 |
+
## Training
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
|
| 145 |
+
- **Data:** ~94M tokens of TinyStories (byte-level BPE, 8192 vocab).
|
| 146 |
+
- **Hardware:** CPU-only (32 cores, no GPU). ~5000 steps, batch 32×512.
|
| 147 |
+
- **Schedule:** linear warmup (200) → cosine decay, peak 3e-4, min 3e-5.
|
| 148 |
+
- **Checkpoint:** best validation perplexity (val ppl ~15.6 on 2M held-out
|
| 149 |
+
tokens).
|
| 150 |
+
- **Reproducibility:** seed 42. The training script is available on request;
|
| 151 |
+
this repo ships the architecture (`model.py`) and weights only.
|
| 152 |
|
| 153 |
+
## Honest caveats
|
| 154 |
+
|
| 155 |
+
- Trained on CPU; throughput is a hardware artifact, not a model property, so
|
| 156 |
+
I am not reporting tokens/sec.
|
| 157 |
+
- The model is small on purpose. Treat it as a reference implementation of a
|
| 158 |
+
clean GQA+SwiGLU+RoPE+RMSNorm subword GPT at the ~5M scale, not as a
|
| 159 |
+
competitive language model.
|
| 160 |
+
- Sampling quality is the weak spot; use greedy for coherent output.
|