Data collator used for language modeling. Args: tokenizer ([`PreTrainedTokenizer`] or [`PreTrainedTokenizerFast`]): The tokenizer used for encoding the data. varlen (`bool`): Whether to return sequences with variable lengths. If `True`, t
| 156 | |
| 157 | @dataclass |
| 158 | class DataCollatorForLanguageModeling: |
| 159 | """ |
| 160 | Data collator used for language modeling. |
| 161 | |
| 162 | Args: |
| 163 | tokenizer ([`PreTrainedTokenizer`] or [`PreTrainedTokenizerFast`]): |
| 164 | The tokenizer used for encoding the data. |
| 165 | varlen (`bool`): |
| 166 | Whether to return sequences with variable lengths. |
| 167 | If `True`, the offsets indicating the start and end of each sequence will be returned. |
| 168 | For example, if the sequence lengths are `[4, 8, 12]`, |
| 169 | the returned `input_ids` will be a long flattened tensor of shape `[1, 24]`, with `offsets` being `[0, 4, 12, 24]`. |
| 170 | If `False`, the `input_ids` with shape `[batch_size, seq_len]` will be returned directly. |
| 171 | return_tensors (`str`): |
| 172 | The type of Tensor to return. Allowable values are "pt". |
| 173 | """ |
| 174 | |
| 175 | tokenizer: PreTrainedTokenizer |
| 176 | varlen: bool = False |
| 177 | return_tensors: str = "pt" |
| 178 | |
| 179 | def __call__( |
| 180 | self, |
| 181 | examples: List[Union[List[int], Dict[str, Any]]] |
| 182 | ) -> Dict[str, Any]: |
| 183 | if not isinstance(examples[0], Dict): |
| 184 | examples = [{'input_ids': example} for example in examples] |
| 185 | |
| 186 | def tensorize(example: Dict[str, Any]) -> Dict[str, Any]: |
| 187 | tensorized = {} |
| 188 | for key in ['input_ids', 'offsets']: |
| 189 | if key not in example: |
| 190 | continue |
| 191 | if isinstance(example[key], List): |
| 192 | tensorized[key] = torch.tensor(example[key], dtype=torch.long) |
| 193 | elif isinstance(example[key], np.ndarray): |
| 194 | tensorized[key] = torch.from_numpy(example[key]) |
| 195 | else: |
| 196 | tensorized[key] = example[key] |
| 197 | return tensorized |
| 198 | |
| 199 | examples = list(map(tensorize, examples)) |
| 200 | |
| 201 | if not self.varlen: |
| 202 | length_of_first = examples[0]['input_ids'].size(0) |
| 203 | # Check if padding is necessary. |
| 204 | if all(example['input_ids'].size(0) == length_of_first for example in examples): |
| 205 | batch = { |
| 206 | 'input_ids': torch.stack([example['input_ids'] for example in examples], dim=0), |
| 207 | } |
| 208 | else: |
| 209 | # If yes, check if we have a `pad_token`. |
| 210 | if self.tokenizer._pad_token is None: |
| 211 | raise ValueError( |
| 212 | f"You are attempting to pad samples but the tokenizer you are using " |
| 213 | f"({self.tokenizer.__class__.__name__}) does not have a pad token." |
| 214 | ) |
| 215 | batch = self.tokenizer.pad(examples, return_tensors=self.return_tensors, return_attention_mask=False) |