Evaluation
Each checkpoint answers each question once (temperature 0.6, top-p 0.95, up to 15,360 tokens, seed 0; vLLM in BF16), with the prompt format below:
- ID: the 500 held-out OpenR1-Math problems, scored like training (math-verify).
- MATH-500: the 500 problems of MATH-500, scored the same way.
- MMLU-Pro: 1,000 questions drawn with seed 0 from the test split of MMLU-Pro. The prompt asks for the letter of the answer within
\boxed{}, and the answer counts as right when that letter is right.
Accuracy:
Table with columns: Step, ID, MATH-500, MMLU-Pro| Step | ID | MATH-500 | MMLU-Pro |
|---|
| 0 (base) | 0.220 | 0.562 | 0.218 |
| 10 | 0.248 | 0.590 | 0.240 |
| 25 | 0.240 | 0.614 | 0.241 |
| 50 | 0.246 | 0.620 | 0.257 |
| 100 | 0.266 | 0.640 | 0.292 |
| 150 | 0.302 | 0.632 | 0.304 |
| 200 | 0.288 | 0.664 | 0.318 |
| 250 | 0.290 | 0.638 | 0.316 |
| 300 | 0.312 | 0.652 | 0.344 |
Checkpoints
Each checkpoint is a branch named after its step: step1 to step50, then step60, step70, …, step300. main holds the last one (step 300). Step 0 is the base model itself.
from transformers import AutoModelForCausalLM, AutoTokenizer repo = "XudongZhu/Qwen3-1.7B-Base-SFT-OnPolicy"model = AutoModelForCausalLM.from_pretrained(repo, revision="step100")tokenizer = AutoTokenizer.from_pretrained(repo, revision="step100")
Without revision, you get step 300. All branches: huggingface_hub.list_repo_refs(repo).branches.
The user turn is the problem, a blank line, and Please reason step by step, and put your final answer within \boxed{}. There is no system prompt; tokenizer.apply_chat_template builds this:
<|im_start|>user{problem} Please reason step by step, and put your final answer within \boxed{}.<|im_end|><|im_start|>assistant
Training
Data. From the default split of OpenR1-Math-220k (93,733 problems):
- Keep the math word problems that have a DeepSeek-R1 answer which math-verify marks correct and which is complete: 59,188 problems. (16,115 are not word problems, and 18,430 have no such answer; none is also in MATH-500.)
- Shuffle them with seed 0 and hold out the first 500 for evaluation.
- In this order, skip the problems whose prompt is longer than 1,024 tokens (29) or whose prompt and R1 answer together are longer than 16,384 tokens (684), and take the first 38,400.
The run trains on these 38,400 problems in this order, once. The length limit counts the R1 answer even in this run, so that both runs see the same problems.
One step. For each of 128 problems, the current model samples 8 answers (temperature 1.0, top-p 1.0, up to 15,360 tokens). math-verify compares the last 2,000 characters of each answer with the reference answer. For each problem, one correct answer is kept at random; a problem with no correct answer is skipped in this step. One optimizer step then minimizes the SFT loss on the kept answers: the mean of −log p over their tokens, without the prompt.
Table with columns: Hyperparameter, Value| Hyperparameter | Value |
|---|
| Optimizer | AdamW (β = 0.9, 0.999), weight decay 0, gradient clipping 1.0 |
| Learning rate | 1e-6, constant, no warmup |
| Batch | 128 problems per step, one optimizer step |
| Sampling | 8 answers per problem, temperature 1.0, top-p 1.0 |
| Length | prompt ≤ 1,024 tokens, answer ≤ 15,360 tokens |
| Steps | 300, one pass over the data |
| Precision | FP32 weights; BF16 compute and FP32 gradient reduction (FSDP mixed precision); BF16 sampling |
| Seeds | sampling 42; picking the kept answer 0 |
Uses and limitations
For research on training dynamics: compare weights or behavior across checkpoints, and against the off-policy twin. The run trains only on English math problems, with no instruction tuning or safety training beyond the base model; its answers are long chains of reasoning. Each accuracy above comes from one sample per question, so small differences between steps are not reliable.