01
Why not the bigger model
Every version of this that people wanted to hear about was larger. A 65B would have cost roughly the same compute as the 38B, because compute is parameters multiplied by tokens and you can trade one against the other freely on a slide.
You cannot trade them freely in the model. Chinchilla had shown ten months earlier that the big models of that year were badly undertrained, and that a smaller one fed more data beat them. The 65B would have seen 6.9 tokens for every parameter it had to store them in. The 38B I built saw 21.
Tokens per parameter
21.06 tokens per parameter, against 6.9 for the 65B alternative at the same compute
02
One key/value head instead of sixty-four
Standard attention keeps a separate key and value head for every query head, and every one of them has to be cached for every token in the conversation. That cache is what limits how many people can be served at once, and it grows as the conversation does.
Multi-query attention shares one key head and one value head across all 64 query heads. I made that call months before launch, and it did nothing for me at all until the day the traffic arrived.
KV cache per full-context request
56 MiB of KV cache for a full 2,048-token request, against 3.5 GiB for the same model with 64 KV heads
03
Why I trained the tokenizer instead of borrowing GPT-2's
Borrowing a tokenizer was the default in 2023, and for most projects it was the right call. It was also the first place I would have inherited somebody else's assumptions. A vocabulary fitted to one corpus segments a different corpus badly, and every extra token it spends is context I had paid for and could not spend on reasoning.
So I trained the tokenizer on the corpus the model would actually see. That took a week. What it bought was fertility, fewer tokens per word on held-out text, so the same 2,048 positions carried more of the document.
04
The refusal problem in post-training
A base model has no refusal behaviour. Refusals arrive during instruction tuning, and the hard part was getting instruction-following without picking them up, because the data that teaches a model to follow directions is the same data that teaches it to decline.
It still had to follow instructions, so I had to carry direct answering through post-training and then go back and check whether it had survived.
05
Reading a loss curve with nothing to compare it to
The recipes were unwritten in 2023. I chose the data mixture, chose the learning-rate schedule, and read the loss curve with no shared sense of what healthy looked like at that scale, because nobody had published one.
The mistakes that hurt were the ones that only showed up after the curve had already looked fine for days. Finding them cost GPU-hours, and there was no way to get those back.