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 large models of the day were badly undertrained, and that a smaller one fed more data beat them. The 65B option would have seen 6.9 tokens for every parameter it had to store them in. The 38B 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. It is a decision made months before launch that only pays off on the day the traffic arrives, which is the kind that is easy to skip.
KV cache per full-context request
56 MiB of KV cache for a full 2,048-token request, against roughly 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 is the default, and for most projects it is correct. It is also the first place a model quietly inherits somebody else's assumptions: a vocabulary fitted to one corpus segments a different corpus badly, and every extra token is context you paid for and cannot spend on reasoning.
So the tokenizer was trained on the corpus the model would actually see. The test of whether that was worth doing is fertility, meaning tokens per word on held-out text, because a lower number is directly more effective context at the same sequence length.
04
The refusal problem in post-training
A base model has no refusal behaviour; refusals are installed during instruction tuning. The work was getting instruction-following without acquiring them, which is delicate because the data that teaches a model to follow directions is the same data that teaches it to decline.
The model still had to follow instructions, so the constraint was to get instruction-following while keeping direct answering intact, and then to measure whether it held rather than assert that it did.
05
Reading a loss curve with nothing to compare it to
The recipes were unwritten in 2023. You chose the data mixture, chose the learning-rate schedule, and read your loss curve without any shared sense of what healthy looked like at that scale, because nobody had published one.
Which meant the errors were the kind that only surface after the loss curve has already looked fine for a long time, and the cost of finding them was measured in GPU-hours, not minutes.