From 422bdbfcd53ef2c6a6805d8ce5ef1d187a186661 Mon Sep 17 00:00:00 2001 From: Hunor Laczko Date: Sat, 17 Jun 2023 09:32:48 +0000 Subject: [PATCH] add checkpoint utils --- .gitignore | 1 + utils/checkpoints.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 utils/checkpoints.py diff --git a/.gitignore b/.gitignore index fa7a81b..cf334b4 100644 --- a/.gitignore +++ b/.gitignore @@ -165,5 +165,6 @@ temp/ dataset/ wandb_login.py custom_data/dijsktra* +checkpoints/ *.out diff --git a/utils/checkpoints.py b/utils/checkpoints.py new file mode 100644 index 0000000..30db495 --- /dev/null +++ b/utils/checkpoints.py @@ -0,0 +1,43 @@ +import torch +import numpy as np +import os +import logging + + +class CheckpointSaver: + def __init__(self, dirpath, top_n=5): + """ + dirpath: Directory path where to store all model weights + decreasing: If decreasing is `True`, then lower metric is better + top_n: Total number of models to track based on validation metric value + """ + if not os.path.exists(dirpath): os.makedirs(dirpath) + self.dirpath = dirpath + self.top_n = top_n + self.top_model_paths = [] + + def __call__(self, model, iteration, optimizer, scaler): + model_path = os.path.join(self.dirpath, f'iteration_{iteration}.pt') + torch.save({ 'model': model.state_dict(), 'optimizer': optimizer, 'scaler': scaler }, model_path) + self.top_model_paths.append({'path': model_path}) + if len(self.top_model_paths)>self.top_n: + self.cleanup() + + def cleanup(self): + to_remove = self.top_model_paths[:len(self.top_model_paths)-self.top_n] + logging.info(f"Removing extra models.. {to_remove}") + for o in to_remove: + os.remove(o['path']) + self.top_model_paths = self.top_model_paths[len(self.top_model_paths)-self.top_n:] + + +def load_model(model: torch.nn.Module, checkpoint, optimizer: torch.nn.Module=None, scaler: torch.nn.Module=None, iteration=''): + # list of checkpoint files in the folder checkpoints + checkpoints = [os.path.join(checkpoint, f) for f in os.listdir(checkpoint) if f.endswith(f'{iteration}.pt')] + checkpoint = torch.load(checkpoints[-1]) + iteration = checkpoints[-1].split('_')[-1].split('.')[0] + model.load_state_dict(checkpoint['model']) + if optimizer is not None: optimizer.load_state_dict(checkpoint['optimizer'].state_dict()) + if scaler is not None and checkpoint['scaler'] is not None: scaler.load_state_dict(checkpoint['scaler']) + return int(iteration) if iteration != '' else 0 +