1616 get_batch_and_global_seqlens ,
1717 reroute_samples_to_dcp_ranks ,
1818)
19- from megatron .core .packed_seq_params import PackedSeqParams
19+ from megatron .core .packed_seq_params import PackedSeqParams , pad_packed_batch_to_capacity
2020from megatron .core .pipeline_parallel .hybrid_cp_schedule import BalancedCPScheduler
2121from megatron .core .process_groups_config import ProcessGroupCollection
2222
@@ -361,6 +361,7 @@ def __init__(
361361 cp_size : int ,
362362 dp_size : int ,
363363 microbatch_group_size_per_vp_stage : Optional [int ],
364+ max_num_seqs : Optional [int ] = None ,
364365 ):
365366 """
366367 Args:
@@ -374,6 +375,7 @@ def __init__(
374375 self .cp_size = cp_size
375376 self .dp_size = dp_size
376377 self .microbatch_group_size_per_vp_stage = microbatch_group_size_per_vp_stage
378+ self .max_num_seqs = max_num_seqs
377379
378380 def get_required_sample_keys (self ):
379381 """Return the required key of each batch."""
@@ -444,7 +446,9 @@ def get_groups_and_subsamples(self, sample_id_seqlens):
444446 single_microbatch = []
445447
446448 for i in range (len (sample_id_seqlens )):
447- if sum_seqlen + sample_id_seqlens [i ][1 ] <= self .max_seq_len_all_ranks :
449+ if sum_seqlen + sample_id_seqlens [i ][1 ] <= self .max_seq_len_all_ranks and (
450+ self .max_num_seqs is None or len (single_microbatch ) < self .max_num_seqs
451+ ):
448452 single_microbatch .append (i )
449453 sum_seqlen += sample_id_seqlens [i ][1 ]
450454 else :
@@ -720,6 +724,14 @@ def wrap_data_iterator(
720724 if config .virtual_pipeline_model_parallel_size is None
721725 else config .microbatch_group_size_per_vp_stage
722726 ),
727+ # Reserve a document when token padding can append a dummy tail. Enforce
728+ # the metadata bound before routing instead of falling back mid-pipeline.
729+ max_num_seqs = (
730+ config .thd_max_packed_sequences
731+ - int (getattr (config , "pad_packed_seq_alignment" , None ) is not None )
732+ if getattr (config , "thd_max_packed_sequences" , None ) is not None
733+ else None
734+ ),
723735 )
724736
725737 (
@@ -745,6 +757,7 @@ def get_batch_on_this_rank_for_sequence_packing(
745757 mtp_on_this_rank : bool = False ,
746758 vp_stage : Optional [int ] = None ,
747759 pg_collection : Optional [ProcessGroupCollection ] = None ,
760+ config = None ,
748761):
749762 """
750763 Get a batch of data for sequence packing.
@@ -921,5 +934,29 @@ def get_batch_on_this_rank_for_sequence_packing(
921934 max_seqlen_kv = max_seqlen ,
922935 )
923936
937+ if config is not None and (
938+ config .pad_packed_seq_alignment is not None
939+ or getattr (config , "thd_max_packed_sequences" , None ) is not None
940+ ):
941+ alignment = config .pad_packed_seq_alignment
942+ local_capacity = padding_mask .shape [- 1 ]
943+ if alignment == "max" :
944+ local_capacity = config .max_seqlen_per_dp_cp_rank
945+ elif alignment is not None :
946+ local_capacity = ((local_capacity + alignment - 1 ) // alignment ) * alignment
947+ tokens , labels , loss_mask , position_ids , packed_seq_params , padding_mask = (
948+ pad_packed_batch_to_capacity (
949+ tokens ,
950+ labels ,
951+ loss_mask ,
952+ position_ids ,
953+ packed_seq_params ,
954+ padding_mask ,
955+ local_capacity = local_capacity ,
956+ cp_size = cp_group .size (),
957+ max_num_seqs = getattr (config , "thd_max_packed_sequences" , None ),
958+ )
959+ )
960+
924961 # "attention_mask" is not valid for sequence packing, so set it to None.
925962 return tokens , labels , loss_mask , None , position_ids , packed_seq_params , padding_mask
0 commit comments