@@ -1027,7 +1027,7 @@ def test_eos_index_logic_uses_shape_check(self):
10271027 {
10281028 "input_ids" : np .array ([7 , 0 , 0 , 0 , 0 ], dtype = np .int64 ),
10291029 "seq_boundaries" : [0 , 5 ],
1030- "loss_mask" : np .ones ( 5 , dtype = np .int64 ),
1030+ "loss_mask" : np .array ([ 1 , 0 , 0 , 0 , 0 ] , dtype = np .int64 ),
10311031 }
10321032 ]
10331033
@@ -1056,7 +1056,7 @@ def test_static_metadata_keeps_logical_and_physical_boundaries_aligned(self):
10561056 {
10571057 "input_ids" : np .array ([7 , 0 , 0 , 0 , 0 ], dtype = np .int64 ),
10581058 "seq_boundaries" : [0 , 5 ],
1059- "loss_mask" : np .ones ( 5 , dtype = np .int64 ),
1059+ "loss_mask" : np .array ([ 1 , 0 , 0 , 0 , 0 ] , dtype = np .int64 ),
10601060 }
10611061 ]
10621062
@@ -1068,6 +1068,23 @@ def test_static_metadata_keeps_logical_and_physical_boundaries_aligned(self):
10681068 assert processed ["cu_seqlens_q_padded" ][0 ].tolist () == [0 , 4 , 8 , 8 , 8 ]
10691069 assert processed ["cu_seqlens_kv_padded" ][0 ].tolist () == [0 , 4 , 8 , 8 , 8 ]
10701070
1071+ def test_supervised_terminal_eos_precedes_zero_loss_padding (self ):
1072+ """A supervised EOS remains logical while later zero-loss EOS tokens are padding."""
1073+ dataset = _create_minimal_packed_dataset ()
1074+ batch = [
1075+ {
1076+ "input_ids" : np .array ([7 , 0 , 0 , 0 , 0 ], dtype = np .int64 ),
1077+ "seq_boundaries" : [0 , 5 ],
1078+ "loss_mask" : np .array ([1 , 1 , 0 , 0 , 0 ], dtype = np .int64 ),
1079+ }
1080+ ]
1081+
1082+ processed = dataset .collate_fn (batch )
1083+
1084+ assert processed ["cu_seqlens_q" ][0 ].tolist () == [0 , 2 ]
1085+ assert processed ["cu_seqlens_q_padded" ][0 ].tolist () == [0 , 4 ]
1086+ assert processed ["padding_mask" ].tolist () == [[False , False , True , True ]]
1087+
10711088 def test_without_alignment_padding_omits_physical_variants (self ):
10721089 """Identical logical and physical layouts use only the faster logical TE fields."""
10731090 dataset = _create_minimal_packed_dataset ()
@@ -1261,14 +1278,14 @@ def test_logical_cu_seqlens_uses_correct_eos(self):
12611278 dtype = np .int64 ,
12621279 ),
12631280 "seq_boundaries" : [0 , 5 , 10 ],
1264- "loss_mask" : np .ones ( 10 , dtype = np .int64 ),
1281+ "loss_mask" : np .array ([ 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 ] , dtype = np .int64 ),
12651282 }
12661283 ]
12671284
12681285 processed = dataset .collate_fn (batch )
12691286 cu_logical = processed ["cu_seqlens_q" ][0 ].tolist ()
12701287
1271- # Each non-EOS token contributes exactly once despite EOS padding.
1288+ # Each non-EOS token contributes exactly once despite zero-loss EOS padding.
12721289 assert cu_logical == [0 , 1 , 2 ]
12731290
12741291
0 commit comments