[DistillationTrainer refactor] Heavy-clean the Liger path: share extraction with the chunked path#6537
[DistillationTrainer refactor] Heavy-clean the Liger path: share extraction with the chunked path#6537qgallouedec wants to merge 1 commit into
Conversation
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eb744e799f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return (loss, None) if return_outputs else loss | ||
|
|
||
| # Route the whole chunked loss (backbone + `lm_head` projection + JSD) through the DDP/FSDP wrapper via | ||
| # Route the whole loss (backbone + `lm_head` projection + JSD) through the DDP/FSDP wrapper via |
There was a problem hiding this comment.
Detect
logits_to_keep support on the teacher
When use_liger_kernel=True with different student and teacher architectures, this new common routing sends the Liger path through _get_last_hidden_state for the teacher. That helper decides whether to pass logits_to_keep using self.model_kwarg_keys, which was derived solely from the student signature, so a student that supports the argument paired with a same-vocabulary teacher backbone that rejects it now raises TypeError; the previous Liger implementation called the teacher decoder without this argument. Determine support separately for each model, or pass the appropriate capability into the shared extractor.
Useful? React with 👍 / 👎.
Item 34 (Group E) — stacked on PR 33. Part of #6449.
Keeps the Liger fused-JSD fast path (
use_liger_kernel=True) but heavy-cleans it: the two loss paths now share the same hidden-state extraction and differ only in the final loss call. Net −74 lines.compute_lossalways redirects_compute_lossthrough_forward_redirection(from item 33)._compute_lossextracts student hidden states (inside the student wrapper) + teacher hidden states (via the teacher's own redirection), then:if self.use_liger_loss:→self.liger_loss(...)over the flattened hidden states, withtrue_labelsbuilt fromcompletion_mask(hard-loss weight is 0, so only the ignore-mask matters; no shift —_get_last_hidden_stateis already completion-aligned), wrapped in the sharedmaybe_gather_lm_head_ctxfor ZeRO-3, then thenum_itemsglobal rescale._chunked_divergence_loss(...).Deleted (all superseded by the shared extraction + shared gather util):
_liger_student_forward,_compute_liger_loss,_get_liger_zero3_lm_head_gather_ctx(and its wrapping intraining_step/prediction_step);hasattr/getattrdecoder/bias probing;nullcontextimport.No
use_liger_kernelraise (reversing the earlier "delete Liger" plan — SFT parity, and the path is verified working). The config field stays.Test:
test_distillation_trainer_with_liger(train-smoke) replaced withtest_liger_loss_agrees_with_chunked— asserts the Liger loss equals the chunked loss on a fixed batch (rtol=1e-3), togglinguse_liger_losson one un-patched model so only the loss kernel differs. Suite green (52).Known limitation (pre-existing, unchanged): the Liger kernel does not apply
logit_scale/final_logit_softcapping, so on Gemma/Cohere it diverges slightly from the chunked path; the chunked default is exact. Worth a follow-up if Liger + those families matter.Note
Medium Risk
Changes core distillation loss routing and distributed (DDP/FSDP/ZeRO-3) behavior for the Liger path, though parity is now explicitly tested against the chunked path.
Overview
DistillationTrainer refactors the optional Liger fused-JSD path so it uses the same student/teacher hidden-state extraction and
_forward_redirectionwiring as the default chunked loss; only the final loss kernel differs.compute_lossno longer branches early for Liger—it always routes_compute_lossthrough the DDP/FSDP wrapper. Inside_compute_loss, whenuse_liger_lossis set, it callsLigerFusedLinearJSDLosson the shared hidden states withcompletion_mask-derivedtrue_labels,maybe_gather_lm_head_ctxfor ZeRO-3 lm_heads, and the samenum_items_in_batchrescale. The separate_liger_student_forward,_compute_liger_loss, and_get_liger_zero3_lm_head_gather_ctxhelpers are removed, along with ZeRO-3 gather wrappers intraining_stepandprediction_step.The Liger integration test is replaced with
test_liger_loss_agrees_with_chunked, which asserts Liger and chunked losses match on a fixed batch when onlyuse_liger_losstoggles.Reviewed by Cursor Bugbot for commit eb744e7. Bugbot is set up for automated code reviews on this repo. Configure here.