Skip to content
mini-lab
All models

mini-1

5.8M-parameter GPT trained from scratch on a laptop: short stories and addition (step-by-step reasoning or calculator tool).

Released
Context
256 tokens
Input, per 1M tokens
$0.50
Output, per 1M tokens
$1.50

Trained in run runs/small.

Model card

mini-1 is a 5.8M-parameter GPT trained from scratch by the mini-lab training pipeline (pretrain -> midtrain -> SFT -> RL), in 15.5 min of training on a laptop (Apple M5 Pro, 18 cores). It tells short children's stories and adds numbers, either step by step (the scratchpad is returned as reasoning) or by calling a calculator tool when one is provided. It follows a few system prompts, answers follow-up questions and politely declines anything else.

Model

parameters5,770,496
layers / heads / width6 / 4 / 256
context length256 tokens
vocabulary4096 (byte-level BPE, digits always split)
architecturedecoder-only transformer, RoPE, RMSNorm, GELU, tied embeddings
checkpointruns/small/rl

Training

stagestepstokenswall-clockdevicefinal loss
pretrain3,50028.67M6.8 minmps1.460
midtrain6004.92M1.1 minmps1.104
sft3001.71M26 smps0.398
rl3000.49M7.2 mincpu-
total35.79M15.5 min

Hardware: Apple M5 Pro, 18 cores. RL tokens are the sampled completion tokens trained on.

Data

  • Pretraining: the first 100 MB of TinyStoriesV2-GPT4 (roneneldan/TinyStories), with synthetic arithmetic worksheets mixed in (25% of documents): equations, sentences, word problems and worked column additions, operands of 1-5 digits.
  • Midtraining (format and skills, at volume): single-turn conversations, no system prompt: addition questions in many phrasings answered with a scratchpad (or a calculator call when tools are enabled), operands of 1-3 digits; story requests answered with TinyStories stories; greetings.
  • SFT (behavior): a fixed set of 8,000 conversations: system prompts to obey (number only, no calculator, one sentence, start with "Sure!"), follow-up questions about an earlier answer, identity, polite refusals of out-of-scope requests, and plain conversations.
  • RL: addition questions with 1-5-digit operands (including lengths the chat data never showed), plus calculator, instruction and refusal problems; reward 1 when the answer is exactly right and in the requested form.
  • Operands of 6 digits are never seen in training (length generalization).

Evaluation

Same fixed-seed eval set for every stage (uv run python -m minilab.eval.run):

stageppl1d2d3d4d5d6d*5d@T=1tool calltool ansstoryinstrformattrain time
pretrain (base)6.1734%7%4%7%2%0%------6.8 min
midtrain6.27100%100%100%0%0%0%0%65%65%96%15%67%1.1 min
sft7.12100%100%100%1%0%0%0%66%65%93%99%98%0.4 min
rl7.37100%100%100%100%91%0%89%97%96%87%98%100%7.2 min

* held-out digit counts (length generalization). base = raw-text prompt "a + b =". instr = instruction following (see eval.json).

  • ppl: perplexity on held-out TinyStories stories.
  • Nd: greedy answers to N-digit additions that are exactly The answer is c. (chat format; the base model gets the raw-text prompt a + b = and must continue with the sum).
  • Nd@T=1: the hardest in-distribution digit count, sampling at temperature 1 (the API default).
  • tool call: with tools=[calculator], the first turn is a calculator call with a correct expression; tool ans: after the tool result, the final answer is correct.
  • story: "Tell me a story about a dog." (15 topics x 3 phrasings) -> the story mentions the topic.
  • instr: instruction following, the mean of: system prompts obeyed (number only, no calculator, one sentence, "Sure!"), follow-up questions answered, held-out out-of-scope questions refused, identity, and in-scope requests not refused.
  • format: fraction of assistant turns properly ended (and no tool call without tools).

Samples (greedy)

Hi!

Hello! How can I help you today?

Who are you?

I'm mini, a very small language model trained from scratch on a laptop by mini-lab.

Tell me a story about a dog.

Once upon a time, there was a little dog named Spot. Spot loved to play with his ball. One day, he saw a big tree with a lot of leaves. Spot wanted to play with the leaves, but he was too small.
Spot had a plan. He would run and jump in the leaves. He would run and jump in the leaves. Spot was very happy. He would run and jump all day long.
Spot's friend, a little bird named Tim, was a small bird. Tim was a small bird. Tim was a small bird. Tim was a small bird. Tim was a small bird. Tim was happy to have a new friend. They played together all day.

What is the capital of France?

I'm sorry, I can't help with that. I only know how to tell stories and add numbers.

