[bugfix] LoRA + TP>1 + sequence_parallel: sum grads of the replicated LoRA factor over the TP group (exported adapter had last-layer linear_proj.lora_B == 0) - #173
Open
hojuna wants to merge 1 commit into
Conversation
…r sequence_parallel
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.
Summary
With
tensor_model_parallel_size > 1andsequence_parallel=True, the replicated LoRA factor created byLoraParallelLinear.update_layer—lora_Bfor RowParallel targets (linear_proj,linear_fc2) andlora_Afor ColumnParallel targets (linear_qkv,linear_fc1) — only receives the gradient of its own TP rank's sequence shard, and that gradient is never summed over the TP group. Each TP rank therefore trains a different copy of the factor, andexport_weightssaves rank 0's copy only, so the exported adapter is not the model that was trained.lora_A(TERowParallelLinear) reduce-scatters its output, so the locallora_B(built with_build_local_te_linear) sees a different sequence shard on every TP rank.lora_Aconsumes the sequence-sharded input.finalize_model_gradsonly for params flaggedparam.sequence_parallel = True(as it does for layernorm weights).LoraParallelLinearnever sets the flag (tuners/patcher.pyonly marks the non-parallelLoraLinear).Not affected:
tensor_model_parallel_size=1, orsequence_parallel=False(the replicated factor then sees identical inputs on all TP ranks).Observed
ms-swift 4.4.2
megatron sft, mcore-bridge 1.5.2 (code path unchanged on currentmain), Qwen3.5-35B-A3B-FP8, TP4 / EP2,--sequence_parallel true, LoRA r=8 onlinear_qkv linear_proj,--save_safetensors true.layers.39.self_attn.o_proj.lora_B.weight == 0(exactly zero) at every checkpoint (100 … 541 steps) while itslora_Akeeps training normally on all 4 TP shards.save_checkpointafter 3 iterations (TP ranks 0-3 of DP rank 0):layers.39.linear_proj.lora_Blayers.35.linear_proj.lora_BFor the last layer, rank 0-2's shards (system prompt + image tokens, loss-masked) get exactly zero gradient, hence the all-zero tensor; deeper layers are silently different per rank rather than zero. With TP=1 / EP=8 the same run trains
layers.39.o_proj.lora_Bto 0.0075.Fix
Set
p.sequence_parallel = Trueon the parameters of the replicated factor (lora_bifis_parallel_aelselora_a) whentp_size > 1and sequence parallelism is enabled (router LoRA excluded). Megatron'sfinalize_model_gradsthen all-reduces (SUM) the gradient over the TP group.Verification
Same 3-iteration run with the fix: all 8 ranks hold identical values (
layers.35.linear_proj.lora_B= 0.007253,layers.39.linear_proj.lora_B= 0.007726 on every rank), the exported adapter has no all-zero tensors, andlayers.39.o_proj.lora_Bmatches the TP=1 result (0.0077 vs 0.0075).