fix(peft): preserve grouped expert LoRA routing semantics - #3902
Open
hasuoshenyun wants to merge 1 commit into
Open
hasuoshenyun wants to merge 1 commit into
hasuoshenyun wants to merge 1 commit into
Conversation
Signed-off-by: hasuoshenyun <1225541074@qq.com>
This was referenced Sep 16, 2026
hasuoshenyun
marked this pull request as ready for review
September 16, 2026 07:58
Author
This branch was successfully deployed
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.
What does this PR do ?
Fix ordinary grouped-expert LoRA so that adding an initially zero adapter does not unexpectedly change the parent expert's numerical behavior. Preserve its routing-weight placement, reduction order, dtype and backend settings, and handle empty routing safely. This PR does not add QAT.
Why this fix is independent of QAT
Wrapping an expert module with ordinary LoRA should preserve the original expert's configured behavior when the adapter update is zero. The previous wrapper did not consistently preserve projection dtype/backend settings or
apply_router_weight_after_down. In particular, a parent configured to apply routing probabilities after the down projection could instead apply them before that projection in the LoRA wrapper. These formulas are algebraically equivalent for a linear down projection, but BF16 rounding and top-k reduction order differ.Concretely, if the parent asks for
route_weight * down(activation), attaching LoRA should not silently switch it todown(route_weight * activation). This fix follows the parent's setting; it does not force all models to use one routing placement. V4's default pre-down placement remains intact, while GLM's configured post-down placement is honored. It also preserves existing projection storage and handles genuinely empty inputs without dereferencingx[0].This PR fixes that ordinary-LoRA baseline without adding quantizers. It also handles zero-token/fully-masked expert ranks, where the previous dummy path could index nonexistent
x[0]or leave expected gradient connections absent. The graph-connected zero returns zero numerical contribution while retaining explicit zero gradients; it does not add a loss or train unused experts with real data. Whether such connections are needed depends on the surrounding autograd/distributed contract, not a claim that every disconnected rank necessarily hangs.The routing, wrapper-storage and empty-route cases are separate regression-test groups. The empty-route expression is correctness-first rather than a claimed performance optimization; its full-tensor reductions and readability warrant review independently of the routing fix.
Changelog
apply_router_weight_after_downin additive expert LoRA without merging its weights or enabling QAT.Before your PR is "Ready for review"
Additional Information
This is the first prerequisite for targeted weight QAT. It intentionally fixes ordinary LoRA behavior and is separated from QAT to make that compatibility impact reviewable.
Before/after regression evidence
The same 164 newly added focused regression cases were run against the old implementation and the extracted standalone fix:
The 78 failures are reproduced defects in the old code, not failures remaining after the fix. The 86 cases that already passed continue to pass. These are targeted regression cases, not a claim that the upstream project's existing test suite previously had 78 failures.
The test groups cover parent-equivalent behavior with zero adapters, configured routing placement and reduction order, preservation of projection dtype/backend settings, and empty/fully masked inputs with zero-gradient connections.
Grouped-MM/DeepEP tests use CPU doubles and are not native-kernel validation. Broader integrated regression after rebasing passed 1454 tests with 53 conditional skips; that broader run also includes the dependent QAT work and is not evidence for this commit alone.
Native backend CI should run before merge. The author has marked this PR ready for review; the dependent QAT feature remains draft.