You are browsing as a guest. Sign up (or log in) to start making projects!

Open comments for this post

5h 33m 9s logged

Devlog #4 — wait, why am I training on Wikipedia?

Last week I got le gros chaton (my from-scratch transformer) to actually train. Ran it on wikitext-103 in a Colab notebook on a free T4, 12k steps, val loss hit 3.73. Felt insane for something I wrote myself from PyTorch primitives.

But then I looked at what it generated. It could do English-ish. It knew about Singapore and stuff. The moment I asked it to write code? Total garbage. Fair enough. It has never seen a single line of code.

the pivot

I thought about what I actually want this thing to do. Answer: a coding agent. Something that mogs on terminal-bench, that you give a task and it runs commands, fixes its own bugs, gets it done. Qwen-coder territory.

Wikitext won’t get me there. You can’t learn Python from Wikipedia articles about the snake.

So the plan changed. The big project is now le fat chaton, the bigger sibling. And it’s a coder.

the architecture stuff

I went down a rabbit hole on what frontier coding models do. They’re basically all mixture-of-experts (MoE) now. Qwen3-coder is 480B params / 35B active. Deepseek-coder-v2-lite is 16B / 2.4B active. The trick:

  • big total params (knows a lot)
  • small active params per token (runs fast and cheap)

Runs like a small model, knows like a big one. Exactly what I want for a snappy terminal agent.

So I rewrote the model. Added an MoE class. A gate routes each token to its top-2 experts out of 8, with a load-balance loss so the router doesn’t pick the same expert every time. Also threw in:

  1. SwiGLU — gated MLP, basically free quality, every Llama uses it
  2. GQA — smaller KV cache, faster long-context decoding (the agent harness needs this)
  3. Shared expert — DeepSeek-style, one always-on expert for common knowledge

Fat config math: ~10.25B total / ~3.65B active. Not building that locally, it would crash my PC again.

the data question

Wikitext was a fine proof. For the coder I need code. Options:

  • smollm-corpus python-edu — 7.6M educational Python files, high quality, but gated behind S3 (slow pull)
  • starcoderdata python — ~50GB Python, streams fast from HF, the Codellama workhorse
  • the-stack-v2 — 900B tokens, overkill for my budget

Going with starcoderdata Python, blended with ~15-20% cosmopedia (prose) so it has general knowledge. That blend is the Qwen-coder recipe.

am I warm-starting from wikitext?

No. Different architecture entirely (17M dense vs 10B MoE, weights don’t fit). Even if they did, warm-starting a coder from prose wastes compute unlearning prose. Fresh random init on the mixed corpus. Clean slate.

This went from “lets make a little model that talks” to “lets build a coding agent that mogs the big labs” real fast. Ambitious for a solo student with a 2070 and $30 of Modal credits? Absolutely. Doing it anyway? Yeah.

Next: the eval harness so I can measure if this is making the model better at code (pass@1, pass@5 on HumanEval). Val loss going down means nothing if it still can’t write a

0
0
2
Open comments for this post

23m 59s logged

DEVLOG #3: teaching it to talk (fine-tuning)

the base model was a completer. ask it “what is 2+2?” and it just continues the sentence. fine-tuning is what makes it actually answer: same model, more training, but on prompt/response pairs.

i wrote ~48 Q&A pairs by hand. trivia, math, jokes, hellos. all in the same rigid Q: …\nA: format. new trick: loss masking. only the response counts toward the loss, not the prompt, so i set prompt targets to -100 (pytorch’s cross_entropy ignores that automatically, zero model changes). tested the mask boundary in isolation first. wrong mask = 400 steps of training the wrong thing.

the run: load base weights, 400 steps, lower lr. loss went 12.3 to 0.02.then the reality check. it nails everything in the set. capitals, math, jokes, “who are you,” verbatim. but something NOT in the set? slop. 17M params + 48 examples is a lookup table, not a reasoner. real chat models are billions of params. not a bug, just the scale.but it’s finally coherent. the first base model was word salad. now you type a question and get a real answer back that makes sense.

it’s tiny and dumb and can’t generalize, but it actually talks. that’s the win.

full pipeline done: tokenizer, model from scratch, pretrain on wikipedia, fine-tune, chat. mine, it talks, i understand every piece.

0
0
12
Open comments for this post

19m 1s logged

DEVLOG #2: real data, real loss, and a lesson about memorizing

split my data into 90% train / 10% val. before i only had one number, training loss, and it lies to you. you can’t tell learning from memorizing with just that. now i check both every 200 steps. rule: both go down = learning. train down but val up = memorizing = useless.also made the model bigger, 7M -> 17.7M params. immediately ran out of gpu memory lol. dropped batch size to 32 to fit my 8GB card.training: 3000 steps. loss started at 158 (should be ~10 for random , my first pass blew up and made garbage). recovered fast though, didn’t ruin the run.

right now the llm is spitting out gibberish and random words but after finetuning it should sound more coherent

0
0
7
Open comments for this post

1h 53m 52s logged

DEVLOG #1: wiki text training

so i finally got the model to train on actual data instead of that one paragraph about singapore nature reserves lol. before this the whole thing was basically a joke, i trained a 7M parameter transformer on like 134 tokens and it just spat out jumbled fragments of the same sentence over and over. cool proof it worked but definitely not a “language model” in any real sense.anyway. the big move this week was swapping out the tiny json file for wikitext-2. that’s a huggingface dataset of wikipedia text, about 2.4 million tokens once you filter out the empty lines. that’s… a lot more than 134 lol. encoding it took maybe half a minute with tiktoken and the whole tensor fits on my gpu no problem (it’s only like 8MB of ints).

0
0
6

Followers

Loading…