Training
The source checkpoint was named qwen3-4b-recursive-sft-v3-expanded-r5.
Table with columns: Setting, Value| Setting | Value |
|---|
| Original curated GSM8K problem rollouts | 5,935 |
| Component-level SFT examples | 20,332 |
| Objective | Output-token-only causal language modeling |
| Configured epochs | 4 |
| Actual optimizer updates | 632 |
| Final recorded epoch | 3.994688 |
| Global batch | 128 component calls, not 128 original problems |
| Maximum training sequence length | 2,048 tokens |
| Learning rate | 1e-5 |
| Weight decay | 0.01 |
| Warmup ratio / scheduler | 0.1 / cosine |
| Precision | BF16 |
| Seed | 1 |
The training inputs were raw recursive prompt strings, not Qwen chat-template
conversations. The training dataset itself is not included in this release.
The final weights, tokenizer, and generation configuration are unchanged from
the saved checkpoint. Optimizer states and pickled training arguments are omitted.
Recursive inference
The model returns one action per call:
SOLVE_DIRECTLY: solve the supplied problem.
DECOMPOSE: emit at least two standalone paths for the engine to execute.
AGGREGATE: combine the returned child answers when invoked by the engine.
Use the bundled prompts/recursive_sft_prefix_prompt.txt and
recursive_engine.py. Do not apply a chat template or expect a single
model.generate call to execute the complete recursive tree. The parser must
retain the protocol's special tokens when decoding.
pip install 'transformers==4.51.1' torch accelerate huggingface_hub
import sys
from pathlib import Path
from huggingface_hub import snapshot_download
snapshot = Path(snapshot_download("tawer12/qwen3-4b-recursive-sft-v3.1"))
sys.path.insert(0, str(snapshot))
from recursive_engine import RecursiveEngine, load_model_and_tokenizer
model, tokenizer = load_model_and_tokenizer(
str(snapshot), dtype="bf16", device_map="auto"
)
engine = RecursiveEngine(
model=model,
tokenizer=tokenizer,
prefix_template=(snapshot / "prompts/recursive_sft_prefix_prompt.txt").read_text(),
max_new_tokens=2048,
temperature=0.0,
top_p=1.0,
max_depth=3,
max_calls=10,
)
result = engine.rollout("What is the smallest multiple of 5 greater than -32?")
print(result.full_trace)
print(result.final_answer, result.parsed_ok, result.parse_errors)
The helper explicitly enables the generation KV cache even though the saved
training configuration has use_cache=false. device_map="auto" requires
Accelerate; inference performance depends on available device memory.
The engine source is a release-time snapshot, not a guarantee of bitwise
reproduction of every historical environment.
Evaluation and limitations
Historical recorded results, not corrected benchmark claims:
Table with columns: Evaluation, Sampling, Historical score| Evaluation | Sampling | Historical score |
|---|
| AMC23 mean@16 | 40 questions x 16 attempts, temperature 0.5 | 32.50% |
| AMC23 pass@16 | Same attempts; at least one recorded success per question | 80.00% |
| MATH5000 | 5,000 questions, greedy | 50.62% |
| MATH algebra | 1,187 algebra questions, separate greedy evaluation | 70.68% |
All used a limit of 2,048 new tokens per call, maximum depth 3, and maximum
10 calls per tree. AMC seeds were 5000 through 5015. top_p=1.0; top-k was
unspecified, preserving the generation library/checkpoint default. MATH5000
means the full 5,000-example MATH test set, not MATH-500.
Known grading problems: the historical recursive evaluator gates its
correct flag on parsing success. Answer normalization can reject equivalent
fractions and damage tuple/vector notation. Generic whole-trace extraction can
also select a child result or incidental number in an incomplete tree.
Do not treat these flags as authoritative mathematical judgments; regrade the
saved root answers consistently before making benchmark comparisons.
Syntactically valid decompositions may still contain dependent or underspecified
child tasks. Children receive fresh contexts. Aggregation sees child final-answer
summaries rather than their complete derivations, and can accept incorrect
results. The current engine executes children sequentially; its
critical-path-token statistic is not measured parallel wall-clock latency.
Attribution
The base model is from the Qwen team and is distributed under Apache 2.0; its
license is included in LICENSE. This repository contains a modified, fine-tuned
model with recursive protocol tokens and an inference helper.
GSM8K is the source of the curated training questions. Benchmark attribution and
third-party data-rights notes are in the linked evaluation dataset card.