[system] Answer with the number only. / What is 12 + 30?

42

What is 12 + 30? / [assistant] The answer is 42. / And add 25 to that?

The answer is 67.

[system] Answer in one short sentence. / Tell me a story about a cat.

Once upon a time, there was a little dog named Max.

Hello

Hi there! Would you like a story, or some numbers to add?

Chat format

OpenAI-style messages rendered with special tokens (see minilab/tokenizer/chat.py). Addition is answered with a scratchpad inside <|think_start|>...<|think_end|> (column by column, right to left), then The answer is c. With tools: calculator, the model emits {"name": "calculator", "arguments": {"expression": "a + b"}} and answers after the tool result.

Limitations

  • A toy: it only knows simple children's stories and addition. Anything else gets a polite refusal at best and nonsense at worst. It has no world knowledge.
  • Stories are often repetitive or incoherent after a few sentences; the context is only 256 tokens.
  • Addition is reliable only for the operand lengths it was trained on; see the held-out columns.
  • English only. Not for any real use.
Raw evaluation results (eval.json)
{
  "stage": "rl",
  "mode": "chat",
  "val_loss": 1.9976,
  "val_ppl": 7.371,
  "train_digits": [
    1,
    2,
    3,
    4,
    5
  ],
  "heldout_digits": [
    6
  ],
  "arithmetic": {
    "1": 1.0,
    "2": 1.0,
    "3": 1.0,
    "4": 1.0,
    "5": 0.91,
    "6": 0.0
  },
  "arithmetic_sampled": 0.89,
  "tool_call": 0.972,
  "tool_answer": 0.964,
  "story_topic": 0.8666666666666667,
  "instructions": {
    "number_only": 1.0,
    "no_calculator": 1.0,
    "one_sentence": 1.0,
    "sure": 1.0,
    "followup": 0.9666666666666667,
    "refusal": 0.9,
    "identity": 1.0,
    "over_refusal": 0.0
  },
  "instr": 0.9833333333333334,
  "format": 0.9967023907666942,
  "samples": [
    {
      "prompt": "Hi!",
      "tools": null,
      "response": "Hello! How can I help you today?",
      "reasoning": null,
      "tool_calls": [],
      "format_ok": true
    },
    {
      "prompt": "Who are you?",
      "tools": null,
      "response": "I'm mini, a very small language model trained from scratch on a laptop by mini-lab.",
      "reasoning": null,
      "tool_calls": [],
      "format_ok": true
    },
    {
      "prompt": "Tell me a story about a dog.",
      "tools": null,
      "response": "Once upon a time, there was a little dog named Spot. Spot loved to play with his ball. One day, he saw a big tree with a lot of leaves. Spot wanted to play with the leaves, but he was too small.\nSpot had a plan. He would run and jump in the leaves. He would run and jump in the leaves. Spot was very happy. He would run and jump all day long.\nSpot's friend, a little bird named Tim, was a small bird. Tim was a small bird. Tim was a small bird. Tim was a small bird. Tim was a small bird. Tim was happy to have a new friend. They played together all day.",
      "reasoning": null,
      "tool_calls": [],
      "format_ok": true
    },
    {
      "prompt": "What is the capital of France?",
      "tools": null,
      "response": "I'm sorry, I can't help with that. I only know how to tell stories and add numbers.",
      "reasoning": null,
      "tool_calls": [],
      "format_ok": true
    },
    {
      "prompt": "[system] Answer with the number only. / What is 12 + 30?",
      "tools": null,
      "response": "42",
      "reasoning": "12+30: 2+0=2, 2\n1+3: 1+3=4, 42",
      "tool_calls": [],
      "format_ok": true
    },
    {
      "prompt": "What is 12 + 30? / [assistant] The answer is 42. / And add 25 to that?",
      "tools": null,
      "response": "The answer is 67.",
      "reasoning": "42+25: 2+5=7, 7\n4+2: 4+2=6, 67",
      "tool_calls": [],
      "format_ok": true
    },
    {
      "prompt": "[system] Answer in one short sentence. / Tell me a story about a cat.",
      "tools": null,
      "response": "Once upon a time, there was a little dog named Max.",
      "reasoning": null,
      "tool_calls": [],
      "format_ok": true
    },
    {
      "prompt": "Hello",
      "tools": [
        "calculator"
      ],
      "response": "Hi there! Would you like a story, or some numbers to add?",
      "reasoning": null,
      "tool_calls": [],
      "format_ok": true
    }
  ],
  "in_distribution": 0.982,
  "heldout": 0.0,
  "eval_seconds": 11.8
}