Aditya12kumar commited on
Commit
6cb8e83
·
verified ·
1 Parent(s): b3395ee

Upload 5 files

Browse files
FineTuning_GPT2_for_Quotes_Generation.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
HuggingFace_Inference_API.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
README.md ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Quotes Generator
2
+
3
+ ## Project description
4
+
5
+ Fine-tuned GPT2 model on the Quotes-500K dataset. For a given user prompt, it can generate motivational quotes starting with it. The model weights are deployed on Hugging Face Models Hub.
6
+ Check it out at https://huggingface.co/nandinib1999/quote-generator.
7
+
8
+ ## Training data
9
+
10
+ This is the distribution of the total dataset into training, validation and test dataset for the fine-tuning task.
11
+
12
+ <table style="width:30%">
13
+ <tr>
14
+ <th>train</th>
15
+ <td>349796</td>
16
+ </tr>
17
+ <tr>
18
+ <th>validation</th>
19
+ <td>99942</td>
20
+ </tr>
21
+ <tr>
22
+ <th>test</th>
23
+ <td>49971</td>
24
+ </tr>
25
+ </table>
26
+
27
+ ## Training procedure
28
+
29
+ The model was fine-tuned using the Google Colab GPU for one epoch. The weights of the pre-trained GPT2 model were used as a base.
30
+
31
+ ## Eval results
32
+
33
+ <table style="width:30%">
34
+ <tr>
35
+ <th>Epoch</th>
36
+ <th>Perplexity</th>
37
+ </tr>
38
+ <tr>
39
+ <td>1</td>
40
+ <td>15.180</td>
41
+ </tr>
42
+ </table>
run_generation.py ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+ # Copyright 2018 Google AI, Google Brain and Carnegie Mellon University Authors and the HuggingFace Inc. team.
4
+ # Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ """ Conditional text generation with the auto-regressive models of the library (GPT/GPT-2/CTRL/Transformer-XL/XLNet)
18
+ """
19
+
20
+
21
+ import argparse
22
+ import logging
23
+
24
+ import numpy as np
25
+ import torch
26
+
27
+ from transformers import (
28
+ CTRLLMHeadModel,
29
+ CTRLTokenizer,
30
+ GPT2LMHeadModel,
31
+ GPT2Tokenizer,
32
+ OpenAIGPTLMHeadModel,
33
+ OpenAIGPTTokenizer,
34
+ TransfoXLLMHeadModel,
35
+ TransfoXLTokenizer,
36
+ XLMTokenizer,
37
+ XLMWithLMHeadModel,
38
+ XLNetLMHeadModel,
39
+ XLNetTokenizer,
40
+ )
41
+
42
+
43
+ logging.basicConfig(
44
+ format="%(asctime)s - %(levelname)s - %(name)s - %(message)s", datefmt="%m/%d/%Y %H:%M:%S", level=logging.INFO,
45
+ )
46
+ logger = logging.getLogger(__name__)
47
+
48
+ MAX_LENGTH = int(10000) # Hardcoded max length to avoid infinite loop
49
+
50
+ MODEL_CLASSES = {
51
+ "gpt2": (GPT2LMHeadModel, GPT2Tokenizer),
52
+ "ctrl": (CTRLLMHeadModel, CTRLTokenizer),
53
+ "openai-gpt": (OpenAIGPTLMHeadModel, OpenAIGPTTokenizer),
54
+ "xlnet": (XLNetLMHeadModel, XLNetTokenizer),
55
+ "transfo-xl": (TransfoXLLMHeadModel, TransfoXLTokenizer),
56
+ "xlm": (XLMWithLMHeadModel, XLMTokenizer),
57
+ }
58
+
59
+ # Padding text to help Transformer-XL and XLNet with short prompts as proposed by Aman Rusia
60
+ # in https://github.com/rusiaaman/XLNet-gen#methodology
61
+ # and https://medium.com/@amanrusia/xlnet-speaks-comparison-to-gpt-2-ea1a4e9ba39e
62
+ PADDING_TEXT = """In 1991, the remains of Russian Tsar Nicholas II and his family
63
+ (except for Alexei and Maria) are discovered.
64
+ The voice of Nicholas's young son, Tsarevich Alexei Nikolaevich, narrates the
65
+ remainder of the story. 1883 Western Siberia,
66
+ a young Grigori Rasputin is asked by his father and a group of men to perform magic.
67
+ Rasputin has a vision and denounces one of the men as a horse thief. Although his
68
+ father initially slaps him for making such an accusation, Rasputin watches as the
69
+ man is chased outside and beaten. Twenty years later, Rasputin sees a vision of
70
+ the Virgin Mary, prompting him to become a priest. Rasputin quickly becomes famous,
71
+ with people, even a bishop, begging for his blessing. <eod> </s> <eos>"""
72
+
73
+
74
+ def set_seed(args):
75
+ np.random.seed(args.seed)
76
+ torch.manual_seed(args.seed)
77
+ if args.n_gpu > 0:
78
+ torch.cuda.manual_seed_all(args.seed)
79
+
80
+
81
+ #
82
+ # Functions to prepare models' input
83
+ #
84
+
85
+
86
+ def prepare_ctrl_input(args, _, tokenizer, prompt_text):
87
+ if args.temperature > 0.7:
88
+ logger.info("CTRL typically works better with lower temperatures (and lower top_k).")
89
+
90
+ encoded_prompt = tokenizer.encode(prompt_text, add_special_tokens=False)
91
+ if not any(encoded_prompt[0] == x for x in tokenizer.control_codes.values()):
92
+ logger.info("WARNING! You are not starting your generation from a control code so you won't get good results")
93
+ return prompt_text
94
+
95
+
96
+ def prepare_xlm_input(args, model, tokenizer, prompt_text):
97
+ # kwargs = {"language": None, "mask_token_id": None}
98
+
99
+ # Set the language
100
+ use_lang_emb = hasattr(model.config, "use_lang_emb") and model.config.use_lang_emb
101
+ if hasattr(model.config, "lang2id") and use_lang_emb:
102
+ available_languages = model.config.lang2id.keys()
103
+ if args.xlm_language in available_languages:
104
+ language = args.xlm_language
105
+ else:
106
+ language = None
107
+ while language not in available_languages:
108
+ language = input("Using XLM. Select language in " + str(list(available_languages)) + " >>> ")
109
+
110
+ model.config.lang_id = model.config.lang2id[language]
111
+ # kwargs["language"] = tokenizer.lang2id[language]
112
+
113
+ # TODO fix mask_token_id setup when configurations will be synchronized between models and tokenizers
114
+ # XLM masked-language modeling (MLM) models need masked token
115
+ # is_xlm_mlm = "mlm" in args.model_name_or_path
116
+ # if is_xlm_mlm:
117
+ # kwargs["mask_token_id"] = tokenizer.mask_token_id
118
+
119
+ return prompt_text
120
+
121
+
122
+ def prepare_xlnet_input(args, _, tokenizer, prompt_text):
123
+ prompt_text = (args.padding_text if args.padding_text else PADDING_TEXT) + prompt_text
124
+ return prompt_text
125
+
126
+
127
+ def prepare_transfoxl_input(args, _, tokenizer, prompt_text):
128
+ prompt_text = (args.padding_text if args.padding_text else PADDING_TEXT) + prompt_text
129
+ return prompt_text
130
+
131
+
132
+ PREPROCESSING_FUNCTIONS = {
133
+ "ctrl": prepare_ctrl_input,
134
+ "xlm": prepare_xlm_input,
135
+ "xlnet": prepare_xlnet_input,
136
+ "transfo-xl": prepare_transfoxl_input,
137
+ }
138
+
139
+
140
+ def adjust_length_to_model(length, max_sequence_length):
141
+ if length < 0 and max_sequence_length > 0:
142
+ length = max_sequence_length
143
+ elif 0 < max_sequence_length < length:
144
+ length = max_sequence_length # No generation bigger than model size
145
+ elif length < 0:
146
+ length = MAX_LENGTH # avoid infinite loop
147
+ return length
148
+
149
+
150
+ def main():
151
+ parser = argparse.ArgumentParser()
152
+ parser.add_argument(
153
+ "--model_type",
154
+ default=None,
155
+ type=str,
156
+ required=True,
157
+ help="Model type selected in the list: " + ", ".join(MODEL_CLASSES.keys()),
158
+ )
159
+ parser.add_argument(
160
+ "--model_name_or_path",
161
+ default=None,
162
+ type=str,
163
+ required=True,
164
+ help="Path to pre-trained model or shortcut name selected in the list: " + ", ".join(MODEL_CLASSES.keys()),
165
+ )
166
+
167
+ parser.add_argument("--prompt", type=str, default="")
168
+ parser.add_argument("--length", type=int, default=20)
169
+ parser.add_argument("--stop_token", type=str, default=None, help="Token at which text generation is stopped")
170
+
171
+ parser.add_argument(
172
+ "--temperature",
173
+ type=float,
174
+ default=1.0,
175
+ help="temperature of 1.0 has no effect, lower tend toward greedy sampling",
176
+ )
177
+ parser.add_argument(
178
+ "--repetition_penalty", type=float, default=1.0, help="primarily useful for CTRL model; in that case, use 1.2"
179
+ )
180
+ parser.add_argument("--k", type=int, default=0)
181
+ parser.add_argument("--p", type=float, default=0.9)
182
+
183
+ parser.add_argument("--padding_text", type=str, default="", help="Padding text for Transfo-XL and XLNet.")
184
+ parser.add_argument("--xlm_language", type=str, default="", help="Optional language when used with the XLM model.")
185
+
186
+ parser.add_argument("--seed", type=int, default=42, help="random seed for initialization")
187
+ parser.add_argument("--no_cuda", action="store_true", help="Avoid using CUDA when available")
188
+ parser.add_argument("--num_return_sequences", type=int, default=1, help="The number of samples to generate.")
189
+ args = parser.parse_args()
190
+
191
+ args.device = torch.device("cuda" if torch.cuda.is_available() and not args.no_cuda else "cpu")
192
+ args.n_gpu = 0 if args.no_cuda else torch.cuda.device_count()
193
+
194
+ set_seed(args)
195
+
196
+ # Initialize the model and tokenizer
197
+ try:
198
+ args.model_type = args.model_type.lower()
199
+ model_class, tokenizer_class = MODEL_CLASSES[args.model_type]
200
+ except KeyError:
201
+ raise KeyError("the model {} you specified is not supported. You are welcome to add it and open a PR :)")
202
+
203
+ tokenizer = tokenizer_class.from_pretrained(args.model_name_or_path)
204
+ model = model_class.from_pretrained(args.model_name_or_path)
205
+ model.to(args.device)
206
+
207
+ args.length = adjust_length_to_model(args.length, max_sequence_length=model.config.max_position_embeddings)
208
+ logger.info(args)
209
+
210
+ prompt_text = args.prompt if args.prompt else input("Model prompt >>> ")
211
+
212
+ # Different models need different input formatting and/or extra arguments
213
+ requires_preprocessing = args.model_type in PREPROCESSING_FUNCTIONS.keys()
214
+ if requires_preprocessing:
215
+ prepare_input = PREPROCESSING_FUNCTIONS.get(args.model_type)
216
+ preprocessed_prompt_text = prepare_input(args, model, tokenizer, prompt_text)
217
+ encoded_prompt = tokenizer.encode(
218
+ preprocessed_prompt_text, add_special_tokens=False, return_tensors="pt", add_space_before_punct_symbol=True
219
+ )
220
+ else:
221
+ encoded_prompt = tokenizer.encode(prompt_text, add_special_tokens=True, return_tensors="pt")
222
+ encoded_prompt = encoded_prompt.to(args.device)
223
+
224
+ if encoded_prompt.size()[-1] == 0:
225
+ input_ids = None
226
+ else:
227
+ input_ids = encoded_prompt
228
+
229
+ output_sequences = model.generate(
230
+ input_ids=input_ids,
231
+ max_length=args.length + len(encoded_prompt[0]),
232
+ temperature=args.temperature,
233
+ top_k=args.k,
234
+ top_p=args.p,
235
+ repetition_penalty=args.repetition_penalty,
236
+ do_sample=True,
237
+ num_return_sequences=args.num_return_sequences,
238
+ )
239
+
240
+ # Remove the batch dimension when returning multiple sequences
241
+ if len(output_sequences.shape) > 2:
242
+ output_sequences.squeeze_()
243
+
244
+ generated_sequences = []
245
+
246
+ for generated_sequence_idx, generated_sequence in enumerate(output_sequences):
247
+ print("=== GENERATED SEQUENCE {} ===".format(generated_sequence_idx + 1))
248
+ generated_sequence = generated_sequence.tolist()
249
+
250
+ # Decode text
251
+ text = tokenizer.decode(generated_sequence, clean_up_tokenization_spaces=True)
252
+
253
+ # Remove all text after the stop token
254
+ text = text[: text.find(args.stop_token) if args.stop_token else None]
255
+
256
+ # Add the prompt at the beginning of the sequence. Remove the excess text that was used for pre-processing
257
+ total_sequence = (
258
+ prompt_text + text[len(tokenizer.decode(encoded_prompt[0], clean_up_tokenization_spaces=True)) :]
259
+ )
260
+
261
+ generated_sequences.append(total_sequence)
262
+ print(total_sequence)
263
+
264
+ return generated_sequences
265
+
266
+
267
+ if __name__ == "__main__":
268
+ main()
run_language_modeling.py ADDED
@@ -0,0 +1,283 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.
3
+ # Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ """
17
+ Fine-tuning the library models for language modeling on a text file (GPT, GPT-2, BERT, RoBERTa).
18
+ GPT and GPT-2 are fine-tuned using a causal language modeling (CLM) loss while BERT and RoBERTa are fine-tuned
19
+ using a masked language modeling (MLM) loss.
20
+ """
21
+
22
+
23
+ import logging
24
+ import math
25
+ import os
26
+ from dataclasses import dataclass, field
27
+ from typing import Optional
28
+
29
+ from transformers import (
30
+ CONFIG_MAPPING,
31
+ MODEL_WITH_LM_HEAD_MAPPING,
32
+ AutoConfig,
33
+ AutoModelWithLMHead,
34
+ AutoTokenizer,
35
+ DataCollatorForLanguageModeling,
36
+ HfArgumentParser,
37
+ LineByLineTextDataset,
38
+ PreTrainedTokenizer,
39
+ TextDataset,
40
+ Trainer,
41
+ TrainingArguments,
42
+ set_seed,
43
+ )
44
+
45
+
46
+ logger = logging.getLogger(__name__)
47
+
48
+
49
+ MODEL_CONFIG_CLASSES = list(MODEL_WITH_LM_HEAD_MAPPING.keys())
50
+ MODEL_TYPES = tuple(conf.model_type for conf in MODEL_CONFIG_CLASSES)
51
+
52
+
53
+ @dataclass
54
+ class ModelArguments:
55
+ """
56
+ Arguments pertaining to which model/config/tokenizer we are going to fine-tune, or train from scratch.
57
+ """
58
+
59
+ model_name_or_path: Optional[str] = field(
60
+ default=None,
61
+ metadata={
62
+ "help": "The model checkpoint for weights initialization. Leave None if you want to train a model from scratch."
63
+ },
64
+ )
65
+ model_type: Optional[str] = field(
66
+ default=None,
67
+ metadata={"help": "If training from scratch, pass a model type from the list: " + ", ".join(MODEL_TYPES)},
68
+ )
69
+ config_name: Optional[str] = field(
70
+ default=None, metadata={"help": "Pretrained config name or path if not the same as model_name"}
71
+ )
72
+ tokenizer_name: Optional[str] = field(
73
+ default=None, metadata={"help": "Pretrained tokenizer name or path if not the same as model_name"}
74
+ )
75
+ cache_dir: Optional[str] = field(
76
+ default=None, metadata={"help": "Where do you want to store the pretrained models downloaded from s3"}
77
+ )
78
+
79
+
80
+ @dataclass
81
+ class DataTrainingArguments:
82
+ """
83
+ Arguments pertaining to what data we are going to input our model for training and eval.
84
+ """
85
+
86
+ train_data_file: Optional[str] = field(
87
+ default=None, metadata={"help": "The input training data file (a text file)."}
88
+ )
89
+ eval_data_file: Optional[str] = field(
90
+ default=None,
91
+ metadata={"help": "An optional input evaluation data file to evaluate the perplexity on (a text file)."},
92
+ )
93
+ line_by_line: bool = field(
94
+ default=False,
95
+ metadata={"help": "Whether distinct lines of text in the dataset are to be handled as distinct sequences."},
96
+ )
97
+
98
+ mlm: bool = field(
99
+ default=False, metadata={"help": "Train with masked-language modeling loss instead of language modeling."}
100
+ )
101
+ mlm_probability: float = field(
102
+ default=0.15, metadata={"help": "Ratio of tokens to mask for masked language modeling loss"}
103
+ )
104
+
105
+ block_size: int = field(
106
+ default=-1,
107
+ metadata={
108
+ "help": "Optional input sequence length after tokenization."
109
+ "The training dataset will be truncated in block of this size for training."
110
+ "Default to the model max input length for single sentence inputs (take into account special tokens)."
111
+ },
112
+ )
113
+ overwrite_cache: bool = field(
114
+ default=False, metadata={"help": "Overwrite the cached training and evaluation sets"}
115
+ )
116
+
117
+
118
+ def get_dataset(args: DataTrainingArguments, tokenizer: PreTrainedTokenizer, evaluate=False):
119
+ file_path = args.eval_data_file if evaluate else args.train_data_file
120
+ if args.line_by_line:
121
+ return LineByLineTextDataset(tokenizer=tokenizer, file_path=file_path, block_size=args.block_size)
122
+ else:
123
+ return TextDataset(
124
+ tokenizer=tokenizer, file_path=file_path, block_size=args.block_size, overwrite_cache=args.overwrite_cache
125
+ )
126
+
127
+
128
+ def main():
129
+ # See all possible arguments in src/transformers/training_args.py
130
+ # or by passing the --help flag to this script.
131
+ # We now keep distinct sets of args, for a cleaner separation of concerns.
132
+
133
+ parser = HfArgumentParser((ModelArguments, DataTrainingArguments, TrainingArguments))
134
+ model_args, data_args, training_args = parser.parse_args_into_dataclasses()
135
+
136
+ if data_args.eval_data_file is None and training_args.do_eval:
137
+ raise ValueError(
138
+ "Cannot do evaluation without an evaluation data file. Either supply a file to --eval_data_file "
139
+ "or remove the --do_eval argument."
140
+ )
141
+
142
+ if (
143
+ os.path.exists(training_args.output_dir)
144
+ and os.listdir(training_args.output_dir)
145
+ and training_args.do_train
146
+ and not training_args.overwrite_output_dir
147
+ ):
148
+ raise ValueError(
149
+ f"Output directory ({training_args.output_dir}) already exists and is not empty. Use --overwrite_output_dir to overcome."
150
+ )
151
+
152
+ # Setup logging
153
+ logging.basicConfig(
154
+ format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",
155
+ datefmt="%m/%d/%Y %H:%M:%S",
156
+ level=logging.INFO if training_args.local_rank in [-1, 0] else logging.WARN,
157
+ )
158
+ logger.warning(
159
+ "Process rank: %s, device: %s, n_gpu: %s, distributed training: %s, 16-bits training: %s",
160
+ training_args.local_rank,
161
+ training_args.device,
162
+ training_args.n_gpu,
163
+ bool(training_args.local_rank != -1),
164
+ training_args.fp16,
165
+ )
166
+ logger.info("Training/evaluation parameters %s", training_args)
167
+
168
+ # Set seed
169
+ set_seed(training_args.seed)
170
+
171
+ # Load pretrained model and tokenizer
172
+ #
173
+ # Distributed training:
174
+ # The .from_pretrained methods guarantee that only one local process can concurrently
175
+ # download model & vocab.
176
+
177
+ if model_args.config_name:
178
+ config = AutoConfig.from_pretrained(model_args.config_name, cache_dir=model_args.cache_dir)
179
+ elif model_args.model_name_or_path:
180
+ config = AutoConfig.from_pretrained(model_args.model_name_or_path, cache_dir=model_args.cache_dir)
181
+ else:
182
+ config = CONFIG_MAPPING[model_args.model_type]()
183
+ logger.warning("You are instantiating a new config instance from scratch.")
184
+
185
+ if model_args.tokenizer_name:
186
+ tokenizer = AutoTokenizer.from_pretrained(model_args.tokenizer_name, cache_dir=model_args.cache_dir)
187
+ elif model_args.model_name_or_path:
188
+ tokenizer = AutoTokenizer.from_pretrained(model_args.model_name_or_path, cache_dir=model_args.cache_dir)
189
+ else:
190
+ raise ValueError(
191
+ "You are instantiating a new tokenizer from scratch. This is not supported, but you can do it from another script, save it,"
192
+ "and load it from here, using --tokenizer_name"
193
+ )
194
+
195
+ if model_args.model_name_or_path:
196
+ model = AutoModelWithLMHead.from_pretrained(
197
+ model_args.model_name_or_path,
198
+ from_tf=bool(".ckpt" in model_args.model_name_or_path),
199
+ config=config,
200
+ cache_dir=model_args.cache_dir,
201
+ )
202
+ else:
203
+ logger.info("Training new model from scratch")
204
+ model = AutoModelWithLMHead.from_config(config)
205
+
206
+ special_tokens_dict = {'bos_token': '<BOS>', 'eos_token': '<EOS>', 'pad_token': '<PAD>'}
207
+ num_added_toks = tokenizer.add_special_tokens(special_tokens_dict)
208
+ model.resize_token_embeddings(len(tokenizer))
209
+
210
+ if config.model_type in ["bert", "roberta", "distilbert", "camembert"] and not data_args.mlm:
211
+ raise ValueError(
212
+ "BERT and RoBERTa-like models do not have LM heads but masked LM heads. They must be run using the --mlm "
213
+ "flag (masked language modeling)."
214
+ )
215
+
216
+ if data_args.block_size <= 0:
217
+ data_args.block_size = tokenizer.max_len
218
+ # Our input block size will be the max possible for the model
219
+ else:
220
+ data_args.block_size = min(data_args.block_size, tokenizer.max_len)
221
+
222
+ # Get datasets
223
+
224
+ train_dataset = get_dataset(data_args, tokenizer=tokenizer) if training_args.do_train else None
225
+ eval_dataset = get_dataset(data_args, tokenizer=tokenizer, evaluate=True) if training_args.do_eval else None
226
+ data_collator = DataCollatorForLanguageModeling(
227
+ tokenizer=tokenizer, mlm=data_args.mlm, mlm_probability=data_args.mlm_probability
228
+ )
229
+
230
+ # Initialize our Trainer
231
+ trainer = Trainer(
232
+ model=model,
233
+ args=training_args,
234
+ data_collator=data_collator,
235
+ train_dataset=train_dataset,
236
+ eval_dataset=eval_dataset,
237
+ prediction_loss_only=True,
238
+ )
239
+
240
+ # Training
241
+ if training_args.do_train:
242
+ model_path = (
243
+ model_args.model_name_or_path
244
+ if model_args.model_name_or_path is not None and os.path.isdir(model_args.model_name_or_path)
245
+ else None
246
+ )
247
+ trainer.train(model_path=model_path)
248
+ trainer.save_model()
249
+ # For convenience, we also re-save the tokenizer to the same directory,
250
+ # so that you can share your model easily on huggingface.co/models =)
251
+ if trainer.is_world_master():
252
+ tokenizer.save_pretrained(training_args.output_dir)
253
+
254
+ # Evaluation
255
+ results = {}
256
+ if training_args.do_eval:
257
+ logger.info("*** Evaluate ***")
258
+
259
+ eval_output = trainer.evaluate()
260
+
261
+ perplexity = math.exp(eval_output["eval_loss"])
262
+ result = {"perplexity": perplexity}
263
+
264
+ output_eval_file = os.path.join(training_args.output_dir, "eval_results_lm.txt")
265
+ if trainer.is_world_master():
266
+ with open(output_eval_file, "w") as writer:
267
+ logger.info("***** Eval results *****")
268
+ for key in sorted(result.keys()):
269
+ logger.info(" %s = %s", key, str(result[key]))
270
+ writer.write("%s = %s\n" % (key, str(result[key])))
271
+
272
+ results.update(result)
273
+
274
+ return results
275
+
276
+
277
+ def _mp_fn(index):
278
+ # For xla_spawn (TPUs)
279
+ main()
280
+
281
+
282
+ if __name__ == "__main__":
283
+ main()