CoolFace
Modelpublic

XinnanZhang/Qwen3-8B-openthoughts3-math-400k-sft

sourceHugging Faceapache-2.0updated 24d agoView on Hugging Face
0likes238downloads
Model Card

Qwen3-8B-openthoughts3-math-400k-sft

Qwen/Qwen3-8B 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.

For reference, the untuned Qwen/Qwen3-8B scores 67.06 / 80.76 on the same eval, i.e. this SFT model is 14.1pp worse than the base model it was fine-tuned from.

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 rate8e-5
global batch size512
epochs1
cutoff length20000
packingneat_packing (requires per-device batch size 1; scale with gradient accumulation)
otherliger kernel, FlashAttention-2, bf16

Evaluation

mean@8 / pass@8 in percent, n=8 samples per prompt, 16384 max response tokens, T=0.6 / topp=0.95 / topk=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.

datasetmean@8pass@8
aime2446.2570.60
aime2537.0853.34
aime2646.2562.62
amc2382.1993.61
average52.9470.04

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.