@@ -24,13 +24,13 @@ def setup_self_module(self):
2424 self .actor = self .opt_groups ['group0' ].actor
2525 self .toknizer = self .opt_groups ['group0' ].tokenizer
2626 self .optimizer = self .opt_groups ['group0' ].optimizer
27- self .scheduler = self .opt_groups ['group0' ].scheduler ,
27+ self .scheduler = self .opt_groups ['group0' ].scheduler
2828 self .loss_fn = self .opt_groups ['group0' ].loss_fn
2929
3030 def micro_batch_forward_backward (self , batch ) -> "dict[str, object]" :
31- inputs , attention_masks , loss_masks , seq_lens = batch
32- output = self .actor (sequences = inputs , attention_masks = attention_masks , seq_lens = seq_lens )
33- labels = torch .where (attention_masks .bool () & loss_masks .bool (), inputs , self .loss_fn .ignore_index )
31+ inputs , attention_mask , loss_mask , seq_lens = batch
32+ output = self .actor (sequences = inputs , attention_mask = attention_mask , seq_lens = seq_lens )
33+ labels = torch .where (attention_mask .bool () & loss_mask .bool (), inputs , self .loss_fn .ignore_index )
3434
3535 gpt_loss = self .loss_fn (output .logits , labels )
3636
@@ -39,7 +39,7 @@ def micro_batch_forward_backward(self, batch) -> "dict[str, object]":
3939 return dict (
4040 loss = gpt_loss .item (),
4141 total_tokens = parallel .all_reduce (sum (seq_lens )) * parallel .get_dp_count () / 10 ** 9 ,
42- loss_tokens = parallel .all_reduce (loss_masks .int ().sum ().item ()) * parallel .get_dp_count () / 10 ** 9
42+ loss_tokens = parallel .all_reduce (loss_mask .int ().sum ().item ()) * parallel .get_dp_count () / 10 ** 9
4343 )
4444
4545 def micro_batch_validate_forward (self , batch ):
@@ -74,55 +74,6 @@ def __init__(self,
7474 assert "prompt_key" in data_dict
7575 assert "response_key" in data_dict
7676
77- @LoomDataModule .datasetmethod
78- def filter_data (dataset , self :"LoomSFTData" , data : "dict" ):
79- if dataset .max_length < 128000 :
80- prompt_template = data [dataset .prompt_key ]
81- response_template = role_template (data [dataset .response_key ], "assistant" )
82- tokenized = dataset .tokenizer .apply_chat_template (
83- prompt_template + response_template , tokenize = True ,
84- max_length = 128000 , padding = False ,
85- truncation = True , return_tensors = 'pt'
86- )
87- if tokenized .numel () > dataset .max_length : return False
88- return True
89-
90- @LoomDataModule .datasetmethod
91- def process_data (dataset , data ):
92- prompt_template = data [dataset .prompt_key ]
93- response_text = data [dataset .response_key ]
94- if isinstance (response_text , str ):
95- response_text = [{"role" :"assistant" , "content" : response_text }]
96- prompt = dataset .tokenizer .apply_chat_template (
97- prompt_template , tokenize = False , add_generation_prompt = True
98- )
99- response = dataset .tokenizer .apply_chat_template (
100- prompt_template + response_text , tokenize = False
101- )[len (prompt ): ]
102-
103-
104- prompt_token = dataset .tokenizer (prompt , max_length = dataset .max_length ,
105- padding = False ,
106- truncation = True ,
107- return_tensors = 'pt' ,
108- add_special_tokens = False )
109- response_token = dataset .tokenizer (response , max_length = dataset .max_length ,
110- padding = False ,
111- truncation = True ,
112- return_tensors = 'pt' ,
113- add_special_tokens = False )
114-
115- prompt_ids_len = prompt_token ["attention_mask" ].int ().sum ().item ()
116- input_ids_len = prompt_ids_len + response_token ["attention_mask" ].int ().sum ().item ()
117-
118- return dict (
119- prompt = prompt ,
120- response = response ,
121- prompt_ids_len = prompt_ids_len ,
122- input_ids_len = input_ids_len ,
123- response_ranges = None # not multiturn
124- )
125-
12677 @LoomDataModule .datasetmethod
12778 def get_loss_mask (dataset , input_ids , idx ):
12879 loss_mask = torch .zeros_like (input_ids , dtype = torch .bool )
@@ -132,19 +83,70 @@ def get_loss_mask(dataset, input_ids, idx):
13283
13384 return loss_mask
13485
86+ def dataset_initialize (dataset , self : "LoomSFTData" , raw_dataset , data_dict ):
13587
88+ tokenizer = dataset .tokenizer = data_dict .tokenizer
89+ prompt_key = dataset .prompt_key = data_dict ["prompt_key" ]
90+ response_key = dataset .response_key = data_dict ["response_key" ]
91+ max_length = dataset .max_length = self .max_length
92+
93+ def filter_data (data : "dict" ):
94+ if max_length < 128000 :
95+ prompt_template = data [prompt_key ]
96+ response_template = role_template (data [response_key ], "assistant" )
97+ tokenized = tokenizer .apply_chat_template (
98+ prompt_template + response_template , tokenize = True ,
99+ max_length = 128000 , padding = False ,
100+ truncation = True , return_tensors = 'pt'
101+ )
102+ if tokenized .numel () > max_length : return False
103+ return True
104+
105+ def process_data (data ):
106+ prompt_template = data [prompt_key ]
107+ response_text = data [response_key ]
108+ if isinstance (response_text , str ):
109+ response_text = [{"role" :"assistant" , "content" : response_text }]
110+ prompt = tokenizer .apply_chat_template (
111+ prompt_template , tokenize = False , add_generation_prompt = True
112+ )
113+ response = tokenizer .apply_chat_template (
114+ prompt_template + response_text , tokenize = False
115+ )[len (prompt ): ]
136116
137- def dataset_initialize (dataset , self : "LoomSFTData" , raw_dataset , data_dict ):
138- dataset .tokenizer = data_dict .tokenizer
139- raw_dataset = raw_dataset .filter (dataset .filter_data , num_proc = self .num_proc )
140- processed_dataset = raw_dataset .map (dataset .process_data ,
117+
118+ prompt_token = tokenizer (prompt , max_length = max_length ,
119+ padding = False ,
120+ truncation = True ,
121+ return_tensors = 'pt' ,
122+ add_special_tokens = False )
123+ response_token = tokenizer (response , max_length = max_length ,
124+ padding = False ,
125+ truncation = True ,
126+ return_tensors = 'pt' ,
127+ add_special_tokens = False )
128+
129+ prompt_ids_len = prompt_token ["attention_mask" ].int ().sum ().item ()
130+ input_ids_len = prompt_ids_len + response_token ["attention_mask" ].int ().sum ().item ()
131+
132+ return dict (
133+ prompt = prompt ,
134+ response = response ,
135+ prompt_ids_len = prompt_ids_len ,
136+ input_ids_len = input_ids_len ,
137+ response_ranges = None # not multiturn
138+ )
139+
140+ raw_dataset = raw_dataset .filter (filter_data , num_proc = self .num_proc )
141+ processed_dataset = raw_dataset .map (process_data ,
141142 remove_columns = raw_dataset .column_names ,
142143 num_proc = self .num_proc )
143144
144145 dataset .prompts = processed_dataset ["prompt" ]
145146 dataset .responses = processed_dataset ["response" ]
146147 dataset .prompt_ids_lens = processed_dataset ["prompt_ids_len" ]
147- dataset .input_ids_lens = processed_dataset ["prompt_ids_len" ]
148+ # This attribute makes itself possible to be packed.
149+ dataset ._input_ids_lens = processed_dataset ["prompt_ids_len" ]
148150
149151
150152
@@ -193,7 +195,7 @@ def dataset_collate_fn(dataset, self: "LoomSFTData", item_list):
193195
194196 if packed_input_ids .numel () % self .cp_size :
195197 padding_len = self .cp_size - (packed_input_ids .numel () % self .cp_size )
196- packed_input_ids = F .pad (packed_input_ids , (0 , padding_len ), value = self .tokenizer .pad_token_id )
198+ packed_input_ids = F .pad (packed_input_ids , (0 , padding_len ), value = dataset .tokenizer .pad_token_id )
197199 packed_attention_masks = F .pad (packed_attention_masks , (0 , padding_len ), value = 0 )
198200 packed_loss_masks = F .pad (packed_loss_masks , (0 , padding_len ), value = 0 )
199201
0 commit comments