@@ -263,13 +263,18 @@ def prepare_prefix_suffix_ids(
263263 max_seq_len : Optional [int ] = None ,
264264 truncate : Literal ["max" , "block" , None ] = "block" ,
265265 loss_on_padding : bool = True ,
266+ suffix_block_size : Optional [int ] = None ,
266267) -> MLMBatch :
267268 """Prepare concatenated prefix and suffix ids for seq2seq tasks with padding on the right only
268269
269270 Args:
270271 loss_on_padding: bool
271272 - If true, pad token is treated as a normal token: it has attention on it, it is predicted as a target token.
272273 - If false, it has no attention on it, it is not predicted as a target token (-100)
274+ suffix_block_size: When set, reserve exactly this many suffix tokens after the prefix
275+ (suffix + EOS padded/truncated to fit). Positions beyond ``prefix + BOS +
276+ suffix_block_size`` are attention-hidden and excluded from MLM masking and loss,
277+ matching inference ``max_new_tokens``.
273278 """
274279 input_ids : List [TT ] = []
275280 attention_mask : List [TT ] = []
@@ -280,10 +285,16 @@ def prepare_prefix_suffix_ids(
280285 bos_token_id is not None
281286 ) # always add bos before the suffix. Otherwise it is not needed.
282287 if truncate in ["max" , None ]:
283- max_len = max (
284- len (_prefix_ids ) + len (_suffix_ids ) + add_eos + add_bos
285- for _prefix_ids , _suffix_ids in zip (prefix_ids , suffix_ids )
286- )
288+ if suffix_block_size is not None :
289+ max_len = max (
290+ len (_prefix_ids ) + add_bos + suffix_block_size
291+ for _prefix_ids , _suffix_ids in zip (prefix_ids , suffix_ids )
292+ )
293+ else :
294+ max_len = max (
295+ len (_prefix_ids ) + len (_suffix_ids ) + add_eos + add_bos
296+ for _prefix_ids , _suffix_ids in zip (prefix_ids , suffix_ids )
297+ )
287298 if truncate == "max" and max_seq_len is not None :
288299 max_len = max (max_len , max_seq_len )
289300 elif truncate == "block" and max_seq_len is not None :
@@ -296,58 +307,99 @@ def prepare_prefix_suffix_ids(
296307 for i , (_prefix_ids , _suffix_ids ) in enumerate (
297308 zip (prefix_ids , suffix_ids )
298309 ):
299- # bos should not be masked
300- suffix_mask = pad_truncate_list (
301- [0 ] * (len (_prefix_ids ) + add_bos )
302- + [1 ] * (len (_suffix_ids ) + add_eos ),
303- max_len ,
304- 1 ,
305- pad_left = False ,
306- )
307- temp = pad_truncate_list (
308- _prefix_ids
309- + ([bos_token_id ] * add_bos )
310- + _suffix_ids
311- + ([eos_token_id ] * add_eos ),
312- max_len ,
313- pad_token_id ,
314- pad_left = False ,
315- )
316- _mask = (torch .rand (len (temp )) < t [i ]).logical_and (
317- torch .tensor (suffix_mask , dtype = torch .bool )
318- )
319- _input_ids = torch .tensor (temp , dtype = torch .long )
320- input_ids .append (_input_ids )
321- if loss_on_padding :
322- attention_mask .append (
323- torch .tensor ([1 ] * len (temp ), dtype = torch .bool )
310+ if suffix_block_size is not None :
311+ suffix_slot = pad_truncate_list (
312+ _suffix_ids + [eos_token_id ] * add_eos ,
313+ suffix_block_size ,
314+ pad_token_id ,
315+ pad_left = False ,
324316 )
325- target_ids .append (_input_ids .clone ())
317+ content = (
318+ _prefix_ids + ([bos_token_id ] * add_bos ) + suffix_slot
319+ )
320+ visible_len = len (_prefix_ids ) + add_bos + suffix_block_size
321+ temp = pad_truncate_list (
322+ content , max_len , pad_token_id , pad_left = False
323+ )
324+ effective_visible = min (visible_len , len (temp ))
325+ suffix_mask = pad_truncate_list (
326+ [0 ] * (len (_prefix_ids ) + add_bos )
327+ + [1 ] * suffix_block_size ,
328+ max_len ,
329+ 0 ,
330+ pad_left = False ,
331+ )
332+ _mask = (torch .rand (len (temp )) < t [i ]).logical_and (
333+ torch .tensor (suffix_mask , dtype = torch .bool )
334+ )
335+ _input_ids = torch .tensor (temp , dtype = torch .long )
336+ input_ids .append (_input_ids )
337+ _attn = torch .zeros (len (temp ), dtype = torch .bool )
338+ _attn [:effective_visible ] = True
339+ attention_mask .append (_attn )
340+ _target_ids = _input_ids .clone ()
341+ _target_ids [effective_visible :] = - 100
342+ if not loss_on_padding :
343+ content_len = (
344+ len (_prefix_ids ) + add_bos + len (_suffix_ids ) + add_eos
345+ )
346+ for j in range (min (content_len , effective_visible ), effective_visible ):
347+ _target_ids [j ] = - 100
348+ target_ids .append (_target_ids )
326349 mask .append (_mask )
327350 else :
328- attention_mask .append (
329- torch .tensor (
330- pad_truncate_list (
331- [1 ]
332- * (
333- len (_prefix_ids )
334- + len (_suffix_ids )
335- + add_eos
336- + add_bos
351+ # bos should not be masked
352+ suffix_mask = pad_truncate_list (
353+ [0 ] * (len (_prefix_ids ) + add_bos )
354+ + [1 ] * (len (_suffix_ids ) + add_eos ),
355+ max_len ,
356+ 1 ,
357+ pad_left = False ,
358+ )
359+ temp = pad_truncate_list (
360+ _prefix_ids
361+ + ([bos_token_id ] * add_bos )
362+ + _suffix_ids
363+ + ([eos_token_id ] * add_eos ),
364+ max_len ,
365+ pad_token_id ,
366+ pad_left = False ,
367+ )
368+ _mask = (torch .rand (len (temp )) < t [i ]).logical_and (
369+ torch .tensor (suffix_mask , dtype = torch .bool )
370+ )
371+ _input_ids = torch .tensor (temp , dtype = torch .long )
372+ input_ids .append (_input_ids )
373+ if loss_on_padding :
374+ attention_mask .append (
375+ torch .tensor ([1 ] * len (temp ), dtype = torch .bool )
376+ )
377+ target_ids .append (_input_ids .clone ())
378+ mask .append (_mask )
379+ else :
380+ attention_mask .append (
381+ torch .tensor (
382+ pad_truncate_list (
383+ [1 ]
384+ * (
385+ len (_prefix_ids )
386+ + len (_suffix_ids )
387+ + add_eos
388+ + add_bos
389+ ),
390+ max_len ,
391+ 0 ,
392+ pad_left = False ,
337393 ),
338- max_len ,
339- 0 ,
340- pad_left = False ,
341- ),
342- dtype = torch .bool ,
394+ dtype = torch .bool ,
395+ )
343396 )
344- )
345- mask .append (
346- _mask .logical_and (attention_mask [- 1 ])
347- ) # no input masks in padding
348- _target_ids = _input_ids .clone ()
349- _target_ids [~ attention_mask [- 1 ]] = - 100 # no loss on padding
350- target_ids .append (_target_ids )
397+ mask .append (
398+ _mask .logical_and (attention_mask [- 1 ])
399+ ) # no input masks in padding
400+ _target_ids = _input_ids .clone ()
401+ _target_ids [~ attention_mask [- 1 ]] = - 100 # no loss on padding
402+ target_ids .append (_target_ids )
351403 target_ids = torch .stack (target_ids , dim = 0 )
352404 attention_mask = torch .stack (attention_mask , dim = 0 )
353405 input_ids = torch .stack (input_ids , dim = 0 )
@@ -452,16 +504,23 @@ def __call__(
452504 suffix_lists = [
453505 seq2seq_suffix_ids (e , self .target_field ) for e in examples
454506 ]
507+ if self .input_block_size == 0 :
508+ max_seq_len = None
509+ truncate = None
510+ else :
511+ max_seq_len = self .input_block_size + self .block_size
512+ truncate = self .truncate
455513 prefix_suffix = prepare_prefix_suffix_ids (
456514 [e ["prompt_ids" ] for e in examples ],
457515 suffix_lists ,
458516 self .tokenizer .pad_token_id ,
459517 self .tokenizer .mask_token_id ,
460518 eos_token_id = self .tokenizer .eos_token_id if self .add_eos else None ,
461519 bos_token_id = self .tokenizer .bos_token_id if self .add_bos else None ,
462- max_seq_len = ( self . input_block_size + self . block_size ) ,
463- truncate = self . truncate ,
520+ max_seq_len = max_seq_len ,
521+ truncate = truncate ,
464522 loss_on_padding = self .loss_on_padding ,
523+ suffix_block_size = self .block_size ,
465524 )
466525 return prefix_suffix
467526
0 commit comments