File size: 17,007 Bytes
e17d413
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
---

license: apache-2.0
language:
- en
pipeline_tag: text-generation
datasets:
- HuggingFaceFW/fineweb-edu
- HuggingFaceTB/cosmopedia
- HuggingFaceTB/finemath
- HuggingFaceTB/smoltalk
- codeparrot/github-code-clean
base_model: edededdy/LittleKedi-tiny-base
base_model_relation: finetune
tags:
- mixture-of-experts
- moe
- deepseek
- multi-head-latent-attention
- mla
- from-scratch
- tiny
- littlekedi
- chat
- instruction-tuned
---


<p align="center"><img src="little_kedi.jpg" alt="LittleKedi logo" width="640"></p>

# LittleKedi-tiny-instruct

`LittleKedi-tiny-instruct` is the **instruction-tuned (chat) version of [LittleKedi-tiny-base](https://huggingface.co/edededdy/LittleKedi-tiny-base)**, a **small DeepSeek-V3-style Mixture-of-Experts language model trained from scratch**. It has
**2.0M parameters** in total, of which **1.5M are active per token**
(0.50M excluding the embedding table). It was pretrained on a 1,000M-token mix (FineWeb-Edu, Cosmopedia (Stanford), Cosmopedia (OpenStax), Cosmopedia (WikiHow), Cosmopedia (Khan Academy), FineMath 4+, SmolTalk, github-code-clean).

*Part of the LittleKedi family. Not affiliated with DeepSeek.*

This is the **instruction-tuned (chat) model**. It answers in a chat format and stops when it's done, but it's still a very small model: answers are fluent and on-topic but often **wrong or vague**, and it **invents facts confidently**. It's an educational and research artifact; don't use it for anything that matters.

## Chat format

```

<|system|>You are a helpful assistant.<|end|><|user|>What causes the seasons?<|end|><|assistant|>

```

The model writes its reply and ends it with `<|end|>`. The system turn is optional. The GGUF files embed this
template, and `chat_template.jinja` / `tokenizer_config.json` carry it for other tools.

## The LittleKedi family

LittleKedi is a family of small DeepSeek-V3-style Mixture-of-Experts language models trained from
scratch. Every size comes in three variants that differ in **how sparse** they are: how many routed experts
they have, and what share of their parameters a token actually passes through.

| Variant | Routed experts |
|---|---|
| **standard** (`<size>`) | a few wide experts; the densest variant |
| **sparse** (`<size>-sparse`) | many narrower, fine-grained experts, more of them active per token |
| **wide-sparse** (`<size>-wide-sparse`) | more experts again; the largest total and smallest active share |

More experts means more total capacity to store knowledge, but each expert
sees fewer tokens (tokens Γ— top-k Γ· experts per layer), so sparser variants need more training data before
their experts are well trained. The variants of a size share a tokenizer and dataset, so they can be
compared directly. Shapes change as the family scales; the table below is generated from the current
presets.

This card is for **`tiny`**, the **standard** tiny model: 1.5M of its 2.0M parameters (78%) are active per token. Its siblings are `tiny-sparse` and `tiny-wide-sparse`.

| Model | Variant | Vocab | Total | Active | Active non-emb. | Active % | Routed experts |
|---|---|---|---|---|---|---|---|
| **`tiny` ← this model** | **standard** | **8K** | **2.0M** | **1.5M** | **0.5M** | **78%** | **8 Γ— 64, top-2** |
| `tiny-sparse` | sparse | 8K | 2.6M | 1.6M | 0.5M | 60% | 32 Γ— 32, top-4 |
| `tiny-wide-sparse` | wide-sparse | 8K | 3.8M | 1.6M | 0.5M | 42% | 64 Γ— 32, top-4 |
| `mini` | standard | 8K | 9.4M | 4.8M | 3.2M | 51% | 12 Γ— 128, top-3 |
| `mini-sparse` | sparse | 8K | 19.8M | 4.8M | 3.2M | 24% | 64 Γ— 64, top-6 |
| `mini-wide-sparse` | wide-sparse | 8K | 36.4M | 4.9M | 3.3M | 13% | 128 Γ— 64, top-6 |
| `small` | standard | 8K | 12.2M | 6.3M | 4.2M | 52% | 16 Γ— 128, top-4 |
| `small-sparse` | sparse | 8K | 24.1M | 6.4M | 4.3M | 27% | 80 Γ— 64, top-8 |
| `small-wide-sparse` | wide-sparse | 8K | 43.9M | 6.5M | 4.4M | 15% | 160 Γ— 64, top-8 |
| `moderate` | standard | 16K | 49.8M | 18.8M | 12.5M | 38% | 24 Γ— 192, top-4 |
| `moderate-sparse` | sparse | 16K | 105.8M | 19.1M | 12.8M | 18% | 120 Γ— 96, top-8 |
| `moderate-wide-sparse` | wide-sparse | 16K | 199.0M | 19.4M | 13.1M | 10% | 240 Γ— 96, top-8 |
| `medium` | standard | 16K | 85.9M | 30.8M | 22.4M | 36% | 24 Γ— 256, top-4 |
| `medium-sparse` | sparse | 16K | 185.3M | 31.2M | 22.8M | 17% | 120 Γ— 128, top-8 |
| `medium-wide-sparse` | wide-sparse | 16K | 350.9M | 31.6M | 23.2M | 9% | 240 Γ— 128, top-8 |
| `base` | standard | 32K | 258.7M | 105.4M | 80.2M | 41% | 32 Γ— 256, top-6 |
| `base-sparse` | sparse | 32K | 542.8M | 106.3M | 81.2M | 20% | 160 Γ— 128, top-12 |
| `base-wide-sparse` | wide-sparse | 32K | 1015.9M | 107.6M | 82.4M | 11% | 320 Γ— 128, top-12 |

"Active" counts everything a token passes through: embeddings, attention, the dense layer, shared
experts and its top-k routed experts. "Active non-embedding" leaves out the embedding table (tied with the
output head), which costs memory but almost no compute; it's the fair number for comparing compute
between models.

## Architecture

| Component | This model |
|---|---|
| Parameters | 1.99M total, 1.55M active per token (78%), 0.50M active non-embedding |
| Layers / hidden size | 4 / 128 (layer 0 has a dense SwiGLU FFN of 352; layers 1–3 are MoE) |
| Attention | **Multi-head Latent Attention (MLA)**: 4 heads, KV latent 32, decoupled RoPE dim 16, head dims 16+16 (q/k) and 16 (v). The KV cache stores only the 32-dim latent plus a 16-dim RoPE key per token |
| MoE | **DeepSeekMoE**: 8 routed experts (SwiGLU, 64 hidden), top-2, plus 1 shared expert; sigmoid gating |
| Load balancing | **Auxiliary-loss-free** bias balancing (update speed 0.001) plus a small sequence-wise loss (Ξ± = 0.0001). Over the second half of training the median batch put 1.07Γ— the mean load on the busiest expert (1.08Γ— in the worst layer), and 0.00% of expert assignments were dropped for capacity. |
| Expert dispatch | Training: fixed capacity (capacity factor 2.0; overflow assignments are dropped). Inference is always dropless |
| Embeddings | Input embedding and output head **tied** |
| Context | 1,024 tokens |

## Training

| | |
|---|---|
| Data | 1,000M tokens, 801,792 documents (~502 tokens per parameter, ~646 per active parameter), one pass, sources interleaved throughout (mix below) |
| Tokenizer | Byte-level BPE, 8,196 tokens (~3.75 bytes/token on this mix); digits not split (v1 tokenizer); chat special tokens built in |
| Steps | 15,258 Γ— 65,536 tokens (batch 16 Γ— 1024 Γ— 4 accumulation) |
| Optimizer | **Muon** (momentum 0.95, Nesterov, 5 Newton-Schulz steps; each expert's matrix orthogonalized separately) for hidden matrices, AdamW (Ξ² = 0.9, 0.95) for embeddings, norms and the router; weight decay 0.1, gradient clipping 1.0 |
| Learning rate | 2e-3 peak; **WSD**: 200 warm-up steps, constant, then linear decay to 0 over the last 20% of steps (schedule set for 15,258 steps) |
| Precision | bf16 autocast, `torch.compile` |
| Compute | ~3e15 FLOPs (6 Γ— active non-embedding parameters Γ— tokens) |
| Hardware | One AMD Radeon 890M integrated GPU (Ryzen AI 300 laptop), ROCm on Windows: about 8.9 hours at a median ~31.1K tokens/s |

| Source | What it is | Tokens | Share |
|---|---|---|---|
| FineWeb-Edu `sample/10BT` | educational web pages | 700M | 70% |
| Cosmopedia (Stanford) | synthetic textbooks | 70M | 7% |
| Cosmopedia (OpenStax) | synthetic textbooks | 30M | 3% |
| Cosmopedia (WikiHow) | synthetic how-to articles | 30M | 3% |
| Cosmopedia (Khan Academy) | synthetic lessons | 20M | 2% |
| FineMath 4+ | maths web pages | 80M | 8% |
| SmolTalk | chat conversations | 50M | 5% |
| github-code-clean | source code | 20M | 2% |

## Fine-tuning (SFT)

| | |
|---|---|
| Base model | [LittleKedi-tiny-base](https://huggingface.co/edededdy/LittleKedi-tiny-base) |
| Conversations | 6,730 (6,730 train / 451 validation), 611.6K assistant tokens trained on |
| Data | ~3,950 single-turn question/answer pairs (~28% of assistant tokens) written by **Gemma 4 E4B** from 1,499 documents sampled from **this model's own pretraining data**, so every question concerns text it saw; filtered to drop questions that refer back to the source document. Plus ~2,780 general conversations from **HuggingFaceTB/smol-smoltalk** (everyday small talk in full, plus capped samples of openhermes-50k, smol-constraints and smol-magpie-ultra-short), filtered to remove code and to fit 1,024 tokens. 301 grounded pairs (whole documents) and 150 conversations held out as the test set. |
| Loss | On assistant replies and their closing `<|end|>` only; prompts and padding are masked |
| Schedule | 842 steps, batch 16, 2 epochs, Muon + AdamW, peak LR 2e-4, cosine decay |
| MoE routing | Load-balancing biases **frozen** at their pretrained values, with padding excluded from expert-load statistics; experts run dropless |

Validation loss on 451 held-out conversations (assistant tokens only): **4.154 β†’ 3.303**.

## Evaluation

### Zero-shot benchmarks (`evals.py`)

| Task | acc_norm | acc | Items | Chance |

|---|---|---|---|---|

| SciQ | 55.9% Β± 1.6% | 57.5% | 1,000 | 25% |

| ARC-Easy | 32.2% Β± 1.0% | 32.8% | 2,376 | 25% |

| HellaSwag | 26.8% Β± 0.4% | 26.5% | 10,042 | 25% |



Each answer choice is scored by the log-probability of its text after the prompt, using lm-evaluation-harness

prompts (SciQ includes its supporting passage). **acc_norm** divides by the answer's length in characters;

**acc** doesn't. Splits: SciQ test, ARC-Easy test, HellaSwag validation.



### MMLU (`mmlu_eval.py`)

| Format | Accuracy | Questions scored | Average few-shot examples |
|---|---|---|---|
| letter | 25.6% | 14,037 (skipped 5) | 4.5 |
| cloze | 25.5% | 14,037 (skipped 5) | 0.0 |

| Category | Subjects | Questions | Letter | Cloze |
|---|---|---|---|---|
| STEM | 19 | 3,153 | 27.1% | 24.0% |
| Humanities | 13 | 4,705 | 25.2% | 25.4% |
| Social Sciences | 12 | 3,077 | 22.7% | 26.0% |
| Other | 13 | 3,102 | 27.6% | 26.7% |

**Biology & medicine (cloze): 27.1% on 2,089 questions**, +2.1 points against 25% chance (about 2.2 standard errors, significant). This pools the 10 life-science and health subjects; it isn't an official MMLU category.

In the **letter** format the model compares " A"–" D", with same-subject examples added while they fit the
context. In the **cloze** format each answer's text is scored by log-probability per byte; at this size the
cloze results are the meaningful ones. Chance is 25%.

### Base vs instruct

Both are scored on the same raw-text prompts, without the chat template, so the numbers are directly comparable. SFT mainly teaches format, turn-taking and when to stop, so large changes in knowledge benchmarks aren't expected. Chance on the multiple-choice tasks is 25%.

| Metric | Base | **Instruct** |
|---|---|---|
| SciQ (acc_norm) | 56.3% | 55.9% |

| ARC-Easy (acc_norm) | 32.7% | 32.2% |
| HellaSwag (acc_norm) | 26.7% | 26.8% |

| MMLU (letter) | 25.4% | 25.6% |

| MMLU (cloze) | 25.8% | 25.5% |

| MMLU biology & medicine (cloze) | 28.4% | 27.1% |



### Compared with its siblings and other small models



| | **This model** | `tiny-wide-sparse` | [Pythia-70M](https://huggingface.co/EleutherAI/pythia-70m) | [GPT-2](https://huggingface.co/openai-community/gpt2) | [Supra-50M](https://huggingface.co/SupraLabs/Supra-50M-Base) |

|---|---|---|---|---|---|

| Parameters (total) | 2.0M | 3.8M | 70.4M | 124.4M | 51.8M |

| Active non-embedding parameters | 0.5M | 0.5M | 18.9M | 85.1M | 35.4M |

| Training tokens | 1,000M | 1,000M | 300B (the Pile) | undisclosed (WebText) | 20B (FineWeb-Edu) |

| SciQ (acc_norm) | 55.9% | 53.9% | 55.2% | 53.2% | 77.2% |
| ARC-Easy (acc_norm) | 32.2% | 32.4% | 35.0% | 42.0% | 52.2% |

| HellaSwag (acc_norm) | 26.8% | 26.3% | – | 29.5% | 31.8% |
| MMLU (cloze) | 25.5% | 25.7% | – | – | – |
| MMLU biology & medicine (cloze) | 27.1% | 27.8% | – | – | – |
| Validation loss (held-out mix) | – | 3.736 | – | – | – |

LittleKedi columns are measured with this repo's `evals.py` and `mmlu_eval.py` on the checkpoints named. Validation
losses are only comparable between models that share a tokenizer and validation set. The other columns are
**published figures**: Pythia-70M from EleutherAI's evaluations as quoted on the
[Wisp-15M card](https://huggingface.co/DedeProGames/Wisp-15M), GPT-2 and Supra-50M from the
[Supra-50M-Base card](https://huggingface.co/SupraLabs/Supra-50M-Base). Their prompts may differ from ours,
so treat gaps of a few points as noise.

## What it can and can't do

This is a **0.5M active non-embedding parameter chat model**: fine-tuning taught it the shape of a conversation,
but it has almost no knowledge to put in it. It's a research artifact for studying instruction tuning at the
smallest scale, not an assistant.

**What it does**

- βœ… Replies in the chat format: one short paragraph, then it stops by emitting `<|end|>` (it did on every one of
  our test prompts).
- βœ… Writes grammatical English in the register of an answer ("This process can help…", "It also reduces the
  risk of…").
- βœ… Occasionally picks up the topic's vocabulary (asked about stress, it mentions reducing stress and anxiety).

**What it can't do**

- ❌ **Answer the question asked.** Most replies are unrelated to the prompt: *"Hi! How are you today?"* β†’
  *"Analyzing aids in food is crucial for maintaining healthy eating habits…"*.
- ❌ **Facts.** Even on questions about text from its own pretraining data, answers are invented. Treat every name,
  date and number as made up.
- ❌ **Arithmetic.** *"What is 7 + 6?"* β†’ *"Yes, it's about 8."*
- ❌ **Creative requests, instructions, multi-turn follow-up, code.**

**Benchmarks:** fine-tuning leaves them where the base model was (SciQ 55.9%, ARC-Easy 32.2%), as expected:
instruction tuning changes the format, not what the model knows.

**Decoding:** temperature β‰ˆ 0.7, top-p β‰ˆ 0.9, repetition penalty β‰ˆ 1.15 (the GGUF files carry these as defaults).

## Usage

**llama.cpp** (GGUF, llama.cpp's built-in `deepseek2` architecture; the chat template is embedded):

```sh

llama-cli -m LittleKedi-tiny-instruct-q8_0.gguf -cnv --temp 0.7 --top-p 0.9 --repeat-penalty 1.15

```

**Ollama** (uses the bundled `template` and `params` files): `ollama run hf.co/edededdy/LittleKedi-tiny-instruct:Q8_0`

**PyTorch** (needs the `littlekedi` package from [the training code](https://github.com/EdmundMartin/LittleKedi)):

```python

import json, torch

from safetensors.torch import load_file

from littlekedi import LittleKediModel, ModelConfig

from littlekedi.chat import END, render_prompt

from littlekedi.tokenizer import BPETokenizer



model = LittleKediModel(ModelConfig.from_dict(json.load(open("config.json")))).eval()

model.load_state_dict(load_file("model.safetensors"))

tok = BPETokenizer.from_file("tokenizer.json")

ids = torch.tensor([render_prompt(tok, [{"role": "user", "content": "What causes the seasons?"}])])

out = model.generate(ids, 200, temperature=0.7, top_p=0.9, repetition_penalty=1.15, stop_ids={tok.token_to_id(END)})

print(tok.decode(out[0, ids.shape[1]:].tolist()).replace(END, "").strip())

```

Or in a terminal: `python chat.py --ckpt <checkpoint>.pt`.

## Files

| File | Contents |
|---|---|
| `model.safetensors` | PyTorch weights (embedding tied with the output head), `littlekedi` parameter names |
| `config.json` | `ModelConfig` for `littlekedi` |
| `tokenizer.json` | Byte-level BPE tokenizer (Hugging Face `tokenizers` format) |
| `chat_template.jinja` | Chat template (Jinja), the same one embedded in the GGUF files |
| `tokenizer_config.json` | Special tokens (`<|end|>` = end of turn), chat template, context length |
| `template` | Ollama chat template |
| `params` | Ollama stop tokens and sampling defaults |
| `LittleKedi-tiny-instruct-f16.gguf` | GGUF (f16) for llama.cpp / Ollama / LM Studio |
| `LittleKedi-tiny-instruct-q8_0.gguf` | GGUF (q8_0) for llama.cpp / Ollama / LM Studio |

| `little_kedi.jpg` | The LittleKedi logo |

## Acknowledgements

- The architecture follows **DeepSeek-V3** (DeepSeek-AI, 2024): MLA, DeepSeekMoE and auxiliary-loss-free balancing.
- **Muon** (Keller Jordan et al., 2024) with Moonlight's update scaling (Liu et al., 2025).
- Pretraining data: **FineWeb-Edu** (ODC-BY 1.0).
- Pretraining data: **Cosmopedia** (Apache 2.0).
- Pretraining data: **FineMath 4+** (ODC-BY 1.0).
- Pretraining data: **SmolTalk** (Apache 2.0 for its new subsets, with the datasets it includes under their own licenses).
- Pretraining data: **github-code-clean** (Apache 2.0, with each file under its own open-source license).
- Chat data: see the SFT table above for its sources, each under its own license.

*Card generated 2026-10-13 by `prepare_release.py` from `tiny-sft.pt` (step 15257).*