@@ -197,6 +197,34 @@ def create_and_check_loss(self, config, input_ids, input_mask, sequence_labels,
197197 ).sum ()
198198 self .parent .assertTrue (paddle .allclose (result .loss , expected_loss , rtol = 1e-5 , atol = 1e-5 ))
199199
200+ def create_and_check_loss_mask (self , config , input_ids ):
201+ model = GraniteForCausalLM (config )
202+ model .eval ()
203+ labels = input_ids .clone ()
204+ loss_mask = paddle .ones_like (input_ids )
205+ loss_mask [:, 2 :4 ] = 0
206+ result = model (input_ids , labels = labels , loss_mask = loss_mask , return_dict = True )
207+
208+ shift_logits = result .logits [:, :- 1 ].reshape ([- 1 , config .vocab_size ])
209+ shift_labels = labels [:, 1 :].reshape ([- 1 ])
210+ valid = (shift_labels != - 100 ) & paddle .cast (loss_mask [:, 1 :].reshape ([- 1 ]), paddle .bool )
211+ safe_labels = paddle .where (valid , shift_labels , paddle .zeros_like (shift_labels ))
212+ selected_log_probs = paddle .take_along_axis (
213+ paddle .nn .functional .log_softmax (shift_logits , axis = - 1 ), safe_labels .unsqueeze (- 1 ), axis = - 1
214+ ).squeeze (- 1 )
215+ valid_float = paddle .cast (valid , selected_log_probs .dtype )
216+ expected_loss = - (selected_log_probs * valid_float ).sum () / paddle .clip (valid_float .sum (), min = 1.0 )
217+ self .parent .assertTrue (paddle .allclose (result .loss , expected_loss , rtol = 1e-5 , atol = 1e-5 ))
218+
219+ empty_loss = model (
220+ input_ids ,
221+ labels = labels ,
222+ loss_mask = paddle .zeros_like (input_ids ),
223+ return_dict = True ,
224+ ).loss
225+ self .parent .assertTrue (paddle .isfinite (empty_loss ).item ())
226+ self .parent .assertEqual (empty_loss .item (), 0.0 )
227+
200228 def create_and_check_generate (self , config , input_ids , input_mask ):
201229 model = GraniteForCausalLM (config )
202230 model .eval ()
@@ -268,6 +296,10 @@ def test_loss(self):
268296 config_and_inputs = self .model_tester .prepare_config_and_inputs ()
269297 self .model_tester .create_and_check_loss (* config_and_inputs )
270298
299+ def test_loss_mask (self ):
300+ config_and_inputs = self .model_tester .prepare_config_and_inputs ()
301+ self .model_tester .create_and_check_loss_mask (* config_and_inputs [:2 ])
302+
271303 def test_generate (self ):
272304 config_and_inputs = self .model_tester .prepare_config_and_inputs ()
273305 self .model_tester .create_and_check_generate (* config_and_inputs [:3 ])
0 commit comments