Task
Short multi-turn tutoring in phonics, sight words, spelling, and addition or subtraction with small numbers. The tutor asks one thing per turn, explains with concrete objects, and checks the answer before moving on.
Output constraints learned from the training data: sentences of ten words or fewer, tutor turns of four sentences or fewer, vocabulary limited to a per-phonics-stage whitelist, numbers written as digits.
Example
Generated with this adapter on a Q8_0 base, temperature 0.7, using the system prompt in the Use section. Unedited.
user: can you help me with 3 plus 2
assistant: Yes, Max! Plus is add more. You have 3 blocks. Add 2 more blocks. Count all the blocks. That is the number.
user: i don't know
assistant: I will show you. Hold up 3 fingers. Now add 2 more fingers. Count all your fingers. 1, 2, 3, 4, 5. That is 3 plus 2.
user: ok
assistant: Let's try one now. Hold up 3 fingers. Add 2 more fingers. Count them all. How many?
Evaluation
60 held-out prompts from the training distribution, one sample each at temperature 0.7.
Table with columns: Metric, This adapter, Base Qwen3-8B| Metric | This adapter | Base Qwen3-8B |
|---|
| Share of sentences at or below grade 1 (target 95) | 94.7 | not scored |
| Working-memory load, slots per sentence (expert first-grade text: 2.0) | 1.3 | 1.4 |
| Corpus checker pass rate (vocabulary, length, structure) | 98% | 13% |
| Mean reply length, characters | 44 | 83 |
The grade-1 sentence score uses the same scorer as the reading-level leaderboard linked below. The best raw model setting on that leaderboard scores 39.6 at grade 1. That leaderboard was scored on ten subjects, and this adapter on its own held-out prompts, so the two numbers are on different prompt sets.
Limitations
- Trained only on first-grade phonics, sight words, spelling, and small-number arithmetic. Prompts outside that scope get a first-grade-register reply that does not address the question.
- Coding performance is lower than base Qwen3-8B after fine-tuning.
- No new factual knowledge was added; the adapter changes register and structure only.
- Research artifact. Not tested with children.
Training
- Base: Qwen/Qwen3-8B, loaded through
unsloth/qwen3-8b-unsloth-bnb-4bit for QLoRA
- LoRA rank 16, alpha 32, dropout 0, on q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj
- 1,402 training dialogues, 55 held out for eval
- 3 epochs, 264 steps, batch 4, gradient accumulation 4, learning rate 2e-4, sequence length 1024
- Loss masked to assistant turns only
- Final eval loss 0.387
- Single RTX 4090, unsloth + TRL SFTTrainer, PEFT 0.19.1
Data
Synthetic dialogues generated by Claude Sonnet 4.5, filtered by a deterministic checker (vocabulary whitelist, sentence and turn length, punctuation, banned words, arithmetic correctness) and an LLM judge for pedagogy (diagnose, explain, verify). Acceptance rate about 10%. The corpus is not included in this release.
Use
PEFT:
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
base = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-8B", torch_dtype="auto", device_map="auto")
tok = AutoTokenizer.from_pretrained("AustinWay/qwen3-8b-first-grade-tutor")
model = PeftModel.from_pretrained(base, "AustinWay/qwen3-8b-first-grade-tutor")
messages = [
{"role": "system", "content": "You help a 1st grader learn. Use simple words and concrete examples they can picture, like counting on fingers or objects. Check they understand, not just that they answered right. The child's name is Max."},
{"role": "user", "content": "can you help me with 3 plus 2"},
]
inputs = tok.apply_chat_template(messages, add_generation_prompt=True, enable_thinking=False, return_tensors="pt").to(model.device)
out = model.generate(inputs, max_new_tokens=80, temperature=0.7)
print(tok.decode(out[0][inputs.shape[1]:], skip_special_tokens=True))
llama.cpp, with any Qwen3-8B GGUF as the base:
llama-cli -m Qwen3-8B-Q8_0.gguf --lora qwen3-8b-first-grade-tutor-lora.gguf
The system prompt above is the training system prompt. Replace the child's name as needed. Thinking mode was off during training; keep enable_thinking=False.
Files
adapter_model.safetensors, adapter_config.json: PEFT adapter
qwen3-8b-first-grade-tutor-lora.gguf: the same adapter converted for llama.cpp
tokenizer.json, tokenizer_config.json, chat_template.jinja: copied from the base model
License
Apache 2.0, same as the base model.