Compare commits

...
Author SHA1 Message Date
Sam Shleifer c1e44a3147 boom boom 2020-09-21 20:12:16 -04:00
Sam Shleifer 21f2672f5b boom boom 2020-09-21 20:08:10 -04:00
Sam Shleifer 248d2e7b91 debug: log more to json 2020-09-21 19:51:33 -04:00
Sam Shleifer cd3f362621 type hints 2020-09-21 15:46:44 -04:00
Sam Shleifer d449ef0cc6 Set dataset size 2020-09-21 15:24:54 -04:00
Sam Shleifer c06ecf10cb Merge branch 'master' into bump-pl 2020-09-21 13:26:46 -04:00
Sam Shleifer 87f69d6566 Wierd failure 2020-09-21 13:23:49 -04:00
Sam Shleifer cb36ccb53f Merge branch 'master' into bump-pl 2020-09-21 13:06:33 -04:00
Sam Shleifer 09846c2ff8 Merge branch 'master' into bump-pl 2020-09-10 17:44:38 -04:00
Sam Shleifer 6b68d3121f bump pl=0.9.0 2020-09-10 13:58:23 -04:00
7 changed files with 40 additions and 40 deletions

No files matched your search

+7 -6
View File
@@ -119,7 +119,7 @@ class BaseTransformer(pl.LightningModule):
def get_lr_scheduler(self): def get_lr_scheduler(self):
get_schedule_func = arg_to_scheduler[self.hparams.lr_scheduler] get_schedule_func = arg_to_scheduler[self.hparams.lr_scheduler]
scheduler = get_schedule_func( scheduler = get_schedule_func(
self.opt, num_warmup_steps=self.hparams.warmup_steps, num_training_steps=self.total_steps self.opt, num_warmup_steps=self.hparams.warmup_steps, num_training_steps=self.total_steps()
) )
scheduler = {"scheduler": scheduler, "interval": "step", "frequency": 1} scheduler = {"scheduler": scheduler, "interval": "step", "frequency": 1}
return scheduler return scheduler
@@ -159,19 +159,20 @@ class BaseTransformer(pl.LightningModule):
def test_epoch_end(self, outputs): def test_epoch_end(self, outputs):
return self.validation_end(outputs) return self.validation_end(outputs)
@property
def total_steps(self) -> int: def total_steps(self) -> int:
"""The number of total training steps that will be run. Used for lr scheduler purposes.""" """The number of total training steps that will be run. Used for lr scheduler purposes."""
num_devices = max(1, self.hparams.gpus) # TODO: consider num_tpu_cores num_devices = max(1, self.hparams.gpus) # TODO: consider num_tpu_cores
effective_batch_size = self.hparams.train_batch_size * self.hparams.accumulate_grad_batches * num_devices effective_batch_size = self.hparams.train_batch_size * self.hparams.accumulate_grad_batches * num_devices
dataset_size = len(self.train_loader.dataset) return (self.dataset_size / effective_batch_size) * self.hparams.max_epochs
return (dataset_size / effective_batch_size) * self.hparams.max_epochs
def setup(self, mode): def setup(self, mode):
if mode == "fit": if mode == "test":
self.dataset_size = len(self.test_dataloader().dataset)
else:
self.train_loader = self.get_dataloader("train", self.hparams.train_batch_size, shuffle=True) self.train_loader = self.get_dataloader("train", self.hparams.train_batch_size, shuffle=True)
self.dataset_size = len(self.train_loader.dataset)
def get_dataloader(self, type_path, batch_size, shuffle=False): def get_dataloader(self, type_path: str, batch_size: int, shuffle: bool = False):
raise NotImplementedError("You must implement this for your task") raise NotImplementedError("You must implement this for your task")
def train_dataloader(self): def train_dataloader(self):
+1 -1
View File
@@ -5,7 +5,7 @@ psutil
sacrebleu sacrebleu
rouge-score rouge-score
tensorflow_datasets tensorflow_datasets
pytorch-lightning==0.8.5 pytorch-lightning==0.9.0
matplotlib matplotlib
git-python==1.0.3 git-python==1.0.3
faiss faiss
+14 -2
View File
@@ -227,7 +227,9 @@ python run_eval.py sshleifer/distilbart-cnn-12-6 $DATA_DIR/val.source dbart_val_
--fp16 \ --fp16 \
--bs 32 --bs 32
``` ```
### Multi-GPU Evalulation
### Multi-GPU Evaluation
here is a command to run xsum evaluation on 8 GPUS. It is more than linearly faster than run_eval.py in some cases here is a command to run xsum evaluation on 8 GPUS. It is more than linearly faster than run_eval.py in some cases
because it uses SortishSampler to minimize padding. You can also use it on 1 GPU. `data_dir` must have because it uses SortishSampler to minimize padding. You can also use it on 1 GPU. `data_dir` must have
`{type_path}.source` and `{type_path}.target`. Run `python run_distributed_eval.py --help` for all clargs. `{type_path}.source` and `{type_path}.target`. Run `python run_distributed_eval.py --help` for all clargs.
@@ -353,6 +355,17 @@ runtime: 13H on V-100 16GB GPU.
pytest examples/seq2seq/ pytest examples/seq2seq/
``` ```
### Converting pytorch-lightning checkpoints
pytorch lightning ``-do_predict`` often fails, after you are done training, the best way to evaluate your model is to convert it.
This should be done for you, with a file called `{save_dir}/best_tfmr`.
If that file doesn't exist but you have a lightning `.ckpt` file, you can run
```bash
python convert_pl_checkpoint_to_hf.py PATH_TO_CKPT randomly_initialized_hf_model_path save_dir/best_tfmr
```
Then either `run_eval` or `run_distributed_eval` with `save_dir/best_tfmr` (see previous sections)
## Experimental Features ## Experimental Features
These features are harder to use and not always useful. These features are harder to use and not always useful.
@@ -381,4 +394,3 @@ uses 12,723 batches of length 48 and takes slightly more time 9.5 minutes.
The feature is still experimental, because: The feature is still experimental, because:
+ we can make it much more robust if we have memory mapped/preprocessed datasets. + we can make it much more robust if we have memory mapped/preprocessed datasets.
+ The speedup over sortish sampler is not that large at the moment. + The speedup over sortish sampler is not that large at the moment.
-26
View File
@@ -13,7 +13,6 @@ from torch.nn import functional as F
from finetune import SummarizationModule, TranslationModule from finetune import SummarizationModule, TranslationModule
from finetune import main as ft_main from finetune import main as ft_main
from initialization_utils import copy_layers, init_student from initialization_utils import copy_layers, init_student
from lightning_base import generic_train
from transformers import AutoModelForSeq2SeqLM, MBartTokenizer, T5Config, T5ForConditionalGeneration from transformers import AutoModelForSeq2SeqLM, MBartTokenizer, T5Config, T5ForConditionalGeneration
from transformers.modeling_bart import shift_tokens_right from transformers.modeling_bart import shift_tokens_right
from utils import ( from utils import (
@@ -22,7 +21,6 @@ from utils import (
calculate_bleu, calculate_bleu,
freeze_params, freeze_params,
label_smoothed_nll_loss, label_smoothed_nll_loss,
pickle_load,
use_task_specific_params, use_task_specific_params,
) )
@@ -412,30 +410,6 @@ def create_module(args):
return model return model
def evaluate_checkpoint(ckpt_path: Path, dest_dir=None):
# TODO(SS): DELETE? Better to convert_pl_ckpt_to_hf and run_eval.py
exp_dir = ckpt_path.parent
if dest_dir is None:
dest_dir = exp_dir
clash = list(dest_dir.glob("test_generations*"))
if clash:
print(f"SKIPPING to avoid overwriting {clash}")
ckpt = torch.load(ckpt_path, map_location="cpu")
if "hparams" in ckpt:
args = argparse.Namespace(**ckpt["hparams"])
else:
args = argparse.Namespace(**pickle_load(exp_dir / "hparams.pkl"))
args.resume_from_checkpoint = str(ckpt_path)
args.do_train = False
args.output_dir = str(dest_dir)
args.n_gpu = 1
args.eval_batch_size = 16
Path(args.output_dir).mkdir(exist_ok=True)
model = create_module(args)
trainer: pl.Trainer = generic_train(model, args, early_stopping_callback=False)
trainer.test(model)
LAYERS_TO_COPY = { LAYERS_TO_COPY = {
# maps num layers in student -> which teacher layers to copy. # maps num layers in student -> which teacher layers to copy.
# 12: bart, 16: pegasus, 6: marian/Helsinki-NLP # 12: bart, 16: pegasus, 6: marian/Helsinki-NLP
+15 -1
View File
@@ -36,7 +36,7 @@ from utils import (
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
from pytorch_lightning.utilities import rank_zero_only
class SummarizationModule(BaseTransformer): class SummarizationModule(BaseTransformer):
mode = "summarization" mode = "summarization"
@@ -183,6 +183,20 @@ class SummarizationModule(BaseTransformer):
losses.update(generative_metrics) losses.update(generative_metrics)
all_metrics = {f"{prefix}_avg_{k}": x for k, x in losses.items()} all_metrics = {f"{prefix}_avg_{k}": x for k, x in losses.items()}
all_metrics["step_count"] = self.step_count all_metrics["step_count"] = self.step_count
def get_date_str(seconds=True) -> str:
"""Returns 2019-09-25-10:02:07, for example."""
if seconds:
return time.strftime('%Y-%m-%d-%H:%M:%S')
else:
return time.strftime('%Y-%m-%d-%H:%M')
all_metrics['Time'] = get_date_str(seconds=True)
#all_metrics['n_obs'] =
all_metrics['rank'] = getattr(self.train_dataloader(), '_rank', -1.)
self.save_metrics(all_metrics, prefix) # writes to self.metrics_save_path self.save_metrics(all_metrics, prefix) # writes to self.metrics_save_path
preds = flatten_list([x["preds"] for x in outputs]) preds = flatten_list([x["preds"] for x in outputs])
return { return {
+1 -4
View File
@@ -13,7 +13,7 @@ import torch
import lightning_base import lightning_base
from convert_pl_checkpoint_to_hf import convert_pl_to_hf from convert_pl_checkpoint_to_hf import convert_pl_to_hf
from distillation import distill_main, evaluate_checkpoint from distillation import distill_main
from finetune import SummarizationModule, main from finetune import SummarizationModule, main
from run_eval import generate_summaries_or_translations, run_generate from run_eval import generate_summaries_or_translations, run_generate
from run_eval_search import run_search from run_eval_search import run_search
@@ -177,7 +177,6 @@ class TestSummarizationDistiller(unittest.TestCase):
generate_summaries_or_translations(examples, out_path, str(model.output_dir / "best_tfmr")) generate_summaries_or_translations(examples, out_path, str(model.output_dir / "best_tfmr"))
self.assertTrue(Path(out_path).exists()) self.assertTrue(Path(out_path).exists())
evaluate_checkpoint(ckpts[0], dest_dir=Path(tempfile.mkdtemp()))
out_path_new = tempfile.mkdtemp() out_path_new = tempfile.mkdtemp()
convert_pl_to_hf(ckpts[0], transformer_ckpts[0].parent, out_path_new) convert_pl_to_hf(ckpts[0], transformer_ckpts[0].parent, out_path_new)
assert os.path.exists(os.path.join(out_path_new, "pytorch_model.bin")) assert os.path.exists(os.path.join(out_path_new, "pytorch_model.bin"))
@@ -226,8 +225,6 @@ class TestSummarizationDistiller(unittest.TestCase):
assert len(all_files) > 2 assert len(all_files) > 2
self.assertEqual(len(transformer_ckpts), 2) self.assertEqual(len(transformer_ckpts), 2)
evaluate_checkpoint(ckpts[0], dest_dir=Path(tempfile.mkdtemp()))
@unittest.skip("T5 distillation is broken at the moment") @unittest.skip("T5 distillation is broken at the moment")
def test_distill_t5(self): def test_distill_t5(self):
updates = dict( updates = dict(
+2
View File
@@ -276,10 +276,12 @@ class DistributedSortishSampler(Sampler):
if not dist.is_available(): if not dist.is_available():
raise RuntimeError("Requires distributed package to be available") raise RuntimeError("Requires distributed package to be available")
num_replicas = dist.get_world_size() num_replicas = dist.get_world_size()
self._rank = -1
if rank is None: if rank is None:
if not dist.is_available(): if not dist.is_available():
raise RuntimeError("Requires distributed package to be available") raise RuntimeError("Requires distributed package to be available")
rank = dist.get_rank() rank = dist.get_rank()
self._rank = rank
self.dataset = dataset self.dataset = dataset
self.num_replicas = num_replicas self.num_replicas = num_replicas
self.rank = rank self.rank = rank