Multi-Teacher On-Policy Distillation
Kimi K3
Medium
Problem
Multi-Teacher On-Policy Distillation selects one teacher for every batch item. Student logits have shape (B,S,V) for batch size B, sequence length S, and vocabulary size V. Teacher logits have shape (3,3,B,S,V): the first axis selects the domain and the second selects the reasoning-effort level. Domain and effort index tensors each have shape (B), and sampled token identifiers have shape (B,S).
For sampled token y_{b,t}, use the two index tensors to select the teacher logits for batch item b, compute student and selected-teacher log probabilities with log-softmax, and gather the probability of y_{b,t}. For positive clipping threshold R_{\max}, compute
r_{b,t}=\operatorname{clip}\left(\operatorname{stopgrad}\left[\log\pi_{\mathrm{teacher}}^{(d_b,e_b)}(y_{b,t})-\log\pi_\theta(y_{b,t})\right],-R_{\max},R_{\max}\right).
The reward must have no gradient connection to either policy. Return a dictionary with rewards and teacher_token_log_probs. Both tensors have shape (B,S) and preserve the logits dtype and device.
Theory
Multi-Teacher On-Policy Distillation gives a student model a dense reward for tokens it sampled itself. For each batch item, the correct teacher is chosen by domain and reasoning-effort indices. The reward compares how much probability that teacher and the student assigned to the sampled token.
Why there are several teachers
Kimi K3 uses specialized policies for different domains and reasoning efforts, then consolidates their capabilities into one student. In this exercise, teacher logits have two selection axes: three domains and three effort levels. Together they represent nine possible teachers.
Every batch item selects exactly one of those nine teachers. Once selected, that teacher supplies logits for all sequence positions of that item. Domain and effort selection happens per batch item, not per token.
The function does not average teachers. Mixing their logits would create a distribution that belongs to none of the specialized policies.
Compare the sampled token only
Student and teacher tensors contain a score for every vocabulary item, but the rollout already tells us which token was sampled at each position. Convert logits to log probabilities with log-softmax, then gather the log probability at that sampled token identifier.
For a sampled token y_{b,t}, the unclipped log-ratio reward is
\log\pi_{\mathrm{teacher}}(y_{b,t})-\log\pi_\theta(y_{b,t})
This value is positive when the selected teacher considered the sampled token more likely than the student did. It is negative when the student assigned more probability than the teacher.
Use log-softmax rather than taking softmax and then logarithm. Log-softmax performs the same mathematics more stably when logits have large magnitudes.
Stop gradients through the reward
The reward is a training signal, not a differentiable path back into the teacher or student probabilities used to calculate it. Detach the log-probability difference before returning the reward.
The selected teacher log probabilities are returned separately and should preserve their ordinary values. The prompt only requires the reward tensor to have no gradient connection. Detaching the reward after subtraction is the clearest way to satisfy this.
Clip extreme comparisons
Very large log-ratios can dominate learning. Clamp the detached difference to the inclusive interval from negative threshold to positive threshold:
r_{b,t}=\operatorname{clip}\left(\operatorname{stopgrad}[\log\pi_T-\log\pi_S],-R_{\max},R_{\max}\right)
Clipping happens after computing the log-probability difference. Clipping logits or individual log probabilities would change which distribution is being compared.
A small probability example
Suppose the selected teacher assigns probability 0.6 to a sampled token, while the student assigns 0.2. The log-ratio is
\log(0.6)-\log(0.2)=\log(3)\approx1.099
With a clipping threshold of 1.0, the returned reward is 1.0. If teacher and student probabilities are equal, the reward is zero. If the teacher gives the token lower probability, the reward is negative.
The selected teacher log probability in this example is \log(0.6). It is returned alongside the clipped reward, not converted back into a probability.
Select teachers with paired batch indices
The domain index and effort index for batch item b must be used together with that same batch index. This is paired advanced indexing, not a Cartesian selection of all domains, efforts, and batch items.
After teacher selection, both the chosen teacher logits and student logits have one batch, sequence, and vocabulary axis. Gathering sampled token IDs along the vocabulary axis leaves a batch-by-sequence result.
Implementation order
- Use each batch item's domain and effort indices to select one teacher logit sequence.
- Apply log-softmax across vocabulary to student logits and selected teacher logits.
- Gather each model's log probability for the supplied sampled token at every position.
- Subtract student token log probability from teacher token log probability.
- Detach this difference and clamp it to the requested interval.
- Return clipped rewards followed by selected teacher token log probabilities.
Common mistakes to avoid
- Averaging all nine teachers. Each batch item uses one selected teacher.
- Gathering before log-softmax. A single logit is not a log probability because normalization needs the full vocabulary.
- Comparing the most likely token. Compare the supplied sampled token, even when it is not an argmax.
- Leaving reward attached to the graph. The log-ratio reward must be stopped from backpropagating.
- Clipping teacher and student values separately. Clip only their final difference.
Examples
Example 1
- Input
student_logits = [[[0,0]]], teacher_logits = [[[[[0,-0.02]]],[[[-0.24,-0.14]]],[[[-0.48,-0.26]]]],[[[[0.15,0.28]]],[[[-0.09,0.16]]],[[[-0.33,0.04]]]],[[[[0.3,0.58]]],[[[0.06,0.46]]],[[[-0.18,0.34]]]]], domain_indices = [0], effort_indices = [0], sampled_tokens = [[0]], clip_threshold = 2- Output
{"rewards": tensor([[0.009950000833311101]]), "teacher_token_log_probs": tensor([[-0.6831971797266342]])}- Explanation
- The selected teacher gives token 0 a slightly higher log probability than the student, producing a small positive unclipped reward.
Example 2
- Input
student_logits.shape = (2, 2, 3), teacher_logits.shape = (3, 3, 2, 2, 3), domain_indices.shape = effort_indices.shape = (2,), sampled_tokens.shape = (2, 2), clip_threshold = 1.5- Output
{"rewards": tensor of shape (2, 2), "teacher_token_log_probs": tensor of shape (2, 2)}
Example 3
- Input
student_logits.shape = (1, 2, 2), teacher_logits.shape = (3, 3, 1, 2, 2), domain_indices.shape = effort_indices.shape = (1,), sampled_tokens.shape = (1, 2), clip_threshold = 0.75- Output
{"rewards": tensor of shape (1, 2), "teacher_token_log_probs": tensor of shape (1, 2)}
Hints
- Use batch indices together with domain and effort indices to select one teacher tensor per item.
- Apply log-softmax before gathering the sampled-token positions.
- Detach the log-probability difference before clipping it to the reward interval.
Requirements
- Return a dictionary with exactly rewards and teacher_token_log_probs. Both tensors have shape (batch, sequence).
- Reward values lie within the inclusive clipping interval.
- The reward tensor has no gradient connection to either policy.
- Preserve floating-point dtype and device.
Constraints
- Teacher logits have leading dimensions (3, 3, batch, sequence, vocabulary).
- Domain and effort indices lie in [0, 2].
- Sampled token indices are valid vocabulary positions.
- Clipping threshold is positive.
Starter Code
import torch
def multi_teacher_opd_reward(student_logits: torch.Tensor, teacher_logits: torch.Tensor, domain_indices: torch.Tensor, effort_indices: torch.Tensor, sampled_tokens: torch.Tensor, clip_threshold: float) -> dict[str, torch.Tensor]:
"""
Returns a dictionary containing clipped rewards and selected teacher token log probabilities.
"""
passTest Cases
| Case | Matches | |
|---|---|---|
| Teacher and student agreement | — | public |
| Mixed teacher selection | — | public |
| Reward clipping | — | public |