Fuse distillation + z-loss in the triton monolithic path (#507)#566
Merged
jlamypoirier merged 2 commits intoJul 15, 2026
Merged
Conversation
Add a distribution-family triton kernel alongside the label-family monolithic
kernel: distillation (the general full-distribution loss) with an optional
z-loss superposed over the same shared student softmax, so distillation configs
run on triton instead of falling back to the compiled path.
z-loss folds into the two from-distribution forward/backward kernels as a
student-probability coefficient (`2·grad_z·log_sum_exp`, no target term),
sharing distillation's loss mask and divisor; gated on its output pointer so it
is dead-code-eliminated when absent. `triton_entropy_loss_forward_backward`
gains an optional `z` slot and returns `(loss, z_loss, grad_logits)`.
`MonolithicLoss` dispatches to the distribution kernel when a distillation child
is present ({distillation} or {distillation, z_loss}); other combinations stay
on the label kernel or the compiled path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the duplicated triton child-finish loop into _triton_finish_children, shared by the label-family and distribution-family drivers; trim a redundant parenthetical in the masked-row comment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Claude Opus 4.8 note: authored with Claude Code on the user's behalf.
Part of the monolithic head-loss work (#507), stacked on #549 ← #558.
What it does
Distillation was the one combinable loss with no slot in the triton monolithic kernel, so any
monolithicloss containing it fell back to the compiled path — even though distillation already has a perfectly good standalone triton kernel. This adds a second fused triton kernel so distillation configs run on triton.The label-family kernel (
ce/z/grpo/gspo) and the distribution-family loss don't share a gradient shape — the label losses superpose a one-hot target (grad_j = prob_coeff·softmax_j − label_coeff·δ), while distillation's target is a full teacher distribution. Rather than force both into one kernel,MonolithicLossnow picks between two fused kernels by child kind:{ce, z, grpo, gspo}→ the existing monolithic kernel (unchanged);{distillation}or{distillation, z_loss}→ the existing from-distribution forward/backward kernels, extended to also emit z-loss over the same shared student softmax.z-loss folds in as a pure student-probability coefficient —
grad_j += 2·grad_z·log_sum_exp · student_prob_j, forward scalarlog_sum_exp²— reusing values the distillation kernel already computes. It's direction-agnostic (cross-entropy / forward-KL / reverse-KL) and shares distillation's loss mask and divisor (both come from the same_get_loss_mask/ label-count on the head). The term is gated on its output pointer, so it's dead-code-eliminated when no z-loss is present, leaving the standalone distillation path bit-for-bit unchanged.Distillation mixed with a label or policy loss under
use_tritonis rejected at config validation (it can't share either kernel) and falls to the compiled path, which already fuses those combinations.Changes
functional/triton/entropy_loss.py— optional z slot in both from-distribution f/b kernels;triton_entropy_loss_forward_backwardgains azargument and returns(loss, z_loss, grad_logits).loss/monolithic.py— kernel selection by child kind; new distribution dispatch method;_TritonContextdistillation slot.loss/entropy_loss.py,loss/config.py— distillationtriton_kind, its_TritonContextpack/read, and relaxed monolithic validation.test_lm_headfused_tritondistillation configs.Validation
On an H100 (
FAST_LLM_SKIP_TRITON_AUTOTUNE=TRUE):test_lm_losses.py— 586 passed / 21 skipped, including the new distillation-triton parity test across CE / forward-KL / reverse-KL, masking, scaling, fp16, and gradient accumulation, and theworld_size=2tensor-parallel subtests.test_lm_head.py— 189 passed, including the newfused_triton_distillation_loss/_and_z_loss/_loss_temperatureconfigs (split and masked variants), exercising theMonolithicLossdispatch end to end.The 21 skips are the pre-existing
reverse_kl-with-labels combinations. As with the rest of the monolithic triton path, the kernel can't run underTRITON_INTERPRET=1(aconstexpr-shaped grid trips anInterpreterError, reproducing on the base branch), so validation is GPU-only.🤖 Generated with Claude Code