| """ |
| Copyright (c) Meta Platforms, Inc. and affiliates. |
| """ |
|
|
| import datetime |
|
|
| curr_time = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") |
|
|
| import argparse |
| import os |
| import pprint |
|
|
| import torch |
|
|
| from utils.config_parser import init_config |
|
|
| |
|
|
| torch.backends.cudnn.benchmark = True |
| import numpy as np |
|
|
| import pkg_resources |
|
|
| from datasets.get_dataset import get_dataset |
|
|
| from fblearner.flow.util.visualization_utils import summary_writer |
|
|
| from losses.get_loss import get_loss |
|
|
| from models.get_model import get_model |
|
|
| from trainer.get_trainer import get_trainer |
|
|
| |
| from utils.manifold_utils import MANIFOLD_BUCKET, MANIFOLD_PATH, pathmgr |
|
|
| from utils.torch_utils import init_seed |
|
|
|
|
| def main_ddp(rank, world_size, cfg): |
| init_seed(cfg.seed) |
|
|
| |
| os.environ["MASTER_ADDR"] = "localhost" |
| os.environ["MASTER_PORT"] = "12356" |
|
|
| torch.distributed.init_process_group( |
| backend="nccl", rank=rank, world_size=world_size |
| ) |
|
|
| device = torch.device("cuda:%d" % rank) |
| torch.cuda.set_device(device) |
| print(f"Use GPU {rank} ({torch.cuda.get_device_name(rank)}) for training") |
|
|
| |
| train_sets, valid_sets, train_sets_epoches = get_dataset(cfg.data) |
| if rank == 0: |
| print( |
| "train sets: " |
| + ", ".join( |
| ["{} ({} samples)".format(ds.name, len(ds)) for ds in train_sets] |
| ) |
| ) |
| print( |
| "val sets: " |
| + ", ".join( |
| ["{} ({} samples)".format(ds.name, len(ds)) for ds in valid_sets] |
| ) |
| ) |
|
|
| train_sets_epoches = [np.inf if e == -1 else e for e in train_sets_epoches] |
|
|
| train_loaders, valid_loaders = [], [] |
| for ds in train_sets: |
| sampler = torch.utils.data.DistributedSampler( |
| ds, num_replicas=world_size, rank=rank, shuffle=True, drop_last=True |
| ) |
| train_loader = torch.utils.data.DataLoader( |
| ds, |
| batch_size=cfg.train.batch_size // world_size, |
| num_workers=cfg.train.workers // world_size, |
| pin_memory=True, |
| sampler=sampler, |
| ) |
| train_loaders.append(train_loader) |
|
|
| if rank == 0: |
| |
| writer = summary_writer(log_dir=cfg.save_root) |
|
|
| |
| for ds in valid_sets: |
| valid_loader = torch.utils.data.DataLoader( |
| ds, |
| batch_size=4, |
| num_workers=4, |
| pin_memory=True, |
| shuffle=False, |
| drop_last=False, |
| ) |
| valid_loaders.append(valid_loader) |
| valid_size = sum([len(loader) for loader in valid_loaders]) |
| if cfg.train.valid_size == 0: |
| cfg.train.valid_size = valid_size |
| cfg.train.valid_size = min(cfg.train.valid_size, valid_size) |
|
|
| else: |
| writer = None |
| valid_loaders = [] |
|
|
| |
| model = get_model(cfg.model).to(device) |
| model = torch.nn.parallel.DistributedDataParallel( |
| model, |
| device_ids=[rank], |
| output_device=rank, |
| ) |
|
|
| |
| loss = get_loss(cfg.loss) |
|
|
| |
| trainer = get_trainer(cfg.trainer)( |
| train_loaders, |
| valid_loaders, |
| model, |
| loss, |
| cfg.save_root, |
| cfg.train, |
| resume=cfg.resume, |
| train_sets_epoches=train_sets_epoches, |
| summary_writer=writer, |
| rank=rank, |
| world_size=world_size, |
| ) |
|
|
| trainer.train() |
|
|
| torch.distributed.destroy_process_group() |
|
|
|
|
| def main(args, run_id=None): |
|
|
| |
| if args.resume is not None: |
| args.config = os.path.join( |
| "manifold://", MANIFOLD_BUCKET, MANIFOLD_PATH, args.resume, "config.json" |
| ) |
| else: |
| args.config = pkg_resources.resource_filename(__name__, args.config) |
|
|
| |
| cfg = init_config(args.config) |
| cfg.train.n_gpu = args.n_gpu |
|
|
| |
| cfg.train.DEBUG = args.DEBUG |
| if args.DEBUG: |
| cfg.data.update( |
| { |
| "epoches_raw": 3, |
| } |
| ) |
| cfg.train.update( |
| { |
| "batch_size": 4, |
| "epoch_num": 5, |
| "epoch_size": 20, |
| "print_freq": 1, |
| "record_freq": 1, |
| "val_epoch_size": 2, |
| "valid_size": 4, |
| "save_iter": 2, |
| } |
| ) |
| if "stage1" in cfg.train: |
| cfg.train.stage1.update({"epoch": 5}) |
| if "stage2" in cfg.train: |
| cfg.train.stage2.update({"epoch": 5}) |
|
|
| |
| if args.model is not None: |
| cfg.train.pretrained_model = args.model |
|
|
| |
| if args.resume is not None: |
| cfg.resume = True |
| cfg.save_root = os.path.join( |
| "manifold://", MANIFOLD_BUCKET, MANIFOLD_PATH, args.resume |
| ) |
| else: |
| cfg.resume = False |
| args.name = os.path.basename(args.config)[:-5] |
|
|
| dirname = curr_time + "_" + args.name |
| if run_id is not None: |
| dirname = dirname + "_f" + str(run_id) |
| if args.DEBUG: |
| dirname = "_DEBUG_" + dirname |
|
|
| cfg.save_root = os.path.join( |
| "manifold://", |
| MANIFOLD_BUCKET, |
| MANIFOLD_PATH, |
| args.exp_folder, |
| dirname, |
| ) |
|
|
| |
|
|
| if not pathmgr.exists(cfg.save_root): |
| pathmgr.mkdirs(cfg.save_root) |
|
|
| pathmgr.copy_from_local( |
| args.config, os.path.join(cfg.save_root, "config.json") |
| ) |
|
|
| if "base_configs" in cfg: |
| pathmgr.copy_from_local( |
| os.path.join(os.path.dirname(args.config), cfg.base_configs), |
| os.path.join(cfg.save_root, cfg.base_configs), |
| ) |
|
|
| """ |
| ## for the linux file system |
| os.makedirs(cfg.save_root) |
| os.system( |
| "cp {} {}".format(args.config, os.path.join(cfg.save_root, "config.json")) |
| ) |
| if "base_configs" in cfg: |
| os.system( |
| "cp {} {}".format( |
| os.path.join(os.path.dirname(args.config), cfg.base_configs), |
| os.path.join(cfg.save_root, cfg.base_configs), |
| ) |
| ) |
| """ |
|
|
| print("=> will save everything to {}".format(cfg.save_root)) |
|
|
| |
| cfg_str = pprint.pformat(cfg) |
| print("=> configurations \n " + cfg_str) |
|
|
| |
| world_size = args.n_gpu |
| torch.multiprocessing.spawn( |
| main_ddp, |
| args=(world_size, cfg), |
| nprocs=world_size, |
| ) |
|
|
| print("Completed!") |
| return |
|
|
|
|
| def invoke_main() -> None: |
| parser = argparse.ArgumentParser() |
| parser.add_argument("-c", "--config", default="configs/base_kitti.json") |
| parser.add_argument("-m", "--model", default=None) |
| parser.add_argument("--exp_folder", default="other") |
| parser.add_argument("-n", "--name", default=None) |
| parser.add_argument("-r", "--resume", default=None) |
| parser.add_argument("--n_gpu", type=int, default=2) |
| parser.add_argument("--DEBUG", action="store_true") |
| args = parser.parse_args() |
|
|
| main(args) |
|
|
|
|
| if __name__ == "__main__": |
| invoke_main() |
|
|