flash_kd
Memory-efficient (vocab-chunked) cross-entropy + knowledge-distillation losses.
This is a simplified, forward-only distillation of the flash-KD kernel: it
computes per-token cross-entropy (student vs. ground-truth labels) and KL
divergence KL(P_teacher || P_student) without ever materializing the full
[num_tokens, vocab_size] logits/probability tensors in fp32.
Motivation: for large-vocab models (e.g. Qwen3.5 with vocab ~248k) the naive
similarity-metric path materializes several full-vocab fp32 tensors per sample
(softmax/log_softmax run in fp32 under autocast), which OOMs at long
sequence lengths. Here we stream over the vocab dimension in chunks and keep
only O(num_tokens) running statistics, using the online-softmax (running
max + rescale) trick so the result is numerically identical to the full
computation.
Only the forward pass is implemented (scoring runs under torch.no_grad);
there are no gradients, no Triton, and no tensor-parallel sharding — the loss is
computed on a single rank that holds the full vocab.
Functions
Compute per-token CE and KD losses by streaming over the vocab dimension. |
- flash_ce_kd_loss(student_logits, teacher_hidden, teacher_lm_head_weight, labels, *, temperature=1.0, ignore_index=-1, chunk_size=16384, upcast=True)
Compute per-token CE and KD losses by streaming over the vocab dimension.
The student side uses already-materialized
student_logits(sliced per chunk); the teacher side recomputes its logits chunk-by-chunk asteacher_hidden @ teacher_lm_head_weight[chunk].Tso the full teacher logits tensor is never materialized.- Parameters:
student_logits (Tensor) –
[N, V]student logits (N = number of tokens).teacher_hidden (Tensor) –
[N, D]teacher hidden states feeding its LM head.teacher_lm_head_weight (Tensor) –
[V, D]teacher LM-head weight (no bias).labels (Tensor) –
[N]ground-truth next-token ids;ignore_indexentries get a CE of 0 (matchingF.cross_entropy(..., reduction="none")).temperature (float) – KD softmax temperature (1.0 reproduces the plain
kl_divscoring metric: mean-per-tokenKL(P_T || P_S)).ignore_index (int) – label value to exclude from cross-entropy.
chunk_size (int) – number of vocab columns processed per step (memory knob).
upcast (bool) – accumulate in fp32 (recommended; matches the autocast path which runs
softmax/log_softmaxin fp32).
- Returns:
(ce_per_token, kd_per_token), each shape[N]in the accumulation dtype.ce_per_tokenis the standard cross-entropy;kd_per_tokenisKL(P_T || P_S)per token (NOT multiplied bytemperature**2).- Return type:
tuple[Tensor, Tensor]