通常一个批次中输入进模型的文本序列是由多个文档(doc)拼接而得。在默认情况下,多个文档被视为同一序列,互相间的self attention没有掩盖。在特定情况下,多个文档间要求独立,文档间不能互相做self attention,在这种情况下attention_mask和position_ids需要在每个文档结束的位置(EoD,End of Document)被重新设置。
--reset-position-ids参数关闭时,整个序列计算位置编码;开启时,在每个序列内独立计算位置编码。
通过调用底层flash-attention算子的可变长模式,支持EoD Reset训练场景。同时在EoD Reset训练场景下,支持Ring Attention长序列并行,对超长序列场景进行加速。
训练数据中每个序列由多个子序列拼接而成,且希望子序列之间相互独立。可以开启EoD训练模式。
def get_batch(data_iterator): """Generate a batch.""" - # TODO: this is pretty hacky, find a better way - if (not mpu.is_pipeline_first_stage()) and (not mpu.is_pipeline_last_stage()): - return None, None, None, None, None # get batches based on the TP rank you are on batch = get_batch_on_this_tp_rank(data_iterator) # slice batch along sequence dimension for context parallelism batch = get_batch_on_this_cp_rank(batch) + # TODO: this is pretty hacky, find a better way + if (not mpu.is_pipeline_first_stage()) and (not mpu.is_pipeline_last_stage()): + return None, None, None, None, None return batch.values()
def is_dataset_built_on_rank(): return ( mpu.is_pipeline_first_stage() or mpu.is_pipeline_last_stage() ) and mpu.get_tensor_model_parallel_rank() == 0
def is_dataset_built_on_rank(): return mpu.get_tensor_model_parallel_rank() == 0
--attention-mask-type general
--reset-attention-mask --reset-position-ids
--context-parallel-size N # 确保N大于1 --reset-attention-mask --reset-position-ids
EoD Reset训练场景下,当mask-type设置为general时,Ring Attention或Hybrid Attention比Ulysses下降较多,为正常现象。
支持了EoD训练场景,训练中将只计算每个子序列(由EoD分割)之间的attention。模型可以更好地专注到每个子序列上。