Auto-select the monolithic head-loss implementation (#507)#568
Merged
jlamypoirier merged 4 commits intoJul 20, 2026
Conversation
Losses stay configured flat: the head groups combinable losses that share a softmax into one fused kernel and picks the backend from a single head-level `loss_implementation` knob (auto/compiled/triton/per_loss, default `auto`). `auto` uses triton when a group is triton-eligible and triton is available, else the compiled path; `per_loss` keeps the unfused per-loss behavior. Grouping is by effective logits scale (one softmax serves one scale); non-combinable losses (e.g. DPO) stay standalone. The nested `type: monolithic` loss is removed as a user-facing concept — `MonolithicLossConfig` is now synthesized internally by `LanguageModelHeadConfig.get_effective_losses`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…507) Guard against a user loss whose name collides with a synthesized fused-group key (which would silently drop an entry), mirroring the `lm_head_loss` reserved name. Split a compound initializer and trim a redundant comment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The distributed-consistency model tests compare gradients across parallel layouts. GRPO/GSPO clip the importance-sampling ratio at `1 ± epsilon`, and that clip bound is a discontinuity: tiny floating-point differences between layouts (single-GPU vs pipeline/tensor-parallel reduction order) flip a token or segment across the boundary, changing its gradient contribution discontinuously and intermittently blowing past the comparison tolerance — the same failure mode as MoE top-k routing. Disable the clip (large epsilons) for the `llama_grpo`/`llama_gspo` model configs so the comparison is smooth. The clip itself stays covered by the single-GPU `test_lm_losses`/`test_lm_head` tests, which don't compare across layouts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ments (#507) - Reserve only the synthesized fused-group names (monolithic / monolithic_<index>) instead of the whole `monolithic` prefix, so flat loss names like `monolithic_kd` are allowed. - Rename `named` -> `multiple_groups` and annotate the `effective` local. - Drop redundant per-member comments on `LossImplementation`, keeping only the non-obvious `auto` fallback note. 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 behalf of @jlamypoirier.
Stacked on #549 (
jlp_monolithic_head_loss); this PR only adds the config-ergonomics layer on top of the monolithic kernels.Motivation
Using the fused kernels currently requires restructuring the head config into a nested
monolithicwrapper and hand-settinguse_triton:That nested type appears in no example/production config. This PR lets losses stay flat and picks the implementation automatically:
What changed
loss_implementationhead knob{auto, compiled, triton, per_loss}, defaultauto.auto: fuse combinable losses; use triton when a group is triton-eligible and triton is available, else the compiled path.compiled/triton: force a fused backend (tritonerrors at config time on an ineligible set).per_loss: unfused per-loss behavior (the pre-change path).LanguageModelHeadConfig.get_effective_losses()applies the default-CE fallback and groups combinable losses by effective logits scale (one softmax serves one scale) into an internally-synthesizedMonolithicLossConfig. Non-combinable losses (e.g. DPO) stay standalone. Called from_validate, so--validatecatches an ineligibletritonset early.type: monolithicfrom the dynamic-type registry; the class stays as the internal grouping vehicle. The head build loop,has_main_loss/registration logic, and metric names are unchanged.Behavior note
autois the default, so it changes the realized kernel for existing configs (including plain single-CE), moving them onto the fused path. Equivalence toper_lossis covered by the head/loss parity tests (rms-close; the fused path accumulates in fp32 and casts once, so it is at least as accurate).per_lossremains the escape hatch.Tests
test_get_effective_losses(new): grouping by scale, singleton wrapping, DPO standalone, backend mapping, and config-time rejection of an ineligibletritonset.tests/layers/test_lm_head.pybuilds losses flat and drives the backend throughloss_implementation(drops the manual wrapping); addsautodistillation variants (interpreter-safe distribution kernel).tests/layers/test_lm_losses.pyunchanged (it exercises the kernels directly, not via the registry).CPU validation green:
test_lm_head.py144 passed / 54 skipped (skips = triton, unavailable on CPU),test_lm_losses.py586 passed / 21 skipped, andfast-llm train gpt --config examples/mistral.yaml --validateaccepts the new default. Not yet run on GPU: the triton label-family paths,auto→triton, and the fulltests/modelssuite (the default-kernel change).🤖 Generated with Claude Code