Qwen3-4B-openthoughts3-math-400k-sft
Qwen/Qwen3-4B supervised-fine-tuned on XinnanZhang/openthoughts3-math-50k8 (50k prompts x 8 samples =
400k examples), used as the student initialization for on-policy distillation experiments.
Read this before using the model
This checkpoint scores below its own base model. It is published for reproducibility of the distillation experiments that start from it, not as an improved model.
The cause is in the training data, not the recipe: only 29.4% of the SFT targets actually
close </think> and emit a \boxed{} answer. The remaining 70.6% hit a ~16k generation cap
mid-reasoning, after which the chat template still appends <|im_end|> — so the model is
trained to emit EOS in the middle of a thought. This is inherited from upstream
(OpenThoughts3-1.2M math is ~30% complete under the same measurement). Prompt formatting and
the boxed-answer suffix were verified byte-exact and are not the cause.
Training
Official openthinker3 hyperparameters, via LLaMA-Factory:
| learning rate | 8e-5 |
| global batch size | 512 |
| epochs | 1 |
| cutoff length | 20000 |
| packing | neat_packing (requires per-device batch size 1; scale with gradient accumulation) |
| other | liger kernel, FlashAttention-2, bf16 |
Evaluation
mean@8 / pass@8 in percent, n=8 samples per prompt, 16384 max response tokens,
T=0.6 / top_p=0.95 / top_k=20, thinking mode. aime24/25/26 are 30 questions each, amc23 is 40.
pass@8 is verl's val-core/<ds>/acc/best@8/mean estimator.
| dataset | mean@8 | pass@8 |
|---|---|---|
| aime24 | 42.08 | 68.37 |
| aime25 | 34.17 | 54.87 |
| aime26 | 37.08 | 56.09 |
| amc23 | 74.69 | 90.27 |
| average | 47.00 | 67.40 |
A packaging note that matters
This checkpoint was saved by transformers 5.2.0, which nests rope_theta under
rope_parameters. Older versions (e.g. 4.55.2) do not know that field and silently fall back
to rope_theta=10000 instead of 1000000; generations then start coherent and collapse into
character garbage with no error raised. On this model that difference was aime24 mean@8
1.25 vs 42.08.
The config.json here carries rope_theta both flat and nested with the same value
1000000, so it loads correctly under either version. If you re-save it, verify the flat key
survives.