@@ -42,7 +42,8 @@ def test_orthogonalized_optimizer_core_matches_sgd(self, shape) -> None:
4242 momentum_beta = 0 ,
4343 use_nesterov = False ,
4444 weight_decay = 0.5 ,
45- use_decoupled_weight_decay = True ,
45+ use_decoupled_wd = True ,
46+ use_independent_wd = False ,
4647 fp32_matmul_prec = "highest" ,
4748 )
4849
@@ -83,7 +84,8 @@ def test_orthogonalized_optimizer_core_matches_sgd_with_momentum(self, shape) ->
8384 momentum_beta = 0.5 ,
8485 use_nesterov = False ,
8586 weight_decay = 0.0 ,
86- use_decoupled_weight_decay = False ,
87+ use_decoupled_wd = False ,
88+ use_independent_wd = False ,
8789 fp32_matmul_prec = "highest" ,
8890 )
8991
@@ -133,7 +135,8 @@ def dummy_interleaved_split_orth_fn(x: torch.Tensor) -> torch.Tensor:
133135 momentum_beta = 0 ,
134136 use_nesterov = False ,
135137 weight_decay = 0.0 ,
136- use_decoupled_weight_decay = False ,
138+ use_decoupled_wd = False ,
139+ use_independent_wd = False ,
137140 fp32_matmul_prec = "highest" ,
138141 scaled_orthogonalize_fn = dummy_interleaved_split_orth_fn ,
139142 )
@@ -185,6 +188,35 @@ def test_use_syrk_match_without_syrk(self) -> None:
185188 ref_param .data ,
186189 )
187190
191+ def test_use_independent_wd (self ) -> None :
192+ """Test that use_independent_wd properly decouples weight decay from learning rate."""
193+ shape = (32 , 32 )
194+ weight_decay = 0.25
195+
196+ # Test with independent weight decay: with lr=0, weight decay should still be applied
197+ # With lr=0, no gradient update occurs, so param should be exactly (1-wd)*param
198+ indep_param = nn .Parameter (torch .randint (- 5 , 5 , shape , dtype = torch .float32 , device = "cuda" ))
199+ indep_param_initial = indep_param .data .clone ()
200+ indep_param .grad = torch .randint_like (indep_param , - 5 , 5 )
201+
202+ muon_opt_indep = muon .Muon (
203+ [indep_param ],
204+ lr = 0.0 , # Zero learning rate
205+ weight_decay = weight_decay ,
206+ use_independent_wd = True ,
207+ momentum_beta = 0.0 ,
208+ )
209+ muon_opt_indep .step ()
210+
211+ # With independent weight decay and lr=0, param should be exactly (1-wd)*param
212+ expected_param = (1 - weight_decay ) * indep_param_initial
213+ torch .testing .assert_close (
214+ indep_param .data ,
215+ expected_param ,
216+ atol = 0 ,
217+ rtol = 0 ,
218+ )
219+
188220
189221if __name__ == "__main__" :
190222 absltest .main ()
0 commit comments