d24-sft-v3-olmo3-10b-wholedoc
v3 SFT chat model — 50B ClimbMix base + 10B whole-doc OLMo-3 midtrain (2x the 5B corpus).
nanochat-style depth-24 decoder — 24 layers × 1536 hidden × 12 heads, SwiGLU / RoPE / RMSNorm, tied embeddings, GPT-2 BPE vocab (50304), 0.757B params, 2048-token context.
Lineage. v3 pretrain (50B ClimbMix) → OLMo-3 Dolmino whole-doc midtrain (10.58B tok, 2x the 5B-wholedoc, all 24 components at true OLMo-3 proportions, long docs sliced to 2048-seq by the loader) → SFT (nanochat mix: SmolTalk + MMLU-aux + GSM8K + spelling + identity).
Metrics. GSM8K (greedy, full 1319): 7.28% · SFT val lm-loss 0.153. 2x the whole-doc data over the 5B-wholedoc SFT (6.60%) = +0.68pt — modest, diminishing returns; still below the math-dense v2 (9.86%). Confirms midtrain mix composition (math density) >> data quantity for GSM8K.
Use (chat)
This is a chat model (ChatML). The turn terminator it emits is the literal string <|im_end|> — which is not the eos_token_id (50256 = <|endoftext|>) and is not even a single token. You must stop on the <|im_end|> string or generation will not stop:
1from transformers import AutoModelForCausalLM, AutoTokenizer
2mid = "sfanm/d24-sft-v3-olmo3-10b-wholedoc"
3tok = AutoTokenizer.from_pretrained(mid)
4model = AutoModelForCausalLM.from_pretrained(mid, torch_dtype="bfloat16", device_map="auto")
5
6msgs = [{"role": "user", "content": "Natalia sold clips to 48 friends in April and half as many in May. How many total?"}]
7ids = tok.apply_chat_template(msgs, add_generation_prompt=True, return_tensors="pt").to(model.device)
8out = model.generate(ids, max_new_tokens=512, do_sample=False, stop_strings=["<|im_end|>"], tokenizer=tok)
9print(tok.decode(out[0, ids.shape[1]:], skip_special_tokens=False))
Without stop_strings=["<|im_end|>"] the model rambles to max_new_tokens: the configured eos_token_id (50256) is the GPT-2 document EOS, which a chat turn does not end with. For vLLM, pass stop=["<|im_end|>"].
Research checkpoint from a from-scratch nanochat-d24 replication (pretrain → midtrain → SFT → RL) on NERSC Perlmutter. Trained on third-party corpora (ClimbMix, FineMath, OpenMath, MetaMath, OpenThoughts, OLMo-3 Dolmino, SmolTalk, …) — see those datasets' licenses; provided as-is for research.