@@ -1996,18 +1996,17 @@ def test_grouped_expert_scales_bottleneck_before_grouped_output_projection(self)
19961996 in_features = 2 ,
19971997 out_features = 2 ,
19981998 dim = 2 ,
1999- alpha = 4 ,
2000- num_local_experts = 2 ,
1999+ alpha = 3 ,
2000+ num_local_experts = 3 ,
20012001 base_linear_name = "decoder.layers.0.mlp.experts.linear_fc2" ,
20022002 activation = "identity" ,
20032003 input_is_parallel = False ,
20042004 model_parallel_config = MockModelParallelConfig (),
20052005 )
20062006 with torch .no_grad ():
2007- adapter .linear_in .weight [0 ].copy_ (torch .eye (2 ))
2008- adapter .linear_in .weight [1 ].copy_ (torch .eye (2 ))
2009- adapter .linear_out .weight [0 ].copy_ (torch .eye (2 ))
2010- adapter .linear_out .weight [1 ].copy_ (torch .eye (2 ))
2007+ for expert_idx in range (3 ):
2008+ adapter .linear_in .weight [expert_idx ].copy_ (torch .eye (2 ))
2009+ adapter .linear_out .weight [expert_idx ].copy_ (torch .eye (2 ))
20112010
20122011 projection_inputs = {}
20132012 original_projection = GroupedExpertLinearAdapter ._forward_grouped_projection
@@ -2034,10 +2033,10 @@ def fake_grouped_mm(inputs, weights, *, offs):
20342033 create = True ,
20352034 ),
20362035 ):
2037- output = adapter (x , [1 , 2 ])
2036+ output = adapter (x , [1 , 0 , 2 ])
20382037
20392038 scale = adapter .alpha / adapter .dim
2040- assert scale == 2.0
2039+ assert scale == 1.5
20412040 # The output projection consumes the already-scaled bottleneck, so no
20422041 # full-width temporary is needed to apply the scale afterwards.
20432042 torch .testing .assert_close (projection_inputs ["linear_out" ], projection_inputs ["linear_in" ] * scale )
@@ -2049,7 +2048,7 @@ def test_grouped_expert_per_expert_fallback_still_applies_lora_scaling(self):
20492048 in_features = 2 ,
20502049 out_features = 2 ,
20512050 dim = 2 ,
2052- alpha = 4 ,
2051+ alpha = 3 ,
20532052 num_local_experts = 2 ,
20542053 base_linear_name = "decoder.layers.0.mlp.experts.linear_fc2" ,
20552054 activation = "identity" ,
@@ -2062,11 +2061,17 @@ def test_grouped_expert_per_expert_fallback_still_applies_lora_scaling(self):
20622061 adapter .linear_out .weight [0 ].copy_ (torch .eye (2 ))
20632062 adapter .linear_out .weight [1 ].copy_ (torch .eye (2 ))
20642063
2065- x = torch .tensor ([[1.0 , 2.0 ], [3.0 , 4.0 ], [5.0 , 6.0 ]])
2064+ x = torch .tensor ([[1.0 , 2.0 ], [3.0 , 4.0 ], [5.0 , 6.0 ]], requires_grad = True )
20662065 with patch .object (GroupedExpertLinearAdapter , "_can_use_grouped_mm" , return_value = False ):
20672066 output = adapter (x , [1 , 2 ])
20682067
2069- torch .testing .assert_close (output , x * (adapter .alpha / adapter .dim ))
2068+ scale = adapter .alpha / adapter .dim
2069+ assert scale == 1.5
2070+ torch .testing .assert_close (output , x * scale )
2071+ output .sum ().backward ()
2072+ torch .testing .assert_close (x .grad , torch .full_like (x , scale ))
2073+ assert torch .isfinite (adapter .linear_in .weight .grad ).all ()
2074+ assert torch .isfinite (adapter .linear_out .weight .grad ).all ()
20702075
20712076 def test_grouped_expert_linear_adapter_fp8_without_te_uses_fallback (self ):
20722077 """An unsupported FP8 layout should not silently run the public BF16 grouped backend."""
@@ -2253,6 +2258,7 @@ def test_grouped_expert_linear_adapter_public_grouped_mm_forward_backward(self):
22532258 in_features = 16 ,
22542259 out_features = 16 ,
22552260 dim = 8 ,
2261+ alpha = 12 ,
22562262 num_local_experts = 2 ,
22572263 base_linear_name = "decoder.layers.0.mlp.experts.linear_fc2" ,
22582264 activation = "identity" ,
@@ -2272,6 +2278,7 @@ def test_grouped_expert_linear_adapter_public_grouped_mm_forward_backward(self):
22722278 expected_chunks = []
22732279 for expert_idx , expert_input in enumerate (reference_x .split ([2 , 3 ])):
22742280 hidden = nn .functional .linear (expert_input , reference_linear_in [expert_idx ])
2281+ hidden = hidden * (adapter .alpha / adapter .dim )
22752282 expected_chunks .append (nn .functional .linear (hidden , reference_linear_out [expert_idx ]))
22762283 expected = torch .cat (expected_chunks )
22772284 expected .float ().sum ().backward ()
@@ -2298,6 +2305,7 @@ def test_grouped_expert_linear_adapter_te_fp8_forward_backward_and_inference(sel
22982305 in_features = 16 ,
22992306 out_features = 16 ,
23002307 dim = 16 ,
2308+ alpha = 24 ,
23012309 num_local_experts = 2 ,
23022310 base_linear_name = "decoder.layers.0.mlp.experts.linear_fc2" ,
23032311 activation = "identity" ,
@@ -2316,6 +2324,7 @@ def test_grouped_expert_linear_adapter_te_fp8_forward_backward_and_inference(sel
23162324 expected_chunks = []
23172325 for expert_idx , expert_input in enumerate (reference_x .split ([2 , 3 ])):
23182326 hidden = nn .functional .linear (expert_input , reference_linear_in [expert_idx ])
2327+ hidden = hidden * (adapter .alpha / adapter .dim )
23192328 expected_chunks .append (nn .functional .linear (hidden , reference_linear_out [expert_idx ]))
23202329 expected = torch .cat (expected_chunks )
23212330 expected .float ().sum ().backward ()
@@ -2872,12 +2881,16 @@ def linear_out(x, *args):
28722881 def test_scales_bottleneck_before_output_projection (self , is_fc1 ):
28732882 """Scaling must land on the rank-sized bottleneck for both fc1 and fc2 wiring."""
28742883 recorded = {}
2875- adapter = self ._stub_adapter (is_fc1 = is_fc1 , alpha = 4 , dim = 2 , recorded = recorded )
2876- x = torch .tensor ([[1.0 , 2.0 ], [3.0 , 4.0 ]])
2884+ adapter = self ._stub_adapter (is_fc1 = is_fc1 , alpha = 3 , dim = 2 , recorded = recorded )
2885+ x = torch .tensor ([[1.0 , 2.0 ], [3.0 , 4.0 ]], requires_grad = True )
28772886
28782887 output = SharedOuterGroupedExpertAdapter .forward (adapter , x , m_splits = [1 , 1 ])
28792888
28802889 # The output projection receives the scaled bottleneck, so applying the
28812890 # scale never allocates a second full-width tensor.
2882- torch .testing .assert_close (recorded ["linear_out_input" ], x * 2.0 )
2883- torch .testing .assert_close (output , x * 2.0 )
2891+ scale = adapter .alpha / adapter .dim
2892+ assert scale == 1.5
2893+ torch .testing .assert_close (recorded ["linear_out_input" ], x * scale )
2894+ torch .testing .assert_close (output , x * scale )
2895+ output .sum ().backward ()
2896+ torch .testing .assert_close (x .grad , torch .full_like (x , scale ))
0 commit comments