From 45e26125de1b9fbae46837856b1f518a4b56eb65 Mon Sep 17 00:00:00 2001 From: Sam Shleifer Date: Sun, 28 Jun 2020 14:53:47 -0400 Subject: [PATCH] save_pretrained: mkdir(exist_ok=True) (#5258) * all save_pretrained methods mkdir if not os.path.exists --- examples/bert-loses-patience/run_glue_with_pabee.py | 6 ------ examples/contrib/mm-imdb/run_mmimdb.py | 4 ---- examples/contrib/run_swag.py | 6 ------ examples/distillation/run_squad_w_distillation.py | 4 ---- examples/movement-pruning/masked_run_glue.py | 4 ---- examples/movement-pruning/masked_run_squad.py | 4 ---- examples/question-answering/run_squad.py | 6 ------ examples/seq2seq/distillation.py | 2 -- examples/text-classification/run_xnli.py | 4 ---- src/transformers/configuration_utils.py | 7 +++---- src/transformers/convert_pytorch_checkpoint_to_tf2.py | 1 - src/transformers/modeling_tf_utils.py | 7 ++++--- src/transformers/modeling_utils.py | 7 ++++--- src/transformers/pipelines.py | 5 +++-- src/transformers/tokenization_utils_base.py | 5 +++-- templates/adding_a_new_example_script/run_xxx.py | 4 ---- 16 files changed, 17 insertions(+), 59 deletions(-) diff --git a/examples/bert-loses-patience/run_glue_with_pabee.py b/examples/bert-loses-patience/run_glue_with_pabee.py index 1ef2b8488e..bddd5adb26 100755 --- a/examples/bert-loses-patience/run_glue_with_pabee.py +++ b/examples/bert-loses-patience/run_glue_with_pabee.py @@ -226,8 +226,6 @@ def train(args, train_dataset, model, tokenizer): if args.local_rank in [-1, 0] and args.save_steps > 0 and global_step % args.save_steps == 0: # Save model checkpoint output_dir = os.path.join(args.output_dir, "checkpoint-{}".format(global_step)) - if not os.path.exists(output_dir): - os.makedirs(output_dir) model_to_save = ( model.module if hasattr(model, "module") else model ) # Take care of distributed/parallel training @@ -649,10 +647,6 @@ def main(): # Saving best-practices: if you use defaults names for the model, you can reload it using from_pretrained() if args.do_train and (args.local_rank == -1 or torch.distributed.get_rank() == 0): - # Create output directory if needed - if not os.path.exists(args.output_dir) and args.local_rank in [-1, 0]: - os.makedirs(args.output_dir) - logger.info("Saving model checkpoint to %s", args.output_dir) # Save a trained model, configuration and tokenizer using `save_pretrained()`. # They can then be reloaded using `from_pretrained()` diff --git a/examples/contrib/mm-imdb/run_mmimdb.py b/examples/contrib/mm-imdb/run_mmimdb.py index 7a3bcbda43..89505454cc 100644 --- a/examples/contrib/mm-imdb/run_mmimdb.py +++ b/examples/contrib/mm-imdb/run_mmimdb.py @@ -521,10 +521,6 @@ def main(): # Saving best-practices: if you use defaults names for the model, you can reload it using from_pretrained() if args.do_train and (args.local_rank == -1 or torch.distributed.get_rank() == 0): - # Create output directory if needed - if not os.path.exists(args.output_dir) and args.local_rank in [-1, 0]: - os.makedirs(args.output_dir) - logger.info("Saving model checkpoint to %s", args.output_dir) # Save a trained model, configuration and tokenizer using `save_pretrained()`. # They can then be reloaded using `from_pretrained()` diff --git a/examples/contrib/run_swag.py b/examples/contrib/run_swag.py index 24f9ecca64..962c2990d1 100644 --- a/examples/contrib/run_swag.py +++ b/examples/contrib/run_swag.py @@ -383,8 +383,6 @@ def train(args, train_dataset, model, tokenizer): if args.local_rank in [-1, 0] and args.save_steps > 0 and global_step % args.save_steps == 0: # Save model checkpoint output_dir = os.path.join(args.output_dir, "checkpoint-{}".format(global_step)) - if not os.path.exists(output_dir): - os.makedirs(output_dir) model_to_save = ( model.module if hasattr(model, "module") else model ) # Take care of distributed/parallel training @@ -651,10 +649,6 @@ def main(): # Save the trained model and the tokenizer if args.local_rank == -1 or torch.distributed.get_rank() == 0: - # Create output directory if needed - if not os.path.exists(args.output_dir) and args.local_rank in [-1, 0]: - os.makedirs(args.output_dir) - logger.info("Saving model checkpoint to %s", args.output_dir) # Save a trained model, configuration and tokenizer using `save_pretrained()`. # They can then be reloaded using `from_pretrained()` diff --git a/examples/distillation/run_squad_w_distillation.py b/examples/distillation/run_squad_w_distillation.py index ff9b381561..f7a8ec02ba 100644 --- a/examples/distillation/run_squad_w_distillation.py +++ b/examples/distillation/run_squad_w_distillation.py @@ -809,10 +809,6 @@ def main(): # Save the trained model and the tokenizer if args.do_train and (args.local_rank == -1 or torch.distributed.get_rank() == 0): - # Create output directory if needed - if not os.path.exists(args.output_dir) and args.local_rank in [-1, 0]: - os.makedirs(args.output_dir) - logger.info("Saving model checkpoint to %s", args.output_dir) # Save a trained model, configuration and tokenizer using `save_pretrained()`. # They can then be reloaded using `from_pretrained()` diff --git a/examples/movement-pruning/masked_run_glue.py b/examples/movement-pruning/masked_run_glue.py index 46107ac28e..218864051f 100644 --- a/examples/movement-pruning/masked_run_glue.py +++ b/examples/movement-pruning/masked_run_glue.py @@ -875,10 +875,6 @@ def main(): # Saving best-practices: if you use defaults names for the model, you can reload it using from_pretrained() if args.do_train and (args.local_rank == -1 or torch.distributed.get_rank() == 0): - # Create output directory if needed - if not os.path.exists(args.output_dir) and args.local_rank in [-1, 0]: - os.makedirs(args.output_dir) - logger.info("Saving model checkpoint to %s", args.output_dir) # Save a trained model, configuration and tokenizer using `save_pretrained()`. # They can then be reloaded using `from_pretrained()` diff --git a/examples/movement-pruning/masked_run_squad.py b/examples/movement-pruning/masked_run_squad.py index b85ee7569c..309fb9ea9d 100644 --- a/examples/movement-pruning/masked_run_squad.py +++ b/examples/movement-pruning/masked_run_squad.py @@ -1059,10 +1059,6 @@ def main(): # Save the trained model and the tokenizer if args.do_train and (args.local_rank == -1 or torch.distributed.get_rank() == 0): - # Create output directory if needed - if not os.path.exists(args.output_dir) and args.local_rank in [-1, 0]: - os.makedirs(args.output_dir) - logger.info("Saving model checkpoint to %s", args.output_dir) # Save a trained model, configuration and tokenizer using `save_pretrained()`. # They can then be reloaded using `from_pretrained()` diff --git a/examples/question-answering/run_squad.py b/examples/question-answering/run_squad.py index 821174dda4..2bd4e90ff9 100644 --- a/examples/question-answering/run_squad.py +++ b/examples/question-answering/run_squad.py @@ -240,8 +240,6 @@ def train(args, train_dataset, model, tokenizer): # Save model checkpoint if args.local_rank in [-1, 0] and args.save_steps > 0 and global_step % args.save_steps == 0: output_dir = os.path.join(args.output_dir, "checkpoint-{}".format(global_step)) - if not os.path.exists(output_dir): - os.makedirs(output_dir) # Take care of distributed/parallel training model_to_save = model.module if hasattr(model, "module") else model model_to_save.save_pretrained(output_dir) @@ -768,10 +766,6 @@ def main(): # Save the trained model and the tokenizer if args.do_train and (args.local_rank == -1 or torch.distributed.get_rank() == 0): - # Create output directory if needed - if not os.path.exists(args.output_dir) and args.local_rank in [-1, 0]: - os.makedirs(args.output_dir) - logger.info("Saving model checkpoint to %s", args.output_dir) # Save a trained model, configuration and tokenizer using `save_pretrained()`. # They can then be reloaded using `from_pretrained()` diff --git a/examples/seq2seq/distillation.py b/examples/seq2seq/distillation.py index 0d645a1458..30e2e1c755 100644 --- a/examples/seq2seq/distillation.py +++ b/examples/seq2seq/distillation.py @@ -92,8 +92,6 @@ class BartSummarizationDistiller(SummarizationModule): student = BartForConditionalGeneration(student_cfg) student, _ = init_student(student, teacher) save_dir = self.output_dir.joinpath("student") - save_dir.mkdir(exist_ok=True) - self.copy_to_student(d_layers_to_copy, e_layers_to_copy, hparams, student, teacher) student.save_pretrained(save_dir) hparams.model_name_or_path = str(save_dir) diff --git a/examples/text-classification/run_xnli.py b/examples/text-classification/run_xnli.py index f0ee5120fa..c1db6fa37c 100644 --- a/examples/text-classification/run_xnli.py +++ b/examples/text-classification/run_xnli.py @@ -573,10 +573,6 @@ def main(): # Saving best-practices: if you use defaults names for the model, you can reload it using from_pretrained() if args.do_train and (args.local_rank == -1 or torch.distributed.get_rank() == 0): - # Create output directory if needed - if not os.path.exists(args.output_dir) and args.local_rank in [-1, 0]: - os.makedirs(args.output_dir) - logger.info("Saving model checkpoint to %s", args.output_dir) # Save a trained model, configuration and tokenizer using `save_pretrained()`. # They can then be reloaded using `from_pretrained()` diff --git a/src/transformers/configuration_utils.py b/src/transformers/configuration_utils.py index 5414753ab1..9929ee4c19 100644 --- a/src/transformers/configuration_utils.py +++ b/src/transformers/configuration_utils.py @@ -132,10 +132,9 @@ class PretrainedConfig(object): save_directory (:obj:`string`): Directory where the configuration JSON file will be saved. """ - assert os.path.isdir( - save_directory - ), "Saving path should be a directory where the model and configuration can be saved" - + if os.path.isfile(save_directory): + raise AssertionError("Provided path ({}) should be a directory, not a file".format(save_directory)) + os.makedirs(save_directory, exist_ok=True) # If we save using the predefined names, we can load using `from_pretrained` output_config_file = os.path.join(save_directory, CONFIG_NAME) diff --git a/src/transformers/convert_pytorch_checkpoint_to_tf2.py b/src/transformers/convert_pytorch_checkpoint_to_tf2.py index 91dd2e8908..d3a6140fdc 100755 --- a/src/transformers/convert_pytorch_checkpoint_to_tf2.py +++ b/src/transformers/convert_pytorch_checkpoint_to_tf2.py @@ -240,7 +240,6 @@ def convert_all_pt_checkpoints_to_tf( remove_cached_files=False, only_convert_finetuned_models=False, ): - assert os.path.isdir(args.tf_dump_path), "--tf_dump_path should be a directory" if args_model_type is None: model_types = list(MODEL_CLASSES.keys()) diff --git a/src/transformers/modeling_tf_utils.py b/src/transformers/modeling_tf_utils.py index 050589984c..648e434f48 100644 --- a/src/transformers/modeling_tf_utils.py +++ b/src/transformers/modeling_tf_utils.py @@ -315,9 +315,10 @@ class TFPreTrainedModel(tf.keras.Model, TFModelUtilsMixin): """ Save a model and its configuration file to a directory, so that it can be re-loaded using the :func:`~transformers.PreTrainedModel.from_pretrained` class method. """ - assert os.path.isdir( - save_directory - ), "Saving path should be a directory where the model and configuration can be saved" + if os.path.isfile(save_directory): + logger.error("Provided path ({}) should be a directory, not a file".format(save_directory)) + return + os.makedirs(save_directory, exist_ok=True) # Save configuration file self.config.save_pretrained(save_directory) diff --git a/src/transformers/modeling_utils.py b/src/transformers/modeling_utils.py index 015dea5d7e..91a167a837 100644 --- a/src/transformers/modeling_utils.py +++ b/src/transformers/modeling_utils.py @@ -477,9 +477,10 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin): Arguments: save_directory: directory to which to save. """ - assert os.path.isdir( - save_directory - ), "Saving path should be a directory where the model and configuration can be saved" + if os.path.isfile(save_directory): + logger.error("Provided path ({}) should be a directory, not a file".format(save_directory)) + return + os.makedirs(save_directory, exist_ok=True) # Only save the model itself if we are using distributed training model_to_save = self.module if hasattr(self, "module") else self diff --git a/src/transformers/pipelines.py b/src/transformers/pipelines.py index 9b70b6bf89..e46358cd75 100755 --- a/src/transformers/pipelines.py +++ b/src/transformers/pipelines.py @@ -405,9 +405,10 @@ class Pipeline(_ScikitCompat): """ Save the pipeline's model and tokenizer to the specified save_directory """ - if not os.path.isdir(save_directory): - logger.error("Provided path ({}) should be a directory".format(save_directory)) + if os.path.isfile(save_directory): + logger.error("Provided path ({}) should be a directory, not a file".format(save_directory)) return + os.makedirs(save_directory, exist_ok=True) self.model.save_pretrained(save_directory) self.tokenizer.save_pretrained(save_directory) diff --git a/src/transformers/tokenization_utils_base.py b/src/transformers/tokenization_utils_base.py index db9b4e45e7..073d84a948 100644 --- a/src/transformers/tokenization_utils_base.py +++ b/src/transformers/tokenization_utils_base.py @@ -1343,9 +1343,10 @@ class PreTrainedTokenizerBase(SpecialTokensMixin): This method make sure the full tokenizer can then be re-loaded using the :func:`~transformers.PreTrainedTokenizer.from_pretrained` class method. """ - if not os.path.isdir(save_directory): - logger.error("Saving directory ({}) should be a directory".format(save_directory)) + if os.path.isfile(save_directory): + logger.error("Provided path ({}) should be a directory, not a file".format(save_directory)) return + os.makedirs(save_directory, exist_ok=True) special_tokens_map_file = os.path.join(save_directory, SPECIAL_TOKENS_MAP_FILE) added_tokens_file = os.path.join(save_directory, ADDED_TOKENS_FILE) diff --git a/templates/adding_a_new_example_script/run_xxx.py b/templates/adding_a_new_example_script/run_xxx.py index 6a86685f7d..67cc154c63 100644 --- a/templates/adding_a_new_example_script/run_xxx.py +++ b/templates/adding_a_new_example_script/run_xxx.py @@ -653,10 +653,6 @@ def main(): # Save the trained model and the tokenizer if args.do_train and (args.local_rank == -1 or torch.distributed.get_rank() == 0): - # Create output directory if needed - if not os.path.exists(args.output_dir) and args.local_rank in [-1, 0]: - os.makedirs(args.output_dir) - logger.info("Saving model checkpoint to %s", args.output_dir) # Save a trained model, configuration and tokenizer using `save_pretrained()`. # They can then be reloaded using `from_pretrained()`