|
Download README.md from brkdrd/simloop: direct link, hf CLI and curl.
- Browser
- Download file 3.24 kB
-
https://huggingface.co/brkdrd/simloop/resolve/main/README.md
- Command line
-
hf download hf://brkdrd/simloop/README.md
-
curl -L -o README.md https://huggingface.co/brkdrd/simloop/resolve/main/README.md
3.24 kB
| license: apache-2.0 | |
| datasets: | |
| - HuggingFaceFW/fineweb | |
| language: | |
| - en | |
| library_name: pytorch | |
| tags: | |
| - looped-transformer | |
| - weight-tying | |
| - recurrent-depth | |
| - small-language-model | |
| # SimLoop 1+loop x1+1 (10.0M) | |
| A **looped** (weight-tied recurrent) Qwen3-style transformer trained from | |
| scratch on FineWeb under a hard budget of **<= 10M parameters** and | |
| **<= 100M training tokens**. | |
| One middle block is applied **K = 1** times; the layers around it are | |
| ordinary unlooped layers: | |
| ``` | |
| embed -> [1 layer] -> ( 1 looped layer ) x K -> [1 layer] -> RMSNorm -> tied head | |
| ``` | |
| | | | | |
| |---|---| | |
| | parameters | **9,962,496** (incl. embeddings, input/output tied) | | |
| | d_model / d_mlp | 384 / 720 | | |
| | heads (GQA) | 6 query / 2 key-value, head_dim 64 | | |
| | context | 512 tokens | | |
| | vocabulary | 16,384 byte-level BPE trained on FineWeb | | |
| | training tokens | 60,014,592 | | |
| | primitives | RMSNorm, RoPE, SwiGLU, GQA, QK-norm | | |
| ## Results | |
| | k | CE (nats) | perplexity | bits-per-byte | | |
| |---|---|---|---| | |
| | 0 | 5.4088 | 223.35 | 1.8913 | | |
| | 1 | 4.3966 | 81.17 | 1.5374 **<- best** | | |
| | 2 | 4.5995 | 99.43 | 1.6083 | | |
| | 3 | 4.9413 | 139.95 | 1.7278 | | |
| | 4 | 5.2659 | 193.62 | 1.8413 | | |
| | 5 | 5.5476 | 256.63 | 1.9399 | | |
| | 6 | 5.7900 | 327.01 | 2.0246 | | |
| | 7 | 6.0000 | 403.41 | 2.0980 | | |
| | 8 | 6.1835 | 484.69 | 2.1622 | | |
| | 9 | 6.3452 | 569.77 | 2.2188 | | |
| | 10 | 6.4887 | 657.65 | 2.2689 | | |
| | 11 | 6.6166 | 747.41 | 2.3137 | | |
| | 12 | 6.7313 | 838.20 | 2.3537 | | |
| Reference points on the same validation split: a context-free **unigram** model scores CE 7.5476 (ppl 1896.10); **uniform** over the vocabulary scores CE 9.7041. | |
| `k` is the number of applications of the looped block at inference. The model | |
| is weight-tied, so **any k can be run**; the table is a single checkpoint | |
| evaluated at every depth. | |
| **Measured behaviour:** TRAINED UNLOOPED (K=1): the k>1 rows show how a model trained at one application behaves when looped anyway, not whether looping pays. | |
| - first application of the looped block buys **+1.0122** nats (k=0 -> k=1) | |
| - all further applications buy **+0.0000** nats (k=1 -> k=1) | |
| ## Usage | |
| ```python | |
| import torch | |
| from simloop.stack import StackConfig, StackedLoop | |
| ck = torch.load("model.pt", map_location="cpu", weights_only=False) | |
| model = StackedLoop(StackConfig(**ck["model_cfg"])) | |
| model.load_state_dict(ck["model"]); model.eval() | |
| ids = torch.tensor([[1, 2, 3]]) # from tokenizer.json | |
| logits = model(ids, K=1) # try other K: the block is tied | |
| ``` | |
| See `load_example.py`. The tokenizer is a `tokenizers` BPE: | |
| `Tokenizer.from_file("tokenizer.json")`. | |
| ## Honest limitations | |
| - Trained on 60,014,592 tokens at ~10M parameters. It is a research artifact | |
| for studying looped depth, **not** a useful general-purpose language model. | |
| - Perplexity is tokenizer-dependent; **bits-per-byte** is the comparable | |
| number and is reported above. | |
| - The looped block **saturates**: past the depth listed as best above, extra | |
| applications make cross-entropy worse, not better. This is measured, not | |
| assumed, and is the central finding of the project. | |
| - English-only, no instruction tuning, no safety filtering beyond FineWeb's. | |
| Full experimental record, including every failed experiment: | |
| https://github.com/brkdrd/SimLoop | |