On-Policy Distillation Example#
This example shows how to run on-policy distillation (OPD) using vime. A small student (Qwen3-8B) is aligned to imitate a larger teacher (Qwen3-32B) by training only on the student’s own rollouts and matching the teacher’s token-level log-probabilities.
Key Features#
OPD is orthogonal to advantage estimators: OPD works as an additive KL penalty on top of any advantage estimator (GRPO, PPO, REINFORCE++, etc.), not as a separate estimator.
Two teacher modes:
vllm: Teacher runs on an external vLLM server; teacher log-probs are obtained during rollout.
megatron: Teacher is loaded directly into Megatron via
--opd-teacher-load; teacher log-probs are computed during the training forward pass.
Student rollout always uses vLLM (vime’s default rollout backend).
Key Arguments#
Argument |
Description |
|---|---|
|
Enable on-policy distillation. Required flag to use OPD. |
|
Type of OPD: |
|
OPD KL penalty coefficient (default: 1.0). |
|
Path to teacher checkpoint. Required when |
|
Optional checkpoint step for teacher model. |
Mode Comparison#
Mode |
Teacher Location |
When to use |
|---|---|---|
|
External vLLM server |
Teacher has different architecture or is larger than GPU memory |
|
Loaded into Megatron training |
Teacher has same architecture as policy/ref model |
Components#
vime/rollout/on_policy_distillation.pyimplements (for vLLM mode):reward_funccalls the teacher server (viaargs.rm_url) with every sample to obtain token-level logprobs.post_process_rewardstrims the teacher logprobs to the generated response span and writes the tensors back to eachSampleto compute advantages.
run-qwen3-8B-opd.shlaunches a vLLM teacher server, then submits a Ray job that runstrain.py.run-qwen3-8B-opd-megatron.shuses a Megatron-loaded teacher model (no external server needed).
Running the example#
Using vLLM Teacher (External Server)#
Download or prepare the required checkpoints and data.
hf download Qwen/Qwen3-32B --local-dir /root/Qwen3-32B
hf download Qwen/Qwen3-8B --local-dir /root/Qwen3-8B
hf download --repo-type dataset zhuzilin/dapo-math-17k --local-dir /root/dapo-math-17k
Run the hf to mcore for student model conversion:
cd /root/vime
source scripts/models/qwen3-8B.sh
PYTHONPATH=/root/Megatron-LM python tools/convert_hf_to_torch_dist.py \
${MODEL_ARGS[@]} \
--hf-checkpoint /root/Qwen3-8B \
--save /root/Qwen3-8B_torch_dist
Run on-policy distillation:
bash examples/on_policy_distillation/run-qwen3-8B-opd.sh
GPU layout:
GPUs |
Role |
|---|---|
0–3 |
Student Megatron train + student vLLM rollout (colocate) |
4–7 |
Teacher vLLM (Qwen3-32B, TP=4) |
Using Megatron Teacher (No External Server)#
Prepare student checkpoint (same as above).
IMPORTANT: Convert your teacher model to Megatron format (change the path to your actual teacher):
# This example uses the same model as both student and teacher (for demonstration only)
# In practice, use a different (stronger) model as the teacher!
cd /root/vime
source scripts/models/qwen3-8B.sh # Or your teacher model config
PYTHONPATH=/root/Megatron-LM python tools/convert_hf_to_torch_dist.py \
${MODEL_ARGS[@]} \
--hf-checkpoint /root/YourTeacherModel \
--save /root/YourTeacherModel_torch_dist
Edit
run-qwen3-8B-opd-megatron.shto update paths:Change
--opd-teacher-loadto your teacher model pathAdjust
--opd-kl-coefbased on your task
Run:
bash examples/on_policy_distillation/run-qwen3-8B-opd-megatron.sh
Preliminary Results#
End-to-end run with run-qwen3-8B-opd.sh (dapo-math-17k train, GRPO +
--opd-kl-coef 1.0, ~220 rollouts / iter_0000219). Offline GSM8K greedy eval:
Model |
GSM8K Accuracy |
|---|---|
Qwen3-8B (pre-OPD) |
79.7% (n=300) |
Qwen3-8B (post-OPD) |
88.2% (n=1319, +8.5 pp) |
Qwen3-32B teacher |
87.0% (n=300) |
Training health signal: rollout/opd_reverse_kl dropped from 0.145 → ~0.10
(−38%). Pure OPD uses raw_reward=0; the learning signal is the OPD KL term.
FAQ#
Why are there two OPD modes?
vllmmode: The teacher runs on an independent vLLM server. This is useful when the teacher has a different architecture or is too large to load together with the policy model.megatronmode: The teacher is loaded into Megatron using the same parameter loading mechanism as the reference model. This requires the teacher to have the same architecture as the policy model.
How do I use Megatron-based teacher instead of vLLM server? Replace your OPD arguments:
# Instead of: --use-opd --opd-type vllm --opd-kl-coef 1.0 # Use: --use-opd --opd-type megatron --opd-kl-coef 1.0 --opd-teacher-load /path/to/teacher_checkpoint
What happens if I set wrong arguments? The system will raise clear errors:
--use-opdwithout--opd-type: Error asking you to specify type--opd-type megatronwithout--opd-teacher-load: Error asking for teacher checkpoint--opd-type vllmwith--opd-teacher-load: Error indicating conflict
Why is
rollout/raw_rewardalways 0? Pure OPD distillation does not use an external reward model. The learning signal comes entirely from the OPD KL term applied to advantages.Self-distillation: why is
opd_reverse_klnear 0 at the start? Teacher and student start from the same weights, so reverse KL is ~0 until the student updates. For a true distillation signal, use a stronger / differently trained teacher (or--opd-type vllmwith Qwen3-32B).
References#
https://thinkingmachines.ai/blog/on-policy-distillation/
https://arxiv.org/abs/2306.13649
https://arxiv.org/abs/2306.08543