From fe8f5c0e693001fadd58a8d0c38ac2185cd9d05f Mon Sep 17 00:00:00 2001 From: skpig <479469418@qq.com> Date: Sun, 21 Nov 2021 14:15:13 +0800 Subject: [PATCH 1/5] Add multi node training in CycleMLP --- image_classification/CycleMLP/README.md | 53 +- .../CycleMLP/main_multi_node.py | 575 ++++++++++++++++++ .../CycleMLP/run_train_multi_node.sh | 8 + 3 files changed, 632 insertions(+), 4 deletions(-) create mode 100644 image_classification/CycleMLP/main_multi_node.py create mode 100644 image_classification/CycleMLP/run_train_multi_node.sh diff --git a/image_classification/CycleMLP/README.md b/image_classification/CycleMLP/README.md index ac65489d..5abfb60f 100644 --- a/image_classification/CycleMLP/README.md +++ b/image_classification/CycleMLP/README.md @@ -126,6 +126,7 @@ python main_multi_gpu.py \ ## Training +### Training with single GPU To train the CycleMLP model on ImageNet2012 with single GPUs, run the following script using command line: ```shell sh run_train.sh @@ -140,11 +141,9 @@ python main_single_gpu.py \ -data_path='/dataset/imagenet' \ ``` -
- - +### Training with multi-GPU Run training using multi-GPUs: - + ```shell @@ -160,9 +159,55 @@ python main_multi_gpu.py \ -data_path='/dataset/imagenet' \ ``` + + +### Training with multi-node +PaddleVit also supports multi-node distributed training under collective mode. + +Suppose you have 2 hosts (denoted as node) with 4 gpus on each machine. +Nodes IP addresses are `192.168.0.16` and `192.168.0.17`. + +Then some lines of `run_train_multi_node.sh` should be modified: +```shell +CUDA_VISIBLE_DEVICES=0,1,2,3 # number of gpus + +-ips= '192.168.0.16, 192.168.0.17' # seperated by comma +``` +Run training script in every node: +```shell +sh run_train_multi.sh +``` + +
+It is possible to train with multi-node even when you have only one machine + +1. Install docker and paddle. For more details, please refer to + [here](https://www.paddlepaddle.org.cn/documentation/docs/zh/install/docker/fromdocker.html). + +2. Create a network between docker containers. + ```shell + docker network create -d bridge paddle_net + ``` +3. Create multiple containers as virtual hosts/nodes. Suppose creating 2 containers +with 2 gpus on each node. + ```shell + docker run --name paddle0 -it -d --gpus "device=0,1" --network paddle_net\ + paddlepaddle/paddle:2.2.0-gpu-cuda10.2-cudnn7 /bin/bash + docker run --name paddle1 -it -d --gpus "device=2,3" --network paddle_net\ + paddlepaddle/paddle:2.2.0-gpu-cuda10.2-cudnn7 /bin/bash + ``` + Noted: + 1. One can assign same gpu device to different containers. But it may occur OOM + since multiple models will run on the same gpu. + 2. One should use `-v` to bind PaddleViT repository to container. +4. Modify `run_train_multi_node.sh` as described above and run the training script on every container. + + Noted: One can use `ping` or `ip -a` bash command to check containers' ip addresses. +
+ ## Visualization Attention Map **(coming soon)** diff --git a/image_classification/CycleMLP/main_multi_node.py b/image_classification/CycleMLP/main_multi_node.py new file mode 100644 index 00000000..5e2d3482 --- /dev/null +++ b/image_classification/CycleMLP/main_multi_node.py @@ -0,0 +1,575 @@ +# Copyright (c) 2021 PPViT Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""CycleMLP training/validation using multiple GPU """ + +import sys +import os +import time +import logging +import argparse +import random +import numpy as np +import paddle +import paddle.nn as nn +import paddle.nn.functional as F +import paddle.distributed as dist +from datasets import get_dataloader +from datasets import get_dataset +from utils import AverageMeter +from utils import WarmupCosineScheduler +from utils import get_exclude_from_weight_decay_fn +from config import get_config +from config import update_config +from mixup import Mixup +from losses import LabelSmoothingCrossEntropyLoss +from losses import SoftTargetCrossEntropyLoss +from losses import DistillationLoss +from cyclemlp import build_cyclemlp as build_model + + +def get_arguments(): + """return argumeents, this will overwrite the config after loading yaml file""" + parser = argparse.ArgumentParser('Swin') + parser.add_argument('-cfg', type=str, default=None) + parser.add_argument('-dataset', type=str, default=None) + parser.add_argument('-batch_size', type=int, default=None) + parser.add_argument('-image_size', type=int, default=None) + parser.add_argument('-data_path', type=str, default=None) + parser.add_argument('-ngpus', type=int, default=None) + parser.add_argument('-pretrained', type=str, default=None) + parser.add_argument('-resume', type=str, default=None) + parser.add_argument('-last_epoch', type=int, default=None) + parser.add_argument('-eval', action='store_true') + parser.add_argument('-amp', action='store_true') + parser.add_argument('-ips', type=str, default="127.0.0.1") + arguments = parser.parse_args() + return arguments + + +def get_logger(filename, logger_name=None): + """set logging file and format + Args: + filename: str, full path of the logger file to write + logger_name: str, the logger name, e.g., 'master_logger', 'local_logger' + Return: + logger: python logger + """ + log_format = "%(asctime)s %(message)s" + logging.basicConfig(stream=sys.stdout, level=logging.INFO, + format=log_format, datefmt="%m%d %I:%M:%S %p") + # different name is needed when creating multiple logger in one process + logger = logging.getLogger(logger_name) + fh = logging.FileHandler(os.path.join(filename)) + fh.setFormatter(logging.Formatter(log_format)) + logger.addHandler(fh) + return logger + + +def train(dataloader, + model, + criterion, + optimizer, + epoch, + total_epochs, + total_batch, + debug_steps=100, + accum_iter=1, + mixup_fn=None, + amp=False, + local_logger=None, + master_logger=None): + """Training for one epoch + Args: + dataloader: paddle.io.DataLoader, dataloader instance + model: nn.Layer, a ViT model + criterion: nn.criterion + epoch: int, current epoch + total_epochs: int, total num of epochs + total_batch: int, total num of batches for one epoch + debug_steps: int, num of iters to log info, default: 100 + accum_iter: int, num of iters for accumulating gradients, default: 1 + mixup_fn: Mixup, mixup instance, default: None + amp: bool, if True, use mix precision training, default: False + local_logger: logger for local process/gpu, default: None + master_logger: logger for main process, default: None + Returns: + train_loss_meter.avg: float, average loss on current process/gpu + train_acc_meter.avg: float, average top1 accuracy on current process/gpu + master_train_loss_meter.avg: float, average loss on all processes/gpus + master_train_acc_meter.avg: float, average top1 accuracy on all processes/gpus + train_time: float, training time + """ + model.train() + train_loss_meter = AverageMeter() + train_acc_meter = AverageMeter() + master_train_loss_meter = AverageMeter() + master_train_acc_meter = AverageMeter() + + if amp is True: + scaler = paddle.amp.GradScaler(init_loss_scaling=1024) + time_st = time.time() + + for batch_id, data in enumerate(dataloader): + image = data[0] + label = data[1] + label_orig = label.clone() + + if mixup_fn is not None: + image, label = mixup_fn(image, label_orig) + + if amp is True: # mixed precision training + with paddle.amp.auto_cast(): + output = model(image) + loss = criterion(image, output, label) + scaled = scaler.scale(loss) + scaled.backward() + if ((batch_id +1) % accum_iter == 0) or (batch_id + 1 == len(dataloader)): + scaler.minimize(optimizer, scaled) + optimizer.clear_grad() + else: # full precision training + output = model(image) + loss = criterion(output, label) + #NOTE: division may be needed depending on the loss function + # Here no division is needed: + # default 'reduction' param in nn.CrossEntropyLoss is set to 'mean' + #loss = loss / accum_iter + loss.backward() + + if ((batch_id +1) % accum_iter == 0) or (batch_id + 1 == len(dataloader)): + optimizer.step() + optimizer.clear_grad() + + pred = F.softmax(output) + if mixup_fn: + acc = paddle.metric.accuracy(pred, label_orig) + else: + acc = paddle.metric.accuracy(pred, label_orig.unsqueeze(1)) + + batch_size = paddle.to_tensor(image.shape[0]) + + # sync from other gpus for overall loss and acc + master_loss = loss.clone() + master_acc = acc.clone() + master_batch_size = batch_size.clone() + dist.all_reduce(master_loss) + dist.all_reduce(master_acc) + dist.all_reduce(master_batch_size) + master_loss = master_loss / dist.get_world_size() + master_acc = master_acc / dist.get_world_size() + master_train_loss_meter.update(master_loss.numpy()[0], master_batch_size.numpy()[0]) + master_train_acc_meter.update(master_acc.numpy()[0], master_batch_size.numpy()[0]) + + train_loss_meter.update(loss.numpy()[0], batch_size.numpy()[0]) + train_acc_meter.update(acc.numpy()[0], batch_size.numpy()[0]) + + if batch_id % debug_steps == 0: + if local_logger: + local_logger.info( + f"Epoch[{epoch:03d}/{total_epochs:03d}], " + + f"Step[{batch_id:04d}/{total_batch:04d}], " + + f"Avg Loss: {train_loss_meter.avg:.4f}, " + + f"Avg Acc: {train_acc_meter.avg:.4f}") + if master_logger and dist.get_rank() == 0: + master_logger.info( + f"Epoch[{epoch:03d}/{total_epochs:03d}], " + + f"Step[{batch_id:04d}/{total_batch:04d}], " + + f"Avg Loss: {master_train_loss_meter.avg:.4f}, " + + f"Avg Acc: {master_train_acc_meter.avg:.4f}") + + train_time = time.time() - time_st + return (train_loss_meter.avg, + train_acc_meter.avg, + master_train_loss_meter.avg, + master_train_acc_meter.avg, + train_time) + + +def validate(dataloader, + model, + criterion, + total_batch, + debug_steps=100, + local_logger=None, + master_logger=None): + """Validation for whole dataset + Args: + dataloader: paddle.io.DataLoader, dataloader instance + model: nn.Layer, a ViT model + criterion: nn.criterion + total_epoch: int, total num of epoch, for logging + debug_steps: int, num of iters to log info, default: 100 + local_logger: logger for local process/gpu, default: None + master_logger: logger for main process, default: None + Returns: + val_loss_meter.avg: float, average loss on current process/gpu + val_acc1_meter.avg: float, average top1 accuracy on current process/gpu + val_acc5_meter.avg: float, average top5 accuracy on current process/gpu + master_val_loss_meter.avg: float, average loss on all processes/gpus + master_val_acc1_meter.avg: float, average top1 accuracy on all processes/gpus + master_val_acc5_meter.avg: float, average top5 accuracy on all processes/gpus + val_time: float, validation time + """ + model.eval() + val_loss_meter = AverageMeter() + val_acc1_meter = AverageMeter() + val_acc5_meter = AverageMeter() + master_val_loss_meter = AverageMeter() + master_val_acc1_meter = AverageMeter() + master_val_acc5_meter = AverageMeter() + time_st = time.time() + + with paddle.no_grad(): + for batch_id, data in enumerate(dataloader): + image = data[0] + label = data[1] + + output = model(image) + loss = criterion(output, label) + + pred = F.softmax(output) + acc1 = paddle.metric.accuracy(pred, label.unsqueeze(1)) + acc5 = paddle.metric.accuracy(pred, label.unsqueeze(1), k=5) + + batch_size = paddle.to_tensor(image.shape[0]) + + master_loss = loss.clone() + master_acc1 = acc1.clone() + master_acc5 = acc5.clone() + master_batch_size = batch_size.clone() + + dist.all_reduce(master_loss) + dist.all_reduce(master_acc1) + dist.all_reduce(master_acc5) + dist.all_reduce(master_batch_size) + master_loss = master_loss / dist.get_world_size() + master_acc1 = master_acc1 / dist.get_world_size() + master_acc5 = master_acc5 / dist.get_world_size() + + master_val_loss_meter.update(master_loss.numpy()[0], master_batch_size.numpy()[0]) + master_val_acc1_meter.update(master_acc1.numpy()[0], master_batch_size.numpy()[0]) + master_val_acc5_meter.update(master_acc5.numpy()[0], master_batch_size.numpy()[0]) + + val_loss_meter.update(loss.numpy()[0], batch_size.numpy()[0]) + val_acc1_meter.update(acc1.numpy()[0], batch_size.numpy()[0]) + val_acc5_meter.update(acc5.numpy()[0], batch_size.numpy()[0]) + + if batch_id % debug_steps == 0: + if local_logger: + local_logger.info( + f"Val Step[{batch_id:04d}/{total_batch:04d}], " + + f"Avg Loss: {val_loss_meter.avg:.4f}, " + + f"Avg Acc@1: {val_acc1_meter.avg:.4f}, " + + f"Avg Acc@5: {val_acc5_meter.avg:.4f}") + if master_logger and dist.get_rank() == 0: + master_logger.info( + f"Val Step[{batch_id:04d}/{total_batch:04d}], " + + f"Avg Loss: {master_val_loss_meter.avg:.4f}, " + + f"Avg Acc@1: {master_val_acc1_meter.avg:.4f}, " + + f"Avg Acc@5: {master_val_acc5_meter.avg:.4f}") + val_time = time.time() - time_st + return (val_loss_meter.avg, + val_acc1_meter.avg, + val_acc5_meter.avg, + master_val_loss_meter.avg, + master_val_acc1_meter.avg, + master_val_acc5_meter.avg, + val_time) + + +def main_worker(*args): + # STEP 0: Preparation + config = args[0] + dist.init_parallel_env() + last_epoch = config.TRAIN.LAST_EPOCH + world_size = dist.get_world_size() + local_rank = dist.get_rank() + seed = config.SEED + local_rank + paddle.seed(seed) + np.random.seed(seed) + random.seed(seed) + # logger for each process/gpu + local_logger = get_logger( + filename=os.path.join(config.SAVE, 'log_{}.txt'.format(local_rank)), + logger_name='local_logger') + # overall logger + if local_rank == 0: + master_logger = get_logger( + filename=os.path.join(config.SAVE, 'log.txt'), + logger_name='master_logger') + master_logger.info(f'\n{config}') + else: + master_logger = None + local_logger.info(f'----- world_size = {world_size}, local_rank = {local_rank}') + if local_rank == 0: + master_logger.info(f'----- world_size = {world_size}, local_rank = {local_rank}') + + # STEP 1: Create model + model = build_model(config) + model = paddle.DataParallel(model) + + # STEP 2: Create train and val dataloader + dataset_train, dataset_val = args[1], args[2] + dataloader_train = get_dataloader(config, dataset_train, 'train', True) + dataloader_val = get_dataloader(config, dataset_val, 'test', True) + total_batch_train = len(dataloader_train) + total_batch_val = len(dataloader_val) + local_logger.info(f'----- Total # of train batch (single gpu): {total_batch_train}') + local_logger.info(f'----- Total # of val batch (single gpu): {total_batch_val}') + if local_rank == 0: + master_logger.info(f'----- Total # of train batch (single gpu): {total_batch_train}') + master_logger.info(f'----- Total # of val batch (single gpu): {total_batch_val}') + + # STEP 3: Define Mixup function + mixup_fn = None + if config.TRAIN.MIXUP_PROB > 0 or config.TRAIN.CUTMIX_ALPHA > 0 or config.TRAIN.CUTMIX_MINMAX is not None: + mixup_fn = Mixup(mixup_alpha=config.TRAIN.MIXUP_ALPHA, + cutmix_alpha=config.TRAIN.CUTMIX_ALPHA, + cutmix_minmax=config.TRAIN.CUTMIX_MINMAX, + prob=config.TRAIN.MIXUP_PROB, + switch_prob=config.TRAIN.MIXUP_SWITCH_PROB, + mode=config.TRAIN.MIXUP_MODE, + label_smoothing=config.TRAIN.SMOOTHING) + + # STEP 4: Define criterion + if config.TRAIN.MIXUP_PROB > 0.: + criterion = SoftTargetCrossEntropyLoss() + elif config.TRAIN.SMOOTHING: + criterion = LabelSmoothingCrossEntropyLoss() + else: + criterion = nn.CrossEntropyLoss() + # only use cross entropy for val + criterion_val = nn.CrossEntropyLoss() + + # STEP 5: Define optimizer and lr_scheduler + # set lr according to batch size and world size (hacked from official code) + linear_scaled_lr = (config.TRAIN.BASE_LR * + config.DATA.BATCH_SIZE * dist.get_world_size()) / 512.0 + linear_scaled_warmup_start_lr = (config.TRAIN.WARMUP_START_LR * + config.DATA.BATCH_SIZE * dist.get_world_size()) / 512.0 + linear_scaled_end_lr = (config.TRAIN.END_LR * + config.DATA.BATCH_SIZE * dist.get_world_size()) / 512.0 + + if config.TRAIN.ACCUM_ITER > 1: + linear_scaled_lr = linear_scaled_lr * config.TRAIN.ACCUM_ITER + linear_scaled_warmup_start_lr = linear_scaled_warmup_start_lr * config.TRAIN.ACCUM_ITER + linear_scaled_end_lr = linear_scaled_end_lr * config.TRAIN.ACCUM_ITER + + config.TRAIN.BASE_LR = linear_scaled_lr + config.TRAIN.WARMUP_START_LR = linear_scaled_warmup_start_lr + config.TRAIN.END_LR = linear_scaled_end_lr + + scheduler = None + if config.TRAIN.LR_SCHEDULER.NAME == "warmupcosine": + scheduler = WarmupCosineScheduler(learning_rate=config.TRAIN.BASE_LR, + warmup_start_lr=config.TRAIN.WARMUP_START_LR, + start_lr=config.TRAIN.BASE_LR, + end_lr=config.TRAIN.END_LR, + warmup_epochs=config.TRAIN.WARMUP_EPOCHS, + total_epochs=config.TRAIN.NUM_EPOCHS, + last_epoch=config.TRAIN.LAST_EPOCH, + ) + elif config.TRAIN.LR_SCHEDULER.NAME == "cosine": + scheduler = paddle.optimizer.lr.CosineAnnealingDecay(learning_rate=config.TRAIN.BASE_LR, + T_max=config.TRAIN.NUM_EPOCHS, + last_epoch=last_epoch) + elif config.scheduler == "multi-step": + milestones = [int(v.strip()) for v in config.TRAIN.LR_SCHEDULER.MILESTONES.split(",")] + scheduler = paddle.optimizer.lr.MultiStepDecay(learning_rate=config.TRAIN.BASE_LR, + milestones=milestones, + gamma=config.TRAIN.LR_SCHEDULER.DECAY_RATE, + last_epoch=last_epoch) + else: + local_logger.fatal(f"Unsupported Scheduler: {config.TRAIN.LR_SCHEDULER}.") + if local_rank == 0: + master_logger.fatal(f"Unsupported Scheduler: {config.TRAIN.LR_SCHEDULER}.") + raise NotImplementedError(f"Unsupported Scheduler: {config.TRAIN.LR_SCHEDULER}.") + + if config.TRAIN.OPTIMIZER.NAME == "SGD": + if config.TRAIN.GRAD_CLIP: + clip = paddle.nn.ClipGradByGlobalNorm(config.TRAIN.GRAD_CLIP) + else: + clip = None + optimizer = paddle.optimizer.Momentum( + parameters=model.parameters(), + learning_rate=scheduler if scheduler is not None else config.TRAIN.BASE_LR, + weight_decay=config.TRAIN.WEIGHT_DECAY, + momentum=config.TRAIN.OPTIMIZER.MOMENTUM, + grad_clip=clip) + elif config.TRAIN.OPTIMIZER.NAME == "AdamW": + if config.TRAIN.GRAD_CLIP: + clip = paddle.nn.ClipGradByGlobalNorm(config.TRAIN.GRAD_CLIP) + else: + clip = None + optimizer = paddle.optimizer.AdamW( + parameters=model.parameters(), + learning_rate=scheduler if scheduler is not None else config.TRAIN.BASE_LR, + beta1=config.TRAIN.OPTIMIZER.BETAS[0], + beta2=config.TRAIN.OPTIMIZER.BETAS[1], + weight_decay=config.TRAIN.WEIGHT_DECAY, + epsilon=config.TRAIN.OPTIMIZER.EPS, + grad_clip=clip, + apply_decay_param_fun=get_exclude_from_weight_decay_fn([ + 'absolute_pos_embed', 'relative_position_bias_table']), + ) + else: + local_logger.fatal(f"Unsupported Optimizer: {config.TRAIN.OPTIMIZER.NAME}.") + if local_rank == 0: + master_logger.fatal(f"Unsupported Optimizer: {config.TRAIN.OPTIMIZER.NAME}.") + raise NotImplementedError(f"Unsupported Optimizer: {config.TRAIN.OPTIMIZER.NAME}.") + + # STEP 6: Load pretrained model / load resumt model and optimizer states + if config.MODEL.PRETRAINED: + if (config.MODEL.PRETRAINED).endswith('.pdparams'): + raise ValueError(f'{config.MODEL.PRETRAINED} should not contain .pdparams') + assert os.path.isfile(config.MODEL.PRETRAINED + '.pdparams') is True + model_state = paddle.load(config.MODEL.PRETRAINED+'.pdparams') + model.set_dict(model_state) + local_logger.info(f"----- Pretrained: Load model state from {config.MODEL.PRETRAINED}") + if local_rank == 0: + master_logger.info( + f"----- Pretrained: Load model state from {config.MODEL.PRETRAINED}") + + if config.MODEL.RESUME: + assert os.path.isfile(config.MODEL.RESUME+'.pdparams') is True + assert os.path.isfile(config.MODEL.RESUME+'.pdopt') is True + model_state = paddle.load(config.MODEL.RESUME+'.pdparams') + model.set_dict(model_state) + opt_state = paddle.load(config.MODEL.RESUME+'.pdopt') + optimizer.set_state_dict(opt_state) + local_logger.info( + f"----- Resume Training: Load model and optmizer from {config.MODEL.RESUME}") + if local_rank == 0: + master_logger.info( + f"----- Resume Training: Load model and optmizer from {config.MODEL.RESUME}") + + # STEP 7: Validation (eval mode) + if config.EVAL: + local_logger.info('----- Start Validating') + if local_rank == 0: + master_logger.info('----- Start Validating') + val_loss, val_acc1, val_acc5, avg_loss, avg_acc1, avg_acc5, val_time = validate( + dataloader=dataloader_val, + model=model, + criterion=criterion_val, + total_batch=total_batch_val, + debug_steps=config.REPORT_FREQ, + local_logger=local_logger, + master_logger=master_logger) + local_logger.info(f"Validation Loss: {val_loss:.4f}, " + + f"Validation Acc@1: {val_acc1:.4f}, " + + f"Validation Acc@5: {val_acc5:.4f}, " + + f"time: {val_time:.2f}") + if local_rank == 0: + master_logger.info(f"Validation Loss: {avg_loss:.4f}, " + + f"Validation Acc@1: {avg_acc1:.4f}, " + + f"Validation Acc@5: {avg_acc5:.4f}, " + + f"time: {val_time:.2f}") + return + + # STEP 8: Start training and validation (train mode) + local_logger.info(f"Start training from epoch {last_epoch+1}.") + if local_rank == 0: + master_logger.info(f"Start training from epoch {last_epoch+1}.") + for epoch in range(last_epoch+1, config.TRAIN.NUM_EPOCHS+1): + # train + local_logger.info(f"Now training epoch {epoch}. LR={optimizer.get_lr():.6f}") + if local_rank == 0: + master_logger.info(f"Now training epoch {epoch}. LR={optimizer.get_lr():.6f}") + train_loss, train_acc, avg_loss, avg_acc, train_time = train( + dataloader=dataloader_train, + model=model, + criterion=criterion, + optimizer=optimizer, + epoch=epoch, + total_epochs=config.TRAIN.NUM_EPOCHS, + total_batch=total_batch_train, + debug_steps=config.REPORT_FREQ, + accum_iter=config.TRAIN.ACCUM_ITER, + mixup_fn=mixup_fn, + amp=config.AMP, + local_logger=local_logger, + master_logger=master_logger) + + scheduler.step() + + local_logger.info(f"----- Epoch[{epoch:03d}/{config.TRAIN.NUM_EPOCHS:03d}], " + + f"Train Loss: {train_loss:.4f}, " + + f"Train Acc: {train_acc:.4f}, " + + f"time: {train_time:.2f}") + if local_rank == 0: + master_logger.info(f"----- Epoch[{epoch:03d}/{config.TRAIN.NUM_EPOCHS:03d}], " + + f"Train Loss: {avg_loss:.4f}, " + + f"Train Acc: {avg_acc:.4f}, " + + f"time: {train_time:.2f}") + + # validation + if epoch % config.VALIDATE_FREQ == 0 or epoch == config.TRAIN.NUM_EPOCHS: + local_logger.info(f'----- Validation after Epoch: {epoch}') + if local_rank == 0: + master_logger.info(f'----- Validation after Epoch: {epoch}') + val_loss, val_acc1, val_acc5, avg_loss, avg_acc1, avg_acc5, val_time = validate( + dataloader=dataloader_val, + model=model, + criterion=criterion_val, + total_batch=total_batch_val, + debug_steps=config.REPORT_FREQ, + local_logger=local_logger, + master_logger=master_logger) + local_logger.info(f"----- Epoch[{epoch:03d}/{config.TRAIN.NUM_EPOCHS:03d}], " + + f"Validation Loss: {val_loss:.4f}, " + + f"Validation Acc@1: {val_acc1:.4f}, " + + f"Validation Acc@5: {val_acc5:.4f}, " + + f"time: {val_time:.2f}") + if local_rank == 0: + master_logger.info(f"----- Epoch[{epoch:03d}/{config.TRAIN.NUM_EPOCHS:03d}], " + + f"Validation Loss: {avg_loss:.4f}, " + + f"Validation Acc@1: {avg_acc1:.4f}, " + + f"Validation Acc@5: {avg_acc5:.4f}, " + + f"time: {val_time:.2f}") + # model save + if local_rank == 0: + if epoch % config.SAVE_FREQ == 0 or epoch == config.TRAIN.NUM_EPOCHS: + model_path = os.path.join( + config.SAVE, f"{config.MODEL.TYPE}-Epoch-{epoch}-Loss-{train_loss}") + paddle.save(model.state_dict(), model_path + '.pdparams') + paddle.save(optimizer.state_dict(), model_path + '.pdopt') + master_logger.info(f"----- Save model: {model_path}.pdparams") + master_logger.info(f"----- Save optim: {model_path}.pdopt") + + +def main(): + # config is updated by: (1) config.py, (2) yaml file, (3) arguments + arguments = get_arguments() + config = get_config() + config = update_config(config, arguments) + + # set output folder + if not config.EVAL: + config.SAVE = '{}/train-{}'.format(config.SAVE, time.strftime('%Y%m%d-%H-%M-%S')) + else: + config.SAVE = '{}/eval-{}'.format(config.SAVE, time.strftime('%Y%m%d-%H-%M-%S')) + + if not os.path.exists(config.SAVE): + os.makedirs(config.SAVE, exist_ok=True) + + # get dataset and start DDP + dataset_train = get_dataset(config, mode='train') + dataset_val = get_dataset(config, mode='val') + config.NGPUS = len(paddle.static.cuda_places()) if config.NGPUS == -1 else config.NGPUS + dist.spawn(main_worker, args=(config, dataset_train, dataset_val, ), nprocs=config.NGPUS, ips=arguments.ips) + + +if __name__ == "__main__": + main() diff --git a/image_classification/CycleMLP/run_train_multi_node.sh b/image_classification/CycleMLP/run_train_multi_node.sh new file mode 100644 index 00000000..8a6ad31f --- /dev/null +++ b/image_classification/CycleMLP/run_train_multi_node.sh @@ -0,0 +1,8 @@ +CUDA_VISIBLE_DEVICES=0 \ +python main_multi_node.py \ +-cfg='./configs/cyclemlp_b1.yaml' \ +-dataset='imagenet2012' \ +-batch_size=8 \ +-data_path='/dataset/imagenet' \ +-ips='172.18.0.2, 172.18.0.3, 172.18.0.4, 172.18.0.5' # the ips should be replaced +#-amp From e50a112a3cbe5a0dc4de6c52f8edb2ea21f9d4a8 Mon Sep 17 00:00:00 2001 From: skpig <479469418@qq.com> Date: Sun, 21 Nov 2021 21:44:15 +0800 Subject: [PATCH 2/5] change README in CycleMLP --- image_classification/CycleMLP/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/image_classification/CycleMLP/README.md b/image_classification/CycleMLP/README.md index 5abfb60f..0c1df47c 100644 --- a/image_classification/CycleMLP/README.md +++ b/image_classification/CycleMLP/README.md @@ -196,13 +196,13 @@ with 2 gpus on each node. docker run --name paddle1 -it -d --gpus "device=2,3" --network paddle_net\ paddlepaddle/paddle:2.2.0-gpu-cuda10.2-cudnn7 /bin/bash ``` - Noted: - 1. One can assign same gpu device to different containers. But it may occur OOM - since multiple models will run on the same gpu. - 2. One should use `-v` to bind PaddleViT repository to container. + > Noted: + > 1. One can assign same gpu device to different containers. But it may occur OOM since multiple models will run on the same gpu. + > 2. One should use `-v` to bind PaddleViT repository to container. + 4. Modify `run_train_multi_node.sh` as described above and run the training script on every container. - Noted: One can use `ping` or `ip -a` bash command to check containers' ip addresses. + > Noted: One can use `ping` or `ip -a` bash command to check containers' ip addresses.
From e743b45982b9be38740669fee462e34b3b774578 Mon Sep 17 00:00:00 2001 From: skpig <479469418@qq.com> Date: Tue, 23 Nov 2021 11:52:18 +0800 Subject: [PATCH 3/5] Add Multi_Node_Training folder --- .../Multi_Node_Training/README.md | 1 + .../Multi_Node_Training/config.py | 153 ++++++ .../configs/vit_base_patch16_224.yaml | 21 + .../configs/vit_base_patch16_384.yaml | 14 + .../configs/vit_base_patch32_224.yaml | 21 + .../configs/vit_base_patch32_384.yaml | 21 + .../configs/vit_large_patch16_224.yaml | 14 + .../configs/vit_large_patch16_384.yaml | 14 + .../configs/vit_large_patch32_384.yaml | 14 + .../Multi_Node_Training/datasets.py | 187 ++++++++ .../Multi_Node_Training/droppath.py | 60 +++ .../Multi_Node_Training/main_multi_node.py | 379 +++++++++++++++ .../run_train_multi_node.sh | 8 + .../Multi_Node_Training/transformer.py | 437 ++++++++++++++++++ .../Multi_Node_Training/utils.py | 120 +++++ 15 files changed, 1464 insertions(+) create mode 100644 image_classification/Multi_Node_Training/README.md create mode 100644 image_classification/Multi_Node_Training/config.py create mode 100644 image_classification/Multi_Node_Training/configs/vit_base_patch16_224.yaml create mode 100644 image_classification/Multi_Node_Training/configs/vit_base_patch16_384.yaml create mode 100644 image_classification/Multi_Node_Training/configs/vit_base_patch32_224.yaml create mode 100644 image_classification/Multi_Node_Training/configs/vit_base_patch32_384.yaml create mode 100644 image_classification/Multi_Node_Training/configs/vit_large_patch16_224.yaml create mode 100644 image_classification/Multi_Node_Training/configs/vit_large_patch16_384.yaml create mode 100644 image_classification/Multi_Node_Training/configs/vit_large_patch32_384.yaml create mode 100644 image_classification/Multi_Node_Training/datasets.py create mode 100644 image_classification/Multi_Node_Training/droppath.py create mode 100644 image_classification/Multi_Node_Training/main_multi_node.py create mode 100644 image_classification/Multi_Node_Training/run_train_multi_node.sh create mode 100644 image_classification/Multi_Node_Training/transformer.py create mode 100644 image_classification/Multi_Node_Training/utils.py diff --git a/image_classification/Multi_Node_Training/README.md b/image_classification/Multi_Node_Training/README.md new file mode 100644 index 00000000..839e3dfa --- /dev/null +++ b/image_classification/Multi_Node_Training/README.md @@ -0,0 +1 @@ +# Multiple Node Training diff --git a/image_classification/Multi_Node_Training/config.py b/image_classification/Multi_Node_Training/config.py new file mode 100644 index 00000000..a7273699 --- /dev/null +++ b/image_classification/Multi_Node_Training/config.py @@ -0,0 +1,153 @@ +# Copyright (c) 2021 PPViT Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Configuration + +Configuration for data, model archtecture, and training, etc. +Config can be set by .yaml file or by argparser(limited usage) + + +""" +import os +from yacs.config import CfgNode as CN +import yaml + +_C = CN() +_C.BASE = [''] + +# data settings +_C.DATA = CN() +_C.DATA.BATCH_SIZE = 256 #256 # train batch_size for single GPU +_C.DATA.BATCH_SIZE_EVAL = 8 #64 # val batch_size for single GPU +_C.DATA.DATA_PATH = '/dataset/imagenet/' # path to dataset +_C.DATA.DATASET = 'imagenet2012' # dataset name +_C.DATA.IMAGE_SIZE = 224 # input image size: 224 for pretrain, 384 for finetune +_C.DATA.CROP_PCT = 0.875 # input image scale ratio, scale is applied before centercrop in eval mode +_C.DATA.NUM_WORKERS = 2 # number of data loading threads + +# model settings +_C.MODEL = CN() +_C.MODEL.TYPE = 'ViT' +_C.MODEL.NAME = 'ViT' +_C.MODEL.RESUME = None +_C.MODEL.PRETRAINED = None +_C.MODEL.NUM_CLASSES = 1000 +_C.MODEL.DROPOUT = 0.1 +_C.MODEL.DROPPATH = 0.1 +_C.MODEL.ATTENTION_DROPOUT = 0.1 + +# transformer settings +_C.MODEL.TRANS = CN() +_C.MODEL.TRANS.PATCH_SIZE = 32 +_C.MODEL.TRANS.EMBED_DIM = 768 +_C.MODEL.TRANS.MLP_RATIO= 4.0 +_C.MODEL.TRANS.NUM_HEADS = 12 +_C.MODEL.TRANS.DEPTH = 12 +_C.MODEL.TRANS.QKV_BIAS = True + +# training settings +_C.TRAIN = CN() +_C.TRAIN.LAST_EPOCH = 0 +_C.TRAIN.NUM_EPOCHS = 300 +_C.TRAIN.WARMUP_EPOCHS = 3 #34 # ~ 10k steps for 4096 batch size +_C.TRAIN.WEIGHT_DECAY = 0.05 #0.3 # 0.0 for finetune +_C.TRAIN.BASE_LR = 0.001 #0.003 for pretrain # 0.03 for finetune +_C.TRAIN.WARMUP_START_LR = 1e-6 #0.0 +_C.TRAIN.END_LR = 5e-4 +_C.TRAIN.GRAD_CLIP = 1.0 +_C.TRAIN.ACCUM_ITER = 2 #1 + +_C.TRAIN.LR_SCHEDULER = CN() +_C.TRAIN.LR_SCHEDULER.NAME = 'warmupcosine' +_C.TRAIN.LR_SCHEDULER.MILESTONES = "30, 60, 90" # only used in StepLRScheduler +_C.TRAIN.LR_SCHEDULER.DECAY_EPOCHS = 30 # only used in StepLRScheduler +_C.TRAIN.LR_SCHEDULER.DECAY_RATE = 0.1 # only used in StepLRScheduler + +_C.TRAIN.OPTIMIZER = CN() +_C.TRAIN.OPTIMIZER.NAME = 'AdamW' +_C.TRAIN.OPTIMIZER.EPS = 1e-8 +_C.TRAIN.OPTIMIZER.BETAS = (0.9, 0.999) # for adamW +_C.TRAIN.OPTIMIZER.MOMENTUM = 0.9 + +# misc +_C.SAVE = "./output" +_C.TAG = "default" +_C.SAVE_FREQ = 10 # freq to save chpt +_C.REPORT_FREQ = 100 # freq to logging info +_C.VALIDATE_FREQ = 100 # freq to do validation +_C.SEED = 0 +_C.EVAL = False # run evaluation only +_C.AMP = False # mix precision training +_C.LOCAL_RANK = 0 +_C.NGPUS = -1 + + +def _update_config_from_file(config, cfg_file): + config.defrost() + with open(cfg_file, 'r') as infile: + yaml_cfg = yaml.load(infile, Loader=yaml.FullLoader) + for cfg in yaml_cfg.setdefault('BASE', ['']): + if cfg: + _update_config_from_file( + config, os.path.join(os.path.dirname(cfg_file), cfg) + ) + print('merging config from {}'.format(cfg_file)) + config.merge_from_file(cfg_file) + config.freeze() + +def update_config(config, args): + """Update config by ArgumentParser + Args: + args: ArgumentParser contains options + Return: + config: updated config + """ + if args.cfg: + _update_config_from_file(config, args.cfg) + config.defrost() + if args.dataset: + config.DATA.DATASET = args.dataset + if args.batch_size: + config.DATA.BATCH_SIZE = args.batch_size + if args.image_size: + config.DATA.IMAGE_SIZE = args.image_size + if args.data_path: + config.DATA.DATA_PATH = args.data_path + if args.ngpus: + config.NGPUS = args.ngpus + if args.eval: + config.EVAL = True + config.DATA.BATCH_SIZE_EVAL = args.batch_size + if args.pretrained: + config.MODEL.PRETRAINED = args.pretrained + if args.resume: + config.MODEL.RESUME = args.resume + if args.last_epoch: + config.TRAIN.LAST_EPOCH = args.last_epoch + if args.amp: # only during training + if config.EVAL is True: + config.AMP = False + else: + config.AMP = True + + #config.freeze() + return config + + +def get_config(cfg_file=None): + """Return a clone of config or load from yaml file""" + config = _C.clone() + if cfg_file: + _update_config_from_file(config, cfg_file) + return config diff --git a/image_classification/Multi_Node_Training/configs/vit_base_patch16_224.yaml b/image_classification/Multi_Node_Training/configs/vit_base_patch16_224.yaml new file mode 100644 index 00000000..eff0fc29 --- /dev/null +++ b/image_classification/Multi_Node_Training/configs/vit_base_patch16_224.yaml @@ -0,0 +1,21 @@ +DATA: + IMAGE_SIZE: 224 + CROP_PCT: 0.875 +MODEL: + TYPE: ViT + NAME: vit_base_patch16_224 + TRANS: + PATCH_SIZE: 16 + EMBED_DIM: 768 + MLP_RATIO: 4.0 + DEPTH: 12 + NUM_HEADS: 12 + QKV_BIAS: true +TRAIN: + NUM_EPOCHS: 300 + WARMUP_EPOCHS: 3 + WEIGHT_DECAY: 0.3 + BASE_LR: 0.003 + WARMUP_START_LR: 1e-6 + END_LR: 5e-4 + ACCUM_ITER: 2 diff --git a/image_classification/Multi_Node_Training/configs/vit_base_patch16_384.yaml b/image_classification/Multi_Node_Training/configs/vit_base_patch16_384.yaml new file mode 100644 index 00000000..04cdfaee --- /dev/null +++ b/image_classification/Multi_Node_Training/configs/vit_base_patch16_384.yaml @@ -0,0 +1,14 @@ +DATA: + IMAGE_SIZE: 384 + CROP_PCT: 1.0 +MODEL: + TYPE: ViT + NAME: vit_base_patch16_384 + TRANS: + PATCH_SIZE: 16 + EMBED_DIM: 768 + MLP_RATIO: 4.0 + DEPTH: 12 + NUM_HEADS: 12 + QKV_BIAS: true + diff --git a/image_classification/Multi_Node_Training/configs/vit_base_patch32_224.yaml b/image_classification/Multi_Node_Training/configs/vit_base_patch32_224.yaml new file mode 100644 index 00000000..8b0516d2 --- /dev/null +++ b/image_classification/Multi_Node_Training/configs/vit_base_patch32_224.yaml @@ -0,0 +1,21 @@ +DATA: + IMAGE_SIZE: 224 + CROP_PCT: 0.875 +MODEL: + TYPE: ViT + NAME: vit_base_patch32_224 + TRANS: + PATCH_SIZE: 32 + EMBED_DIM: 768 + MLP_RATIO: 4.0 + DEPTH: 12 + NUM_HEADS: 12 + QKV_BIAS: true +TRAIN: + NUM_EPOCHS: 300 + WARMUP_EPOCHS: 3 + WEIGHT_DECAY: 0.3 + BASE_LR: 0.003 + WARMUP_START_LR: 1e-6 + END_LR: 5e-4 + ACCUM_ITER: 2 diff --git a/image_classification/Multi_Node_Training/configs/vit_base_patch32_384.yaml b/image_classification/Multi_Node_Training/configs/vit_base_patch32_384.yaml new file mode 100644 index 00000000..5aa3e6f1 --- /dev/null +++ b/image_classification/Multi_Node_Training/configs/vit_base_patch32_384.yaml @@ -0,0 +1,21 @@ +DATA: + IMAGE_SIZE: 384 + CROP_PCT: 1.0 +MODEL: + TYPE: ViT + NAME: vit_base_patch32_384 + TRANS: + PATCH_SIZE: 32 + EMBED_DIM: 768 + MLP_RATIO: 4.0 + DEPTH: 12 + NUM_HEADS: 12 + QKV_BIAS: true +TRAIN: + NUM_EPOCHS: 300 + WARMUP_EPOCHS: 3 + WEIGHT_DECAY: 0.3 + BASE_LR: 0.003 + WARMUP_START_LR: 1e-6 + END_LR: 5e-4 + ACCUM_ITER: 2 diff --git a/image_classification/Multi_Node_Training/configs/vit_large_patch16_224.yaml b/image_classification/Multi_Node_Training/configs/vit_large_patch16_224.yaml new file mode 100644 index 00000000..23ac9b37 --- /dev/null +++ b/image_classification/Multi_Node_Training/configs/vit_large_patch16_224.yaml @@ -0,0 +1,14 @@ +DATA: + IMAGE_SIZE: 224 + CROP_PCT: 0.875 +MODEL: + TYPE: ViT + NAME: vit_large_patch16_224 + TRANS: + PATCH_SIZE: 16 + EMBED_DIM: 1024 + MLP_RATIO: 4.0 + DEPTH: 24 + NUM_HEADS: 16 + QKV_BIAS: true + diff --git a/image_classification/Multi_Node_Training/configs/vit_large_patch16_384.yaml b/image_classification/Multi_Node_Training/configs/vit_large_patch16_384.yaml new file mode 100644 index 00000000..c8c01a6a --- /dev/null +++ b/image_classification/Multi_Node_Training/configs/vit_large_patch16_384.yaml @@ -0,0 +1,14 @@ +DATA: + IMAGE_SIZE: 384 + CROP_PCT: 1.0 +MODEL: + TYPE: ViT + NAME: vit_large_patch16_384 + TRANS: + PATCH_SIZE: 16 + EMBED_DIM: 1024 + MLP_RATIO: 4.0 + DEPTH: 24 + NUM_HEADS: 16 + QKV_BIAS: true + diff --git a/image_classification/Multi_Node_Training/configs/vit_large_patch32_384.yaml b/image_classification/Multi_Node_Training/configs/vit_large_patch32_384.yaml new file mode 100644 index 00000000..6b7f15aa --- /dev/null +++ b/image_classification/Multi_Node_Training/configs/vit_large_patch32_384.yaml @@ -0,0 +1,14 @@ +DATA: + IMAGE_SIZE: 384 + CROP_PCT: 1.0 +MODEL: + TYPE: ViT + NAME: vit_large_patch32_384 + TRANS: + PATCH_SIZE: 32 + EMBED_DIM: 1024 + MLP_RATIO: 4.0 + DEPTH: 24 + NUM_HEADS: 16 + QKV_BIAS: true + diff --git a/image_classification/Multi_Node_Training/datasets.py b/image_classification/Multi_Node_Training/datasets.py new file mode 100644 index 00000000..e207f9ba --- /dev/null +++ b/image_classification/Multi_Node_Training/datasets.py @@ -0,0 +1,187 @@ +# Copyright (c) 2021 PPViT Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Dataset related classes and methods for ViT training and validation +Cifar10, Cifar100 and ImageNet2012 are supported +""" + +import os +import math +from paddle.io import Dataset, DataLoader, DistributedBatchSampler +from paddle.vision import transforms, datasets, image_load + +class ImageNet2012Dataset(Dataset): + """Build ImageNet2012 dataset + + This class gets train/val imagenet datasets, which loads transfomed data and labels. + + Attributes: + file_folder: path where imagenet images are stored + transform: preprocessing ops to apply on image + img_path_list: list of full path of images in whole dataset + label_list: list of labels of whole dataset + """ + + def __init__(self, file_folder, mode="train", transform=None): + """Init ImageNet2012 Dataset with dataset file path, mode(train/val), and transform""" + super(ImageNet2012Dataset, self).__init__() + assert mode in ["train", "val"] + self.file_folder = file_folder + self.transform = transform + self.img_path_list = [] + self.label_list = [] + + if mode == "train": + self.list_file = os.path.join(self.file_folder, "train_list.txt") + else: + self.list_file = os.path.join(self.file_folder, "val_list.txt") + + with open(self.list_file, 'r') as infile: + for line in infile: + img_path = line.strip().split()[0] + img_label = int(line.strip().split()[1]) + self.img_path_list.append(os.path.join(self.file_folder, img_path)) + self.label_list.append(img_label) + print(f'----- Imagenet2012 image {mode} list len = {len(self.label_list)}') + + def __len__(self): + return len(self.label_list) + + def __getitem__(self, index): + data = image_load(self.img_path_list[index]).convert('RGB') + data = self.transform(data) + label = self.label_list[index] + + return data, label + + +def get_train_transforms(config): + """ Get training transforms + + For training, a RandomResizedCrop is applied, then normalization is applied with + [0.5, 0.5, 0.5] mean and std. The input pixel values must be rescaled to [0, 1.] + Outputs is converted to tensor + + Args: + config: configs contains IMAGE_SIZE, see config.py for details + Returns: + transforms_train: training transforms + """ + + transforms_train = transforms.Compose([ + transforms.RandomResizedCrop((config.DATA.IMAGE_SIZE, config.DATA.IMAGE_SIZE), + scale=(0.05, 1.0)), + transforms.ToTensor(), + transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), + #transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), + ]) + return transforms_train + + +def get_val_transforms(config): + """ Get training transforms + + For validation, image is first Resize then CenterCrop to image_size. + Then normalization is applied with [0.5, 0.5, 0.5] mean and std. + The input pixel values must be rescaled to [0, 1.] + Outputs is converted to tensor + + Args: + config: configs contains IMAGE_SIZE, see config.py for details + Returns: + transforms_train: training transforms + """ + + scale_size = int(math.floor(config.DATA.IMAGE_SIZE / config.DATA.CROP_PCT)) + transforms_val = transforms.Compose([ + transforms.Resize(scale_size, 'bicubic'), # single int for resize shorter side of image + transforms.CenterCrop((config.DATA.IMAGE_SIZE, config.DATA.IMAGE_SIZE)), + transforms.ToTensor(), + transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), + #transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), + ]) + return transforms_val + + +def get_dataset(config, mode='train'): + """ Get dataset from config and mode (train/val) + + Returns the related dataset object according to configs and mode(train/val) + + Args: + config: configs contains dataset related settings. see config.py for details + Returns: + dataset: dataset object + """ + assert mode in ['train', 'val'] + if config.DATA.DATASET == "cifar10": + if mode == 'train': + dataset = datasets.Cifar10(mode=mode, transform=get_train_transforms(config)) + else: + mode = 'test' + dataset = datasets.Cifar10(mode=mode, transform=get_val_transforms(config)) + elif config.DATA.DATASET == "cifar100": + if mode == 'train': + dataset = datasets.Cifar100(mode=mode, transform=get_train_transforms(config)) + else: + mode = 'test' + dataset = datasets.Cifar100(mode=mode, transform=get_val_transforms(config)) + elif config.DATA.DATASET == "imagenet2012": + if mode == 'train': + dataset = ImageNet2012Dataset(config.DATA.DATA_PATH, + mode=mode, + transform=get_train_transforms(config)) + else: + dataset = ImageNet2012Dataset(config.DATA.DATA_PATH, + mode=mode, + transform=get_val_transforms(config)) + else: + raise NotImplementedError( + "[{config.DATA.DATASET}] Only cifar10, cifar100, imagenet2012 are supported now") + return dataset + + +def get_dataloader(config, dataset, mode='train', multi_process=False): + """Get dataloader with config, dataset, mode as input, allows multiGPU settings. + + Multi-GPU loader is implements as distributedBatchSampler. + + Args: + config: see config.py for details + dataset: paddle.io.dataset object + mode: train/val + multi_process: if True, use DistributedBatchSampler to support multi-processing + Returns: + dataloader: paddle.io.DataLoader object. + """ + + if mode == 'train': + batch_size = config.DATA.BATCH_SIZE + else: + batch_size = config.DATA.BATCH_SIZE_EVAL + + if multi_process is True: + sampler = DistributedBatchSampler(dataset, + batch_size=batch_size, + shuffle=(mode == 'train')) + dataloader = DataLoader(dataset, + batch_sampler=sampler, + num_workers=config.DATA.NUM_WORKERS) + else: + dataloader = DataLoader(dataset, + batch_size=batch_size, + num_workers=config.DATA.NUM_WORKERS, + shuffle=(mode == 'train')) + return dataloader diff --git a/image_classification/Multi_Node_Training/droppath.py b/image_classification/Multi_Node_Training/droppath.py new file mode 100644 index 00000000..25b8d5ff --- /dev/null +++ b/image_classification/Multi_Node_Training/droppath.py @@ -0,0 +1,60 @@ +# Copyright (c) 2021 PPViT Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Droppath, reimplement from https://github.com/yueatsprograms/Stochastic_Depth +""" + +import paddle +import paddle.nn as nn + + +class DropPath(nn.Layer): + """DropPath class""" + def __init__(self, drop_prob=None): + super(DropPath, self).__init__() + self.drop_prob = drop_prob + + def drop_path(self, inputs): + """drop path op + Args: + input: tensor with arbitrary shape + drop_prob: float number of drop path probability, default: 0.0 + training: bool, if current mode is training, default: False + Returns: + output: output tensor after drop path + """ + # if prob is 0 or eval mode, return original input + if self.drop_prob == 0. or not self.training: + return inputs + keep_prob = 1 - self.drop_prob + keep_prob = paddle.to_tensor(keep_prob, dtype='float32') + shape = (inputs.shape[0], ) + (1, ) * (inputs.ndim - 1) # shape=(N, 1, 1, 1) + random_tensor = keep_prob + paddle.rand(shape, dtype=inputs.dtype) + random_tensor = random_tensor.floor() # mask + output = inputs.divide(keep_prob) * random_tensor #divide is to keep same output expectation + return output + + def forward(self, inputs): + return self.drop_path(inputs) + + +#def main(): +# tmp = paddle.to_tensor(np.random.rand(8, 16, 8, 8), dtype='float32') +# dp = DropPath(0.5) +# out = dp(tmp) +# print(out) +# +#if __name__ == "__main__": +# main() diff --git a/image_classification/Multi_Node_Training/main_multi_node.py b/image_classification/Multi_Node_Training/main_multi_node.py new file mode 100644 index 00000000..bb0462b2 --- /dev/null +++ b/image_classification/Multi_Node_Training/main_multi_node.py @@ -0,0 +1,379 @@ +# Copyright (c) 2021 PPViT Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""ViT training/validation using multiple GPU """ + +import sys +import os +import time +import logging +import argparse +import random +import numpy as np +import paddle +import paddle.nn as nn +import paddle.nn.functional as F +import paddle.distributed as dist +from datasets import get_dataloader +from datasets import get_dataset +from transformer import build_vit as build_model +from utils import AverageMeter +from utils import WarmupCosineScheduler +from config import get_config +from config import update_config + + +parser = argparse.ArgumentParser('ViT') +parser.add_argument('-cfg', type=str, default=None) +parser.add_argument('-dataset', type=str, default=None) +parser.add_argument('-batch_size', type=int, default=None) +parser.add_argument('-image_size', type=int, default=None) +parser.add_argument('-data_path', type=str, default=None) +parser.add_argument('-ngpus', type=int, default=None) +parser.add_argument('-pretrained', type=str, default=None) +parser.add_argument('-resume', type=str, default=None) +parser.add_argument('-last_epoch', type=int, default=None) +parser.add_argument('-eval', action='store_true') +parser.add_argument('-amp', action='store_true') +parser.add_argument('-ips', type=str, default="127.0.0.1") +arguments = parser.parse_args() + + +log_format = "%(asctime)s %(message)s" +logging.basicConfig(stream=sys.stdout, level=logging.INFO, + format=log_format, datefmt="%m%d %I:%M:%S %p") + +# get default config +config = get_config() +# update config by arguments +config = update_config(config, arguments) + +# set output folder +if not config.EVAL: + config.SAVE = '{}/train-{}'.format(config.SAVE, time.strftime('%Y%m%d-%H-%M-%S')) +else: + config.SAVE = '{}/eval-{}'.format(config.SAVE, time.strftime('%Y%m%d-%H-%M-%S')) + +if not os.path.exists(config.SAVE): + os.makedirs(config.SAVE, exist_ok=True) + +# set logging format +logger = logging.getLogger() +fh = logging.FileHandler(os.path.join(config.SAVE, 'log.txt')) +fh.setFormatter(logging.Formatter(log_format)) +logger.addHandler(fh) +logger.info(f'config= {config}') + + +def train(dataloader, + model, + criterion, + optimizer, + epoch, + total_batch, + debug_steps=100, + accum_iter=1, + amp=False): + """Training for one epoch + Args: + dataloader: paddle.io.DataLoader, dataloader instance + model: nn.Layer, a ViT model + criterion: nn.criterion + epoch: int, current epoch + total_epoch: int, total num of epoch, for logging + debug_steps: int, num of iters to log info, default: 100 + accum_iter: int, num of iters for accumulating gradients, default: 1 + amp: bool, if True, use mix precision training, default: False + Returns: + train_loss_meter.avg + train_acc_meter.avg + train_time + """ + model.train() + train_loss_meter = AverageMeter() + train_acc_meter = AverageMeter() + if amp is True: + scaler = paddle.amp.GradScaler(init_loss_scaling=1024) + time_st = time.time() + + for batch_id, data in enumerate(dataloader): + image = data[0] + label = data[1] + + if amp is True: + with paddle.amp.auto_cast(): + output = model(image) + loss = criterion(output, label) + scaled = scaler.scale(loss) + scaled.backward() + + if ((batch_id +1) % accum_iter == 0) or (batch_id + 1 == len(dataloader)): + scaler.minimize(optimizer, scaled) + optimizer.clear_grad() + else: + output = model(image) + loss = criterion(output, label) + #NOTE: division may be needed depending on the loss function + # Here no division is needed: + # default 'reduction' param in nn.CrossEntropyLoss is set to 'mean' + # + #loss = loss / accum_iter + loss.backward() + + if ((batch_id +1) % accum_iter == 0) or (batch_id + 1 == len(dataloader)): + optimizer.step() + optimizer.clear_grad() + + pred = F.softmax(output) + acc = paddle.metric.accuracy(pred, label.unsqueeze(1)) + + batch_size = image.shape[0] + train_loss_meter.update(loss.numpy()[0], batch_size) + train_acc_meter.update(acc.numpy()[0], batch_size) + + if batch_id % debug_steps == 0: + logger.info( + f"Epoch[{epoch:03d}/{config.TRAIN.NUM_EPOCHS:03d}], " + + f"Step[{batch_id:04d}/{total_batch:04d}], " + + f"Avg Loss: {train_loss_meter.avg:.4f}, " + + f"Avg Acc: {train_acc_meter.avg:.4f}") + + train_time = time.time() - time_st + return train_loss_meter.avg, train_acc_meter.avg, train_time + + +def validate(dataloader, model, criterion, total_batch, debug_steps=100): + """Validation for whole dataset + Args: + dataloader: paddle.io.DataLoader, dataloader instance + model: nn.Layer, a ViT model + criterion: nn.criterion + total_epoch: int, total num of epoch, for logging + debug_steps: int, num of iters to log info + Returns: + val_loss_meter.avg + val_acc1_meter.avg + val_acc5_meter.avg + val_time + """ + model.eval() + val_loss_meter = AverageMeter() + val_acc1_meter = AverageMeter() + val_acc5_meter = AverageMeter() + time_st = time.time() + + with paddle.no_grad(): + for batch_id, data in enumerate(dataloader): + image = data[0] + label = data[1] + + output = model(image) + loss = criterion(output, label) + + pred = F.softmax(output) + acc1 = paddle.metric.accuracy(pred, label.unsqueeze(1)) + acc5 = paddle.metric.accuracy(pred, label.unsqueeze(1), k=5) + + dist.all_reduce(loss) + dist.all_reduce(acc1) + dist.all_reduce(acc5) + loss = loss / dist.get_world_size() + acc1 = acc1 / dist.get_world_size() + acc5 = acc5 / dist.get_world_size() + + batch_size = paddle.to_tensor(image.shape[0]) + dist.all_reduce(batch_size) + + val_loss_meter.update(loss.numpy()[0], batch_size.numpy()[0]) + val_acc1_meter.update(acc1.numpy()[0], batch_size.numpy()[0]) + val_acc5_meter.update(acc5.numpy()[0], batch_size.numpy()[0]) + + if batch_id % debug_steps == 0: + logger.info( + f"Val Step[{batch_id:04d}/{total_batch:04d}], " + + f"Avg Loss: {val_loss_meter.avg:.4f}, " + + f"Avg Acc@1: {val_acc1_meter.avg:.4f}, " + + f"Avg Acc@5: {val_acc5_meter.avg:.4f}") + + val_time = time.time() - time_st + return val_loss_meter.avg, val_acc1_meter.avg, val_acc5_meter.avg, val_time + + +def main_worker(*args): + # 0. Preparation + dist.init_parallel_env() + last_epoch = config.TRAIN.LAST_EPOCH + world_size = paddle.distributed.get_world_size() + local_rank = paddle.distributed.get_rank() + logger.info(f'----- world_size = {world_size}, local_rank = {local_rank}') + seed = config.SEED + local_rank + paddle.seed(seed) + np.random.seed(seed) + random.seed(seed) + # 1. Create model + model = build_model(config) + model = paddle.DataParallel(model) + # 2. Create train and val dataloader + dataset_train, dataset_val = args[0], args[1] + dataloader_train = get_dataloader(config, dataset_train, 'train', True) + dataloader_val = get_dataloader(config, dataset_val, 'test', True) + total_batch_train = len(dataloader_train) + total_batch_val = len(dataloader_val) + logging.info(f'----- Total # of train batch (single gpu): {total_batch_train}') + logging.info(f'----- Total # of val batch (single gpu): {total_batch_val}') + # 3. Define criterion + criterion = nn.CrossEntropyLoss() + # 4. Define optimizer and lr_scheduler + scheduler = None + if config.TRAIN.LR_SCHEDULER.NAME == "warmupcosine": + scheduler = WarmupCosineScheduler(learning_rate=config.TRAIN.BASE_LR, + warmup_start_lr=config.TRAIN.WARMUP_START_LR, + start_lr=config.TRAIN.BASE_LR, + end_lr=config.TRAIN.END_LR, + warmup_epochs=config.TRAIN.WARMUP_EPOCHS, + total_epochs=config.TRAIN.NUM_EPOCHS, + last_epoch=config.TRAIN.LAST_EPOCH, + ) + elif config.TRAIN.LR_SCHEDULER.NAME == "cosine": + scheduler = paddle.optimizer.lr.CosineAnnealingDecay(learning_rate=config.TRAIN.BASE_LR, + T_max=config.TRAIN.NUM_EPOCHS, + last_epoch=last_epoch) + elif config.scheduler == "multi-step": + milestones = [int(v.strip()) for v in config.TRAIN.LR_SCHEDULER.MILESTONES.split(",")] + scheduler = paddle.optimizer.lr.MultiStepDecay(learning_rate=config.TRAIN.BASE_LR, + milestones=milestones, + gamma=config.TRAIN.LR_SCHEDULER.DECAY_RATE, + last_epoch=last_epoch) + else: + logging.fatal(f"Unsupported Scheduler: {config.TRAIN.LR_SCHEDULER}.") + raise NotImplementedError(f"Unsupported Scheduler: {config.TRAIN.LR_SCHEDULER}.") + + if config.TRAIN.OPTIMIZER.NAME == "SGD": + if config.TRAIN.GRAD_CLIP: + clip = paddle.nn.ClipGradByGlobalNorm(config.TRAIN.GRAD_CLIP) + else: + clip = None + optimizer = paddle.optimizer.Momentum( + parameters=model.parameters(), + learning_rate=scheduler if scheduler is not None else config.TRAIN.BASE_LR, + weight_decay=config.TRAIN.WEIGHT_DECAY, + momentum=config.TRAIN.OPTIMIZER.MOMENTUM, + grad_clip=clip) + elif config.TRAIN.OPTIMIZER.NAME == "AdamW": + if config.TRAIN.GRAD_CLIP: + clip = paddle.nn.ClipGradByGlobalNorm(config.TRAIN.GRAD_CLIP) + else: + clip = None + optimizer = paddle.optimizer.AdamW( + parameters=model.parameters(), + learning_rate=scheduler if scheduler is not None else config.TRAIN.BASE_LR, + beta1=config.TRAIN.OPTIMIZER.BETAS[0], + beta2=config.TRAIN.OPTIMIZER.BETAS[1], + weight_decay=config.TRAIN.WEIGHT_DECAY, + epsilon=config.TRAIN.OPTIMIZER.EPS, + grad_clip=clip, + #apply_decay_param_fun=get_exclude_from_weight_decay_fn(['pos_embed', 'cls_token']), + ) + else: + logging.fatal(f"Unsupported Optimizer: {config.TRAIN.OPTIMIZER.NAME}.") + raise NotImplementedError(f"Unsupported Optimizer: {config.TRAIN.OPTIMIZER.NAME}.") + + # 5. Load pretrained model / load resumt model and optimizer states + if config.MODEL.PRETRAINED: + if (config.MODEL.PRETRAINED).endswith('.pdparams'): + raise ValueError(f'{config.MODEL.PRETRAINED} should not contain .pdparams') + assert os.path.isfile(config.MODEL.PRETRAINED + '.pdparams') is True + model_state = paddle.load(config.MODEL.PRETRAINED+'.pdparams') + model.set_dict(model_state) + logger.info(f"----- Pretrained: Load model state from {config.MODEL.PRETRAINED}") + + if config.MODEL.RESUME: + assert os.path.isfile(config.MODEL.RESUME+'.pdparams') is True + assert os.path.isfile(config.MODEL.RESUME+'.pdopt') is True + model_state = paddle.load(config.MODEL.RESUME+'.pdparams') + model.set_dict(model_state) + opt_state = paddle.load(config.MODEL.RESUME+'.pdopt') + optimizer.set_state_dict(opt_state) + logger.info( + f"----- Resume Training: Load model and optmizer states from {config.MODEL.RESUME}") + + # 6. Validation + if config.EVAL: + logger.info('----- Start Validating') + val_loss, val_acc1, val_acc5, val_time = validate( + dataloader=dataloader_val, + model=model, + criterion=criterion, + total_batch=total_batch_val, + debug_steps=config.REPORT_FREQ) + logger.info(f"Validation Loss: {val_loss:.4f}, " + + f"Validation Acc@1: {val_acc1:.4f}, " + + f"Validation Acc@5: {val_acc5:.4f}, " + + f"time: {val_time:.2f}") + return + + # 6. Start training and validation + logging.info(f"Start training from epoch {last_epoch+1}.") + for epoch in range(last_epoch+1, config.TRAIN.NUM_EPOCHS+1): + # train + logging.info(f"Now training epoch {epoch}. LR={optimizer.get_lr():.6f}") + train_loss, train_acc, train_time = train(dataloader=dataloader_train, + model=model, + criterion=criterion, + optimizer=optimizer, + epoch=epoch, + total_batch=total_batch_train, + debug_steps=config.REPORT_FREQ, + accum_iter=config.TRAIN.ACCUM_ITER, + amp=config.AMP) + scheduler.step() + + logger.info(f"----- Epoch[{epoch:03d}/{config.TRAIN.NUM_EPOCHS:03d}], " + + f"Train Loss: {train_loss:.4f}, " + + f"Train Acc: {train_acc:.4f}, " + + f"time: {train_time:.2f}") + # validation + if epoch % config.VALIDATE_FREQ == 0 or epoch == config.TRAIN.NUM_EPOCHS: + logger.info(f'----- Validation after Epoch: {epoch}') + val_loss, val_acc1, val_acc5, val_time = validate( + dataloader=dataloader_val, + model=model, + criterion=criterion, + total_batch=total_batch_val, + debug_steps=config.REPORT_FREQ) + logger.info(f"----- Epoch[{epoch:03d}/{config.TRAIN.NUM_EPOCHS:03d}], " + + f"Validation Loss: {val_loss:.4f}, " + + f"Validation Acc@1: {val_acc1:.4f}, " + + f"Validation Acc@5: {val_acc5:.4f}, " + + f"time: {val_time:.2f}") + # model save + if local_rank == 0: + if epoch % config.SAVE_FREQ == 0 or epoch == config.TRAIN.NUM_EPOCHS: + model_path = os.path.join( + config.SAVE, f"{config.MODEL.TYPE}-Epoch-{epoch}-Loss-{train_loss}") + paddle.save(model.state_dict(), model_path + '.pdparams') + paddle.save(optimizer.state_dict(), model_path + '.pdopt') + logger.info(f"----- Save model: {model_path}.pdparams") + logger.info(f"----- Save optim: {model_path}.pdopt") + + +def main(): + dataset_train = get_dataset(config, mode='train') + dataset_val = get_dataset(config, mode='val') + config.NGPUS = len(paddle.static.cuda_places()) if config.NGPUS == -1 else config.NGPUS + dist.spawn(main_worker, args=(dataset_train, dataset_val, ), nprocs=config.NGPUS, ips=arguments.ips) + + +if __name__ == "__main__": + main() diff --git a/image_classification/Multi_Node_Training/run_train_multi_node.sh b/image_classification/Multi_Node_Training/run_train_multi_node.sh new file mode 100644 index 00000000..bc3893be --- /dev/null +++ b/image_classification/Multi_Node_Training/run_train_multi_node.sh @@ -0,0 +1,8 @@ +CUDA_VISIBLE_DEVICES=0,1 \ +python main_multi_node.py \ +-cfg='./configs/vit_base_patch16_224.yaml' \ +-dataset='imagenet2012' \ +-batch_size=32 \ +-data_path='./dataset/imagenet' \ +-ips='172.18.0.2, 172.18.0.3' # the ips should be replaced +#-amp diff --git a/image_classification/Multi_Node_Training/transformer.py b/image_classification/Multi_Node_Training/transformer.py new file mode 100644 index 00000000..384cacf5 --- /dev/null +++ b/image_classification/Multi_Node_Training/transformer.py @@ -0,0 +1,437 @@ +# Copyright (c) 2021 PPViT Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Implement Transformer Class for ViT +""" + +import copy +import paddle +import paddle.nn as nn +from droppath import DropPath +from config import get_config + + +class Identity(nn.Layer): + """ Identity layer + The output of this layer is the input without any change. + Use this layer to avoid using 'if' condition in forward methods + """ + def __init__(self): + super(Identity, self).__init__() + + def forward(self, x): + return x + + +class PatchEmbedding(nn.Layer): + """Patch Embedding and Position Embedding + + Apply patch embedding and position embedding on input images. + + Attributes: + patch_embddings: impl using a patch_size x patch_size Conv2D operation + position_embddings: a parameter with len = num_patch + 1(for cls_token) + cls_token: token insert to the patch feature for classification + dropout: dropout for embeddings + """ + + def __init__(self, + image_size=224, + patch_size=16, + in_channels=3, + embed_dim=768, + dropout=0.): + super().__init__() + n_patches = (image_size // patch_size) * (image_size // patch_size) + + self.patch_embedding = nn.Conv2D(in_channels=in_channels, + out_channels=embed_dim, + kernel_size=patch_size, + stride=patch_size) + + self.position_embeddings = paddle.create_parameter( + shape=[1, n_patches+1, embed_dim], + dtype='float32', + default_initializer=paddle.nn.initializer.TruncatedNormal(std=.02)) + + self.cls_token = paddle.create_parameter( + shape=[1, 1, embed_dim], + dtype='float32', + default_initializer=paddle.nn.initializer.Constant(0)) + + self.dropout = nn.Dropout(dropout) + + def forward(self, x): + cls_tokens = self.cls_token.expand((x.shape[0], -1, -1)) + x = self.patch_embedding(x) + x = x.flatten(2) + x = x.transpose([0, 2, 1]) + x = paddle.concat((cls_tokens, x), axis=1) + + embeddings = x + self.position_embeddings # tensor broadcast + embeddings = self.dropout(embeddings) + return embeddings + + +class Attention(nn.Layer): + """ Attention module + + Attention module for ViT, here q, k, v are assumed the same. + The qkv mappings are stored as one single param. + + Attributes: + num_heads: number of heads + attn_head_size: feature dim of single head + all_head_size: feature dim of all heads + qkv: a nn.Linear for q, k, v mapping + scales: 1 / sqrt(single_head_feature_dim) + out: projection of multi-head attention + attn_dropout: dropout for attention + proj_dropout: final dropout before output + softmax: softmax op for attention + """ + def __init__(self, + embed_dim, + num_heads, + qkv_bias=True, + dropout=0., + attention_dropout=0.): + super().__init__() + self.num_heads = num_heads + self.attn_head_size = int(embed_dim / self.num_heads) + self.all_head_size = self.attn_head_size * self.num_heads + + w_attr_1, b_attr_1 = self._init_weights() + self.qkv = nn.Linear(embed_dim, + self.all_head_size*3, #weights for q, k, and v + weight_attr=w_attr_1, + bias_attr=b_attr_1 if qkv_bias else False) + + self.scales = self.attn_head_size ** -0.5 + + w_attr_2, b_attr_2 = self._init_weights() + self.out = nn.Linear(embed_dim, + embed_dim, + weight_attr=w_attr_2, + bias_attr=b_attr_2) + + self.attn_dropout = nn.Dropout(attention_dropout) + self.proj_dropout = nn.Dropout(dropout) + self.softmax = nn.Softmax(axis=-1) + + def _init_weights(self): + weight_attr = paddle.ParamAttr(initializer=nn.initializer.KaimingUniform()) + bias_attr = paddle.ParamAttr(initializer=nn.initializer.KaimingUniform()) + return weight_attr, bias_attr + + def transpose_multihead(self, x): + new_shape = x.shape[:-1] + [self.num_heads, self.attn_head_size] + x = x.reshape(new_shape) + x = x.transpose([0, 2, 1, 3]) + return x + + def forward(self, x): + qkv = self.qkv(x).chunk(3, axis=-1) + q, k, v = map(self.transpose_multihead, qkv) + + attn = paddle.matmul(q, k, transpose_y=True) + attn = attn * self.scales + attn = self.softmax(attn) + attn_weights = attn + attn = self.attn_dropout(attn) + + z = paddle.matmul(attn, v) + z = z.transpose([0, 2, 1, 3]) + new_shape = z.shape[:-2] + [self.all_head_size] + z = z.reshape(new_shape) + # reshape + z = self.out(z) + z = self.proj_dropout(z) + return z, attn_weights + + +class Mlp(nn.Layer): + """ MLP module + + Impl using nn.Linear and activation is GELU, dropout is applied. + Ops: fc -> act -> dropout -> fc -> dropout + + Attributes: + fc1: nn.Linear + fc2: nn.Linear + act: GELU + dropout1: dropout after fc1 + dropout2: dropout after fc2 + """ + def __init__(self, + embed_dim, + mlp_ratio, + dropout=0.): + super().__init__() + w_attr_1, b_attr_1 = self._init_weights() + self.fc1 = nn.Linear(embed_dim, + int(embed_dim * mlp_ratio), + weight_attr=w_attr_1, + bias_attr=b_attr_1) + + w_attr_2, b_attr_2 = self._init_weights() + self.fc2 = nn.Linear(int(embed_dim * mlp_ratio), + embed_dim, + weight_attr=w_attr_2, + bias_attr=b_attr_2) + self.act = nn.GELU() + self.dropout1 = nn.Dropout(dropout) + self.dropout2 = nn.Dropout(dropout) + + def _init_weights(self): + weight_attr = paddle.ParamAttr( + initializer=paddle.nn.initializer.XavierUniform()) #default in pp: xavier + bias_attr = paddle.ParamAttr( + initializer=paddle.nn.initializer.Normal(std=1e-6)) #default in pp: zero + return weight_attr, bias_attr + + def forward(self, x): + x = self.fc1(x) + x = self.act(x) + x = self.dropout1(x) + x = self.fc2(x) + x = self.dropout2(x) + return x + + +class EncoderLayer(nn.Layer): + """Encoder Layer + + Encoder layer contains attention, norm, mlp and residual + + Attributes: + hidden_size: transformer feature dim + attn_norm: nn.LayerNorm before attention + mlp_norm: nn.LayerNorm before mlp + mlp: mlp modual + attn: attention modual + """ + def __init__(self, + embed_dim, + num_heads, + qkv_bias=True, + mlp_ratio=4., + dropout=0., + attention_dropout=0., + droppath=0.): + super().__init__() + w_attr_1, b_attr_1 = self._init_weights() + self.attn_norm = nn.LayerNorm(embed_dim, + weight_attr=w_attr_1, + bias_attr=b_attr_1, + epsilon=1e-6) + + self.attn = Attention(embed_dim, + num_heads, + qkv_bias, + dropout, + attention_dropout) + self.drop_path = DropPath(droppath) if droppath > 0. else Identity() + + w_attr_2, b_attr_2 = self._init_weights() + self.mlp_norm = nn.LayerNorm(embed_dim, + weight_attr=w_attr_2, + bias_attr=b_attr_2, + epsilon=1e-6) + + self.mlp = Mlp(embed_dim, mlp_ratio, dropout) + + def _init_weights(self): + weight_attr = paddle.ParamAttr(initializer=nn.initializer.Constant(0.0)) + bias_attr = paddle.ParamAttr(initializer=nn.initializer.Constant(1.0)) + return weight_attr, bias_attr + + def forward(self, x): + h = x + x = self.attn_norm(x) + x, attn = self.attn(x) + x = self.drop_path(x) + x = x + h + + h = x + x = self.mlp_norm(x) + x = self.mlp(x) + x = self.drop_path(x) + x = x + h + + return x, attn + + +class Encoder(nn.Layer): + """Transformer encoder + + Encoder encoder contains a list of EncoderLayer, and a LayerNorm. + + Attributes: + layers: nn.LayerList contains multiple EncoderLayers + encoder_norm: nn.LayerNorm which is applied after last encoder layer + """ + def __init__(self, + embed_dim, + num_heads, + depth, + qkv_bias=True, + mlp_ratio=4.0, + dropout=0., + attention_dropout=0., + droppath=0.): + super(Encoder, self).__init__() + # stochatic depth decay + depth_decay = [x.item() for x in paddle.linspace(0, droppath, depth)] + layer_list = [] + for i in range(depth): + encoder_layer = EncoderLayer(embed_dim, + num_heads, + qkv_bias=True, + mlp_ratio=4., + dropout=0., + attention_dropout=0., + droppath=depth_decay[i]) + layer_list.append(copy.deepcopy(encoder_layer)) + self.layers = nn.LayerList(layer_list) + + w_attr_1, b_attr_1 = self._init_weights() + self.encoder_norm = nn.LayerNorm(embed_dim, + weight_attr=w_attr_1, + bias_attr=b_attr_1, + epsilon=1e-6) + + def _init_weights(self): + weight_attr = paddle.ParamAttr(initializer=nn.initializer.Constant(0.0)) + bias_attr = paddle.ParamAttr(initializer=nn.initializer.Constant(1.0)) + return weight_attr, bias_attr + + def forward(self, x): + self_attn = [] + for layer in self.layers: + x, attn = layer(x) + self_attn.append(attn) + out = self.encoder_norm(x) + return out, self_attn + + +class VisualTransformer(nn.Layer): + """ViT transformer + + ViT Transformer, classifier is a single Linear layer for finetune, + For training from scratch, two layer mlp should be used. + Classification is done using cls_token. + + Args: + image_size: int, input image size, default: 224 + patch_size: int, patch size, default: 16 + in_channels: int, input image channels, default: 3 + num_classes: int, number of classes for classification, default: 1000 + embed_dim: int, embedding dimension (patch embed out dim), default: 768 + depth: int, number ot transformer blocks, default: 12 + num_heads: int, number of attention heads, default: 12 + mlp_ratio: float, ratio of mlp hidden dim to embed dim(mlp in dim), default: 4.0 + qkv_bias: bool, If True, enable qkv(nn.Linear) layer with bias, default: True + dropout: float, dropout rate for linear layers, default: 0. + attention_dropout: float, dropout rate for attention layers default: 0. + droppath: float, droppath rate for droppath layers, default: 0. + """ + def __init__(self, + image_size=224, + patch_size=16, + in_channels=3, + num_classes=1000, + embed_dim=768, + depth=12, + num_heads=12, + mlp_ratio=4, + qkv_bias=True, + dropout=0., + attention_dropout=0., + droppath=0., + train_from_scratch=False, + config=None): + super(VisualTransformer, self).__init__() + # create patch embedding with positional embedding + self.patch_embedding = PatchEmbedding(image_size, + patch_size, + in_channels, + embed_dim, + dropout) + # create multi head self-attention layers + self.encoder = Encoder(embed_dim, + num_heads, + depth, + qkv_bias, + mlp_ratio, + dropout, + attention_dropout, + droppath) + + # classifier head (for training from scracth) + if train_from_scratch: + w_attr_1, b_attr_1 = self._init_weights() + w_attr_2, b_attr_2 = self._init_weights() + self.classifier = nn.Sequential( + nn.Linear(config.MODEL.TRANS.HIDDEN_SIZE, + config.MODEL.TRANS.HIDDEN_SIZE, + weight_attr=w_attr_1, + bias_attr=b_attr_1), + nn.ReLU(), + nn.Dropout(config.MODEL.DROPOUT), + nn.Linear(config.MODEL.TRANS.HIDDEN_SIZE, + config.MODEL.NUM_CLASSES, + weight_attr=w_attr_2, + bias_attr=b_attr_2), + nn.Dropout(config.MODEL.DROPOUT), + ) + else: + # classifier head (for finetuning) + w_attr_1, b_attr_1 = self._init_weights() + self.classifier = nn.Linear(embed_dim, + num_classes, + weight_attr=w_attr_1, + bias_attr=b_attr_1) + + def _init_weights(self): + weight_attr = paddle.ParamAttr( + initializer=paddle.nn.initializer.KaimingUniform()) + bias_attr = paddle.ParamAttr( + initializer=paddle.nn.initializer.KaimingUniform()) + return weight_attr, bias_attr + + def forward(self, x): + x = self.patch_embedding(x) + x, attn = self.encoder(x) + logits = self.classifier(x[:, 0]) # take only cls_token as classifier + return logits + + +def build_vit(config): + model = VisualTransformer(image_size=config.DATA.IMAGE_SIZE, + patch_size=config.MODEL.TRANS.PATCH_SIZE, + in_channels=3, + num_classes=config.MODEL.NUM_CLASSES, + embed_dim=config.MODEL.TRANS.EMBED_DIM, + depth=config.MODEL.TRANS.DEPTH, + num_heads=config.MODEL.TRANS.NUM_HEADS, + mlp_ratio=config.MODEL.TRANS.MLP_RATIO, + qkv_bias=config.MODEL.TRANS.QKV_BIAS, + dropout=config.MODEL.DROPOUT, + attention_dropout=config.MODEL.ATTENTION_DROPOUT, + droppath=config.MODEL.DROPPATH, + train_from_scratch=False, + config=config) + return model diff --git a/image_classification/Multi_Node_Training/utils.py b/image_classification/Multi_Node_Training/utils.py new file mode 100644 index 00000000..44800527 --- /dev/null +++ b/image_classification/Multi_Node_Training/utils.py @@ -0,0 +1,120 @@ +# Copyright (c) 2021 PPViT Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""utils for ViT + +Contains AverageMeter for monitoring, get_exclude_from_decay_fn for training +and WarmupCosineScheduler for training + +""" + +import math +from paddle.optimizer.lr import LRScheduler + + +class AverageMeter(): + """ Meter for monitoring losses""" + def __init__(self): + self.avg = 0 + self.sum = 0 + self.cnt = 0 + self.reset() + + def reset(self): + """reset all values to zeros""" + self.avg = 0 + self.sum = 0 + self.cnt = 0 + + def update(self, val, n=1): + """update avg by val and n, where val is the avg of n values""" + self.sum += val * n + self.cnt += n + self.avg = self.sum / self.cnt + + + +def get_exclude_from_weight_decay_fn(exclude_list=[]): + """ Set params with no weight decay during the training + + For certain params, e.g., positional encoding in ViT, weight decay + may not needed during the learning, this method is used to find + these params. + + Args: + exclude_list: a list of params names which need to exclude + from weight decay. + Returns: + exclude_from_weight_decay_fn: a function returns True if param + will be excluded from weight decay + """ + if len(exclude_list) == 0: + exclude_from_weight_decay_fn = None + else: + def exclude_fn(param): + for name in exclude_list: + if param.endswith(name): + return False + return True + exclude_from_weight_decay_fn = exclude_fn + return exclude_from_weight_decay_fn + + +class WarmupCosineScheduler(LRScheduler): + """Warmup Cosine Scheduler + + First apply linear warmup, then apply cosine decay schedule. + Linearly increase learning rate from "warmup_start_lr" to "start_lr" over "warmup_epochs" + Cosinely decrease learning rate from "start_lr" to "end_lr" over remaining + "total_epochs - warmup_epochs" + + Attributes: + learning_rate: the starting learning rate (without warmup), not used here! + warmup_start_lr: warmup starting learning rate + start_lr: the starting learning rate (without warmup) + end_lr: the ending learning rate after whole loop + warmup_epochs: # of epochs for warmup + total_epochs: # of total epochs (include warmup) + """ + def __init__(self, + learning_rate, + warmup_start_lr, + start_lr, + end_lr, + warmup_epochs, + total_epochs, + cycles=0.5, + last_epoch=-1, + verbose=False): + """init WarmupCosineScheduler """ + self.warmup_epochs = warmup_epochs + self.total_epochs = total_epochs + self.warmup_start_lr = warmup_start_lr + self.start_lr = start_lr + self.end_lr = end_lr + self.cycles = cycles + super(WarmupCosineScheduler, self).__init__(learning_rate, last_epoch, verbose) + + def get_lr(self): + """ return lr value """ + if self.last_epoch < self.warmup_epochs: + val = (self.start_lr - self.warmup_start_lr) * float( + self.last_epoch)/float(self.warmup_epochs) + self.warmup_start_lr + return val + + progress = float(self.last_epoch - self.warmup_epochs) / float( + max(1, self.total_epochs - self.warmup_epochs)) + val = max(0.0, 0.5 * (1. + math.cos(math.pi * float(self.cycles) * 2.0 * progress))) + val = max(0.0, val * (self.start_lr - self.end_lr) + self.end_lr) + return val From caf5f7dd3eb1fb8111974948b00f3b6eddca25c2 Mon Sep 17 00:00:00 2001 From: skpig <479469418@qq.com> Date: Thu, 9 Dec 2021 23:26:08 +0800 Subject: [PATCH 4/5] Add README --- .../Multi_Node_Training/README.md | 56 ++++++++++++++++++ .../Multi_Node_Training/README_cn.md | 45 ++++++++++++++ image_classification/ViT/vit.png | Bin 119352 -> 0 bytes 3 files changed, 101 insertions(+) create mode 100644 image_classification/Multi_Node_Training/README_cn.md delete mode 100644 image_classification/ViT/vit.png diff --git a/image_classification/Multi_Node_Training/README.md b/image_classification/Multi_Node_Training/README.md index 839e3dfa..61e17b1c 100644 --- a/image_classification/Multi_Node_Training/README.md +++ b/image_classification/Multi_Node_Training/README.md @@ -1 +1,57 @@ # Multiple Node Training +English | [简体中文](./README_cn.md) + +PaddleVit also supports multi-node distributed training under collective mode. + +Here we provides a simple tutorial to modify multi-gpus training scripts +to multi-nodes training scripts for any models in PaddleViT. + +This folder takes ViT model as an example. + +## Tutorial +For any models in PaddleViT, one can implement multi-node training by modifying +`main_multi_gpu.py`. +1. Just add arguments `ips='[host ips]' ` in `dist.spawn()`. +2. Then run training script in every host. + +## Training example: ViT +Suppose you have 2 hosts (denoted as node) with 4 gpus on each machine. +Nodes IP addresses are `192.168.0.16` and `192.168.0.17`. + +1. Then modify some lines of `run_train_multi_node.sh`: + ```shell + CUDA_VISIBLE_DEVICES=0,1,2,3 # number of gpus + + -ips= '192.168.0.16, 192.168.0.17' # seperated by comma + ``` +2. Run training script in every host: + ```shell + sh run_train_multi.sh + ``` + +##Multi-nodes training with one host +It is possible to try multi-node training even when you have only one machine. + +1. Install docker and paddle. For more details, please refer + [here](https://www.paddlepaddle.org.cn/documentation/docs/zh/install/docker/fromdocker.html). + +2. Create a network between docker containers. + ```shell + docker network create -d bridge paddle_net + ``` +3. Create multiple containers as virtual hosts/nodes. Suppose creating 2 containers +with 2 gpus on each node. + ```shell + docker run --name paddle0 -it -d --gpus "device=0,1" --network paddle_net\ + paddlepaddle/paddle:2.2.0-gpu-cuda10.2-cudnn7 /bin/bash + docker run --name paddle1 -it -d --gpus "device=2,3" --network paddle_net\ + paddlepaddle/paddle:2.2.0-gpu-cuda10.2-cudnn7 /bin/bash + ``` + > Noted: + > 1. One can assign one gpu device to different containers. But it may occur OOM since multiple models will run on the same gpu. + > 2. One should use `-v` to bind PaddleViT repository to container. + +4. Modify `run_train_multi_node.sh` as described above and run the training script on every container. + + > Noted: One can use `ping` or `ip -a` bash command to check containers' ip addresses. + diff --git a/image_classification/Multi_Node_Training/README_cn.md b/image_classification/Multi_Node_Training/README_cn.md new file mode 100644 index 00000000..c879d46f --- /dev/null +++ b/image_classification/Multi_Node_Training/README_cn.md @@ -0,0 +1,45 @@ +#多机多卡分布式训练 + +简体中文 | [English](./README.md) + +PaddleViT 同样支持Collective多机多卡分布式训练。 + +##教程 +对于每一个模型,用户可以直接通过修改对应模型文件夹下的`main_multi_gpu.py` +以进行多机训练。 +1. 在`dist.spawn()`里加入`ips='[host ips]' `。 +2. 在每个主机上运行代码。 + +##样例:ViT +这个文件夹提供了分布式训练ViT模型的代码和shell脚本。 +假设你有2台主机,每个主机上有4张显卡。主机的ip地址为`192.168.0.16`和`192.168.0.17`。 + +1. 修改shell脚本`run_train_multi_node.sh`的参数 + ```shell + CUDA_VISIBLE_DEVICES=0,1,2,3 # number of gpus + + -ips= '192.168.0.16, 192.168.0.17' # seperated by comma + ``` +2. 在每个主机上运行脚本代码。 + ```shell + sh run_train_multi.sh + ``` +##单机上运行分布式训练 +如果仅有一台主机,同样可以通过docker实现单机上的分布式训练。 +1. 安装docker和paddle。[这里](https://www.paddlepaddle.org.cn/documentation/docs/zh/install/docker/fromdocker.html) +可以下载paddlepaddle提供的docker镜像。 +2. 创建docker容器间网络。 + ```shell + docker network create -d bridge paddle_net + ``` +3. 创建多个docker容器作为虚拟主机,假设我们创建2个容器,并分别分配2个GPU。 + ```shell + docker run --name paddle0 -it -d --gpus "device=0,1" --network paddle_net\ + paddlepaddle/paddle:2.2.0-gpu-cuda10.2-cudnn7 /bin/bash + docker run --name paddle1 -it -d --gpus "device=2,3" --network paddle_net\ + paddlepaddle/paddle:2.2.0-gpu-cuda10.2-cudnn7 /bin/bash + ``` + > 注意: + > 1. 可以将同一个GPU同时分配给多个容器,但是这可能会产生OOM错误,因为多个模型将同时运行在这个GPU上。 + > 2. 使用`-v`挂载PaddleViT所在的目录。 + diff --git a/image_classification/ViT/vit.png b/image_classification/ViT/vit.png deleted file mode 100644 index a6929f74047cd663b33b407d1dd47fe706d27022..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 119352 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�TK6u4?aEFBDM;FMP#S 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 Date: Thu, 9 Dec 2021 23:30:51 +0800 Subject: [PATCH 5/5] add back files in CycleMLP --- image_classification/CycleMLP/README.md | 53 +- .../CycleMLP/main_multi_node.py | 575 ------------------ .../CycleMLP/run_train_multi_node.sh | 8 - image_classification/ViT/vit.png | Bin 0 -> 119352 bytes 4 files changed, 4 insertions(+), 632 deletions(-) delete mode 100644 image_classification/CycleMLP/main_multi_node.py delete mode 100644 image_classification/CycleMLP/run_train_multi_node.sh create mode 100644 image_classification/ViT/vit.png diff --git a/image_classification/CycleMLP/README.md b/image_classification/CycleMLP/README.md index 0c1df47c..ac65489d 100644 --- a/image_classification/CycleMLP/README.md +++ b/image_classification/CycleMLP/README.md @@ -126,7 +126,6 @@ python main_multi_gpu.py \ ## Training -### Training with single GPU To train the CycleMLP model on ImageNet2012 with single GPUs, run the following script using command line: ```shell sh run_train.sh @@ -141,9 +140,11 @@ python main_single_gpu.py \ -data_path='/dataset/imagenet' \ ``` -### Training with multi-GPU -Run training using multi-GPUs: +
+ +Run training using multi-GPUs: + ```shell @@ -159,55 +160,9 @@ python main_multi_gpu.py \ -data_path='/dataset/imagenet' \ ``` - - -### Training with multi-node -PaddleVit also supports multi-node distributed training under collective mode. - -Suppose you have 2 hosts (denoted as node) with 4 gpus on each machine. -Nodes IP addresses are `192.168.0.16` and `192.168.0.17`. - -Then some lines of `run_train_multi_node.sh` should be modified: -```shell -CUDA_VISIBLE_DEVICES=0,1,2,3 # number of gpus - --ips= '192.168.0.16, 192.168.0.17' # seperated by comma -``` -Run training script in every node: -```shell -sh run_train_multi.sh -``` - -
-It is possible to train with multi-node even when you have only one machine - -1. Install docker and paddle. For more details, please refer to - [here](https://www.paddlepaddle.org.cn/documentation/docs/zh/install/docker/fromdocker.html). - -2. Create a network between docker containers. - ```shell - docker network create -d bridge paddle_net - ``` -3. Create multiple containers as virtual hosts/nodes. Suppose creating 2 containers -with 2 gpus on each node. - ```shell - docker run --name paddle0 -it -d --gpus "device=0,1" --network paddle_net\ - paddlepaddle/paddle:2.2.0-gpu-cuda10.2-cudnn7 /bin/bash - docker run --name paddle1 -it -d --gpus "device=2,3" --network paddle_net\ - paddlepaddle/paddle:2.2.0-gpu-cuda10.2-cudnn7 /bin/bash - ``` - > Noted: - > 1. One can assign same gpu device to different containers. But it may occur OOM since multiple models will run on the same gpu. - > 2. One should use `-v` to bind PaddleViT repository to container. - -4. Modify `run_train_multi_node.sh` as described above and run the training script on every container. - - > Noted: One can use `ping` or `ip -a` bash command to check containers' ip addresses. -
- ## Visualization Attention Map **(coming soon)** diff --git a/image_classification/CycleMLP/main_multi_node.py b/image_classification/CycleMLP/main_multi_node.py deleted file mode 100644 index 5e2d3482..00000000 --- a/image_classification/CycleMLP/main_multi_node.py +++ /dev/null @@ -1,575 +0,0 @@ -# Copyright (c) 2021 PPViT Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""CycleMLP training/validation using multiple GPU """ - -import sys -import os -import time -import logging -import argparse -import random -import numpy as np -import paddle -import paddle.nn as nn -import paddle.nn.functional as F -import paddle.distributed as dist -from datasets import get_dataloader -from datasets import get_dataset -from utils import AverageMeter -from utils import WarmupCosineScheduler -from utils import get_exclude_from_weight_decay_fn -from config import get_config -from config import update_config -from mixup import Mixup -from losses import LabelSmoothingCrossEntropyLoss -from losses import SoftTargetCrossEntropyLoss -from losses import DistillationLoss -from cyclemlp import build_cyclemlp as build_model - - -def get_arguments(): - """return argumeents, this will overwrite the config after loading yaml file""" - parser = argparse.ArgumentParser('Swin') - parser.add_argument('-cfg', type=str, default=None) - parser.add_argument('-dataset', type=str, default=None) - parser.add_argument('-batch_size', type=int, default=None) - parser.add_argument('-image_size', type=int, default=None) - parser.add_argument('-data_path', type=str, default=None) - parser.add_argument('-ngpus', type=int, default=None) - parser.add_argument('-pretrained', type=str, default=None) - parser.add_argument('-resume', type=str, default=None) - parser.add_argument('-last_epoch', type=int, default=None) - parser.add_argument('-eval', action='store_true') - parser.add_argument('-amp', action='store_true') - parser.add_argument('-ips', type=str, default="127.0.0.1") - arguments = parser.parse_args() - return arguments - - -def get_logger(filename, logger_name=None): - """set logging file and format - Args: - filename: str, full path of the logger file to write - logger_name: str, the logger name, e.g., 'master_logger', 'local_logger' - Return: - logger: python logger - """ - log_format = "%(asctime)s %(message)s" - logging.basicConfig(stream=sys.stdout, level=logging.INFO, - format=log_format, datefmt="%m%d %I:%M:%S %p") - # different name is needed when creating multiple logger in one process - logger = logging.getLogger(logger_name) - fh = logging.FileHandler(os.path.join(filename)) - fh.setFormatter(logging.Formatter(log_format)) - logger.addHandler(fh) - return logger - - -def train(dataloader, - model, - criterion, - optimizer, - epoch, - total_epochs, - total_batch, - debug_steps=100, - accum_iter=1, - mixup_fn=None, - amp=False, - local_logger=None, - master_logger=None): - """Training for one epoch - Args: - dataloader: paddle.io.DataLoader, dataloader instance - model: nn.Layer, a ViT model - criterion: nn.criterion - epoch: int, current epoch - total_epochs: int, total num of epochs - total_batch: int, total num of batches for one epoch - debug_steps: int, num of iters to log info, default: 100 - accum_iter: int, num of iters for accumulating gradients, default: 1 - mixup_fn: Mixup, mixup instance, default: None - amp: bool, if True, use mix precision training, default: False - local_logger: logger for local process/gpu, default: None - master_logger: logger for main process, default: None - Returns: - train_loss_meter.avg: float, average loss on current process/gpu - train_acc_meter.avg: float, average top1 accuracy on current process/gpu - master_train_loss_meter.avg: float, average loss on all processes/gpus - master_train_acc_meter.avg: float, average top1 accuracy on all processes/gpus - train_time: float, training time - """ - model.train() - train_loss_meter = AverageMeter() - train_acc_meter = AverageMeter() - master_train_loss_meter = AverageMeter() - master_train_acc_meter = AverageMeter() - - if amp is True: - scaler = paddle.amp.GradScaler(init_loss_scaling=1024) - time_st = time.time() - - for batch_id, data in enumerate(dataloader): - image = data[0] - label = data[1] - label_orig = label.clone() - - if mixup_fn is not None: - image, label = mixup_fn(image, label_orig) - - if amp is True: # mixed precision training - with paddle.amp.auto_cast(): - output = model(image) - loss = criterion(image, output, label) - scaled = scaler.scale(loss) - scaled.backward() - if ((batch_id +1) % accum_iter == 0) or (batch_id + 1 == len(dataloader)): - scaler.minimize(optimizer, scaled) - optimizer.clear_grad() - else: # full precision training - output = model(image) - loss = criterion(output, label) - #NOTE: division may be needed depending on the loss function - # Here no division is needed: - # default 'reduction' param in nn.CrossEntropyLoss is set to 'mean' - #loss = loss / accum_iter - loss.backward() - - if ((batch_id +1) % accum_iter == 0) or (batch_id + 1 == len(dataloader)): - optimizer.step() - optimizer.clear_grad() - - pred = F.softmax(output) - if mixup_fn: - acc = paddle.metric.accuracy(pred, label_orig) - else: - acc = paddle.metric.accuracy(pred, label_orig.unsqueeze(1)) - - batch_size = paddle.to_tensor(image.shape[0]) - - # sync from other gpus for overall loss and acc - master_loss = loss.clone() - master_acc = acc.clone() - master_batch_size = batch_size.clone() - dist.all_reduce(master_loss) - dist.all_reduce(master_acc) - dist.all_reduce(master_batch_size) - master_loss = master_loss / dist.get_world_size() - master_acc = master_acc / dist.get_world_size() - master_train_loss_meter.update(master_loss.numpy()[0], master_batch_size.numpy()[0]) - master_train_acc_meter.update(master_acc.numpy()[0], master_batch_size.numpy()[0]) - - train_loss_meter.update(loss.numpy()[0], batch_size.numpy()[0]) - train_acc_meter.update(acc.numpy()[0], batch_size.numpy()[0]) - - if batch_id % debug_steps == 0: - if local_logger: - local_logger.info( - f"Epoch[{epoch:03d}/{total_epochs:03d}], " + - f"Step[{batch_id:04d}/{total_batch:04d}], " + - f"Avg Loss: {train_loss_meter.avg:.4f}, " + - f"Avg Acc: {train_acc_meter.avg:.4f}") - if master_logger and dist.get_rank() == 0: - master_logger.info( - f"Epoch[{epoch:03d}/{total_epochs:03d}], " + - f"Step[{batch_id:04d}/{total_batch:04d}], " + - f"Avg Loss: {master_train_loss_meter.avg:.4f}, " + - f"Avg Acc: {master_train_acc_meter.avg:.4f}") - - train_time = time.time() - time_st - return (train_loss_meter.avg, - train_acc_meter.avg, - master_train_loss_meter.avg, - master_train_acc_meter.avg, - train_time) - - -def validate(dataloader, - model, - criterion, - total_batch, - debug_steps=100, - local_logger=None, - master_logger=None): - """Validation for whole dataset - Args: - dataloader: paddle.io.DataLoader, dataloader instance - model: nn.Layer, a ViT model - criterion: nn.criterion - total_epoch: int, total num of epoch, for logging - debug_steps: int, num of iters to log info, default: 100 - local_logger: logger for local process/gpu, default: None - master_logger: logger for main process, default: None - Returns: - val_loss_meter.avg: float, average loss on current process/gpu - val_acc1_meter.avg: float, average top1 accuracy on current process/gpu - val_acc5_meter.avg: float, average top5 accuracy on current process/gpu - master_val_loss_meter.avg: float, average loss on all processes/gpus - master_val_acc1_meter.avg: float, average top1 accuracy on all processes/gpus - master_val_acc5_meter.avg: float, average top5 accuracy on all processes/gpus - val_time: float, validation time - """ - model.eval() - val_loss_meter = AverageMeter() - val_acc1_meter = AverageMeter() - val_acc5_meter = AverageMeter() - master_val_loss_meter = AverageMeter() - master_val_acc1_meter = AverageMeter() - master_val_acc5_meter = AverageMeter() - time_st = time.time() - - with paddle.no_grad(): - for batch_id, data in enumerate(dataloader): - image = data[0] - label = data[1] - - output = model(image) - loss = criterion(output, label) - - pred = F.softmax(output) - acc1 = paddle.metric.accuracy(pred, label.unsqueeze(1)) - acc5 = paddle.metric.accuracy(pred, label.unsqueeze(1), k=5) - - batch_size = paddle.to_tensor(image.shape[0]) - - master_loss = loss.clone() - master_acc1 = acc1.clone() - master_acc5 = acc5.clone() - master_batch_size = batch_size.clone() - - dist.all_reduce(master_loss) - dist.all_reduce(master_acc1) - dist.all_reduce(master_acc5) - dist.all_reduce(master_batch_size) - master_loss = master_loss / dist.get_world_size() - master_acc1 = master_acc1 / dist.get_world_size() - master_acc5 = master_acc5 / dist.get_world_size() - - master_val_loss_meter.update(master_loss.numpy()[0], master_batch_size.numpy()[0]) - master_val_acc1_meter.update(master_acc1.numpy()[0], master_batch_size.numpy()[0]) - master_val_acc5_meter.update(master_acc5.numpy()[0], master_batch_size.numpy()[0]) - - val_loss_meter.update(loss.numpy()[0], batch_size.numpy()[0]) - val_acc1_meter.update(acc1.numpy()[0], batch_size.numpy()[0]) - val_acc5_meter.update(acc5.numpy()[0], batch_size.numpy()[0]) - - if batch_id % debug_steps == 0: - if local_logger: - local_logger.info( - f"Val Step[{batch_id:04d}/{total_batch:04d}], " + - f"Avg Loss: {val_loss_meter.avg:.4f}, " + - f"Avg Acc@1: {val_acc1_meter.avg:.4f}, " + - f"Avg Acc@5: {val_acc5_meter.avg:.4f}") - if master_logger and dist.get_rank() == 0: - master_logger.info( - f"Val Step[{batch_id:04d}/{total_batch:04d}], " + - f"Avg Loss: {master_val_loss_meter.avg:.4f}, " + - f"Avg Acc@1: {master_val_acc1_meter.avg:.4f}, " + - f"Avg Acc@5: {master_val_acc5_meter.avg:.4f}") - val_time = time.time() - time_st - return (val_loss_meter.avg, - val_acc1_meter.avg, - val_acc5_meter.avg, - master_val_loss_meter.avg, - master_val_acc1_meter.avg, - master_val_acc5_meter.avg, - val_time) - - -def main_worker(*args): - # STEP 0: Preparation - config = args[0] - dist.init_parallel_env() - last_epoch = config.TRAIN.LAST_EPOCH - world_size = dist.get_world_size() - local_rank = dist.get_rank() - seed = config.SEED + local_rank - paddle.seed(seed) - np.random.seed(seed) - random.seed(seed) - # logger for each process/gpu - local_logger = get_logger( - filename=os.path.join(config.SAVE, 'log_{}.txt'.format(local_rank)), - logger_name='local_logger') - # overall logger - if local_rank == 0: - master_logger = get_logger( - filename=os.path.join(config.SAVE, 'log.txt'), - logger_name='master_logger') - master_logger.info(f'\n{config}') - else: - master_logger = None - local_logger.info(f'----- world_size = {world_size}, local_rank = {local_rank}') - if local_rank == 0: - master_logger.info(f'----- world_size = {world_size}, local_rank = {local_rank}') - - # STEP 1: Create model - model = build_model(config) - model = paddle.DataParallel(model) - - # STEP 2: Create train and val dataloader - dataset_train, dataset_val = args[1], args[2] - dataloader_train = get_dataloader(config, dataset_train, 'train', True) - dataloader_val = get_dataloader(config, dataset_val, 'test', True) - total_batch_train = len(dataloader_train) - total_batch_val = len(dataloader_val) - local_logger.info(f'----- Total # of train batch (single gpu): {total_batch_train}') - local_logger.info(f'----- Total # of val batch (single gpu): {total_batch_val}') - if local_rank == 0: - master_logger.info(f'----- Total # of train batch (single gpu): {total_batch_train}') - master_logger.info(f'----- Total # of val batch (single gpu): {total_batch_val}') - - # STEP 3: Define Mixup function - mixup_fn = None - if config.TRAIN.MIXUP_PROB > 0 or config.TRAIN.CUTMIX_ALPHA > 0 or config.TRAIN.CUTMIX_MINMAX is not None: - mixup_fn = Mixup(mixup_alpha=config.TRAIN.MIXUP_ALPHA, - cutmix_alpha=config.TRAIN.CUTMIX_ALPHA, - cutmix_minmax=config.TRAIN.CUTMIX_MINMAX, - prob=config.TRAIN.MIXUP_PROB, - switch_prob=config.TRAIN.MIXUP_SWITCH_PROB, - mode=config.TRAIN.MIXUP_MODE, - label_smoothing=config.TRAIN.SMOOTHING) - - # STEP 4: Define criterion - if config.TRAIN.MIXUP_PROB > 0.: - criterion = SoftTargetCrossEntropyLoss() - elif config.TRAIN.SMOOTHING: - criterion = LabelSmoothingCrossEntropyLoss() - else: - criterion = nn.CrossEntropyLoss() - # only use cross entropy for val - criterion_val = nn.CrossEntropyLoss() - - # STEP 5: Define optimizer and lr_scheduler - # set lr according to batch size and world size (hacked from official code) - linear_scaled_lr = (config.TRAIN.BASE_LR * - config.DATA.BATCH_SIZE * dist.get_world_size()) / 512.0 - linear_scaled_warmup_start_lr = (config.TRAIN.WARMUP_START_LR * - config.DATA.BATCH_SIZE * dist.get_world_size()) / 512.0 - linear_scaled_end_lr = (config.TRAIN.END_LR * - config.DATA.BATCH_SIZE * dist.get_world_size()) / 512.0 - - if config.TRAIN.ACCUM_ITER > 1: - linear_scaled_lr = linear_scaled_lr * config.TRAIN.ACCUM_ITER - linear_scaled_warmup_start_lr = linear_scaled_warmup_start_lr * config.TRAIN.ACCUM_ITER - linear_scaled_end_lr = linear_scaled_end_lr * config.TRAIN.ACCUM_ITER - - config.TRAIN.BASE_LR = linear_scaled_lr - config.TRAIN.WARMUP_START_LR = linear_scaled_warmup_start_lr - config.TRAIN.END_LR = linear_scaled_end_lr - - scheduler = None - if config.TRAIN.LR_SCHEDULER.NAME == "warmupcosine": - scheduler = WarmupCosineScheduler(learning_rate=config.TRAIN.BASE_LR, - warmup_start_lr=config.TRAIN.WARMUP_START_LR, - start_lr=config.TRAIN.BASE_LR, - end_lr=config.TRAIN.END_LR, - warmup_epochs=config.TRAIN.WARMUP_EPOCHS, - total_epochs=config.TRAIN.NUM_EPOCHS, - last_epoch=config.TRAIN.LAST_EPOCH, - ) - elif config.TRAIN.LR_SCHEDULER.NAME == "cosine": - scheduler = paddle.optimizer.lr.CosineAnnealingDecay(learning_rate=config.TRAIN.BASE_LR, - T_max=config.TRAIN.NUM_EPOCHS, - last_epoch=last_epoch) - elif config.scheduler == "multi-step": - milestones = [int(v.strip()) for v in config.TRAIN.LR_SCHEDULER.MILESTONES.split(",")] - scheduler = paddle.optimizer.lr.MultiStepDecay(learning_rate=config.TRAIN.BASE_LR, - milestones=milestones, - gamma=config.TRAIN.LR_SCHEDULER.DECAY_RATE, - last_epoch=last_epoch) - else: - local_logger.fatal(f"Unsupported Scheduler: {config.TRAIN.LR_SCHEDULER}.") - if local_rank == 0: - master_logger.fatal(f"Unsupported Scheduler: {config.TRAIN.LR_SCHEDULER}.") - raise NotImplementedError(f"Unsupported Scheduler: {config.TRAIN.LR_SCHEDULER}.") - - if config.TRAIN.OPTIMIZER.NAME == "SGD": - if config.TRAIN.GRAD_CLIP: - clip = paddle.nn.ClipGradByGlobalNorm(config.TRAIN.GRAD_CLIP) - else: - clip = None - optimizer = paddle.optimizer.Momentum( - parameters=model.parameters(), - learning_rate=scheduler if scheduler is not None else config.TRAIN.BASE_LR, - weight_decay=config.TRAIN.WEIGHT_DECAY, - momentum=config.TRAIN.OPTIMIZER.MOMENTUM, - grad_clip=clip) - elif config.TRAIN.OPTIMIZER.NAME == "AdamW": - if config.TRAIN.GRAD_CLIP: - clip = paddle.nn.ClipGradByGlobalNorm(config.TRAIN.GRAD_CLIP) - else: - clip = None - optimizer = paddle.optimizer.AdamW( - parameters=model.parameters(), - learning_rate=scheduler if scheduler is not None else config.TRAIN.BASE_LR, - beta1=config.TRAIN.OPTIMIZER.BETAS[0], - beta2=config.TRAIN.OPTIMIZER.BETAS[1], - weight_decay=config.TRAIN.WEIGHT_DECAY, - epsilon=config.TRAIN.OPTIMIZER.EPS, - grad_clip=clip, - apply_decay_param_fun=get_exclude_from_weight_decay_fn([ - 'absolute_pos_embed', 'relative_position_bias_table']), - ) - else: - local_logger.fatal(f"Unsupported Optimizer: {config.TRAIN.OPTIMIZER.NAME}.") - if local_rank == 0: - master_logger.fatal(f"Unsupported Optimizer: {config.TRAIN.OPTIMIZER.NAME}.") - raise NotImplementedError(f"Unsupported Optimizer: {config.TRAIN.OPTIMIZER.NAME}.") - - # STEP 6: Load pretrained model / load resumt model and optimizer states - if config.MODEL.PRETRAINED: - if (config.MODEL.PRETRAINED).endswith('.pdparams'): - raise ValueError(f'{config.MODEL.PRETRAINED} should not contain .pdparams') - assert os.path.isfile(config.MODEL.PRETRAINED + '.pdparams') is True - model_state = paddle.load(config.MODEL.PRETRAINED+'.pdparams') - model.set_dict(model_state) - local_logger.info(f"----- Pretrained: Load model state from {config.MODEL.PRETRAINED}") - if local_rank == 0: - master_logger.info( - f"----- Pretrained: Load model state from {config.MODEL.PRETRAINED}") - - if config.MODEL.RESUME: - assert os.path.isfile(config.MODEL.RESUME+'.pdparams') is True - assert os.path.isfile(config.MODEL.RESUME+'.pdopt') is True - model_state = paddle.load(config.MODEL.RESUME+'.pdparams') - model.set_dict(model_state) - opt_state = paddle.load(config.MODEL.RESUME+'.pdopt') - optimizer.set_state_dict(opt_state) - local_logger.info( - f"----- Resume Training: Load model and optmizer from {config.MODEL.RESUME}") - if local_rank == 0: - master_logger.info( - f"----- Resume Training: Load model and optmizer from {config.MODEL.RESUME}") - - # STEP 7: Validation (eval mode) - if config.EVAL: - local_logger.info('----- Start Validating') - if local_rank == 0: - master_logger.info('----- Start Validating') - val_loss, val_acc1, val_acc5, avg_loss, avg_acc1, avg_acc5, val_time = validate( - dataloader=dataloader_val, - model=model, - criterion=criterion_val, - total_batch=total_batch_val, - debug_steps=config.REPORT_FREQ, - local_logger=local_logger, - master_logger=master_logger) - local_logger.info(f"Validation Loss: {val_loss:.4f}, " + - f"Validation Acc@1: {val_acc1:.4f}, " + - f"Validation Acc@5: {val_acc5:.4f}, " + - f"time: {val_time:.2f}") - if local_rank == 0: - master_logger.info(f"Validation Loss: {avg_loss:.4f}, " + - f"Validation Acc@1: {avg_acc1:.4f}, " + - f"Validation Acc@5: {avg_acc5:.4f}, " + - f"time: {val_time:.2f}") - return - - # STEP 8: Start training and validation (train mode) - local_logger.info(f"Start training from epoch {last_epoch+1}.") - if local_rank == 0: - master_logger.info(f"Start training from epoch {last_epoch+1}.") - for epoch in range(last_epoch+1, config.TRAIN.NUM_EPOCHS+1): - # train - local_logger.info(f"Now training epoch {epoch}. LR={optimizer.get_lr():.6f}") - if local_rank == 0: - master_logger.info(f"Now training epoch {epoch}. LR={optimizer.get_lr():.6f}") - train_loss, train_acc, avg_loss, avg_acc, train_time = train( - dataloader=dataloader_train, - model=model, - criterion=criterion, - optimizer=optimizer, - epoch=epoch, - total_epochs=config.TRAIN.NUM_EPOCHS, - total_batch=total_batch_train, - debug_steps=config.REPORT_FREQ, - accum_iter=config.TRAIN.ACCUM_ITER, - mixup_fn=mixup_fn, - amp=config.AMP, - local_logger=local_logger, - master_logger=master_logger) - - scheduler.step() - - local_logger.info(f"----- Epoch[{epoch:03d}/{config.TRAIN.NUM_EPOCHS:03d}], " + - f"Train Loss: {train_loss:.4f}, " + - f"Train Acc: {train_acc:.4f}, " + - f"time: {train_time:.2f}") - if local_rank == 0: - master_logger.info(f"----- Epoch[{epoch:03d}/{config.TRAIN.NUM_EPOCHS:03d}], " + - f"Train Loss: {avg_loss:.4f}, " + - f"Train Acc: {avg_acc:.4f}, " + - f"time: {train_time:.2f}") - - # validation - if epoch % config.VALIDATE_FREQ == 0 or epoch == config.TRAIN.NUM_EPOCHS: - local_logger.info(f'----- Validation after Epoch: {epoch}') - if local_rank == 0: - master_logger.info(f'----- Validation after Epoch: {epoch}') - val_loss, val_acc1, val_acc5, avg_loss, avg_acc1, avg_acc5, val_time = validate( - dataloader=dataloader_val, - model=model, - criterion=criterion_val, - total_batch=total_batch_val, - debug_steps=config.REPORT_FREQ, - local_logger=local_logger, - master_logger=master_logger) - local_logger.info(f"----- Epoch[{epoch:03d}/{config.TRAIN.NUM_EPOCHS:03d}], " + - f"Validation Loss: {val_loss:.4f}, " + - f"Validation Acc@1: {val_acc1:.4f}, " + - f"Validation Acc@5: {val_acc5:.4f}, " + - f"time: {val_time:.2f}") - if local_rank == 0: - master_logger.info(f"----- Epoch[{epoch:03d}/{config.TRAIN.NUM_EPOCHS:03d}], " + - f"Validation Loss: {avg_loss:.4f}, " + - f"Validation Acc@1: {avg_acc1:.4f}, " + - f"Validation Acc@5: {avg_acc5:.4f}, " + - f"time: {val_time:.2f}") - # model save - if local_rank == 0: - if epoch % config.SAVE_FREQ == 0 or epoch == config.TRAIN.NUM_EPOCHS: - model_path = os.path.join( - config.SAVE, f"{config.MODEL.TYPE}-Epoch-{epoch}-Loss-{train_loss}") - paddle.save(model.state_dict(), model_path + '.pdparams') - paddle.save(optimizer.state_dict(), model_path + '.pdopt') - master_logger.info(f"----- Save model: {model_path}.pdparams") - master_logger.info(f"----- Save optim: {model_path}.pdopt") - - -def main(): - # config is updated by: (1) config.py, (2) yaml file, (3) arguments - arguments = get_arguments() - config = get_config() - config = update_config(config, arguments) - - # set output folder - if not config.EVAL: - config.SAVE = '{}/train-{}'.format(config.SAVE, time.strftime('%Y%m%d-%H-%M-%S')) - else: - config.SAVE = '{}/eval-{}'.format(config.SAVE, time.strftime('%Y%m%d-%H-%M-%S')) - - if not os.path.exists(config.SAVE): - os.makedirs(config.SAVE, exist_ok=True) - - # get dataset and start DDP - dataset_train = get_dataset(config, mode='train') - dataset_val = get_dataset(config, mode='val') - config.NGPUS = len(paddle.static.cuda_places()) if config.NGPUS == -1 else config.NGPUS - dist.spawn(main_worker, args=(config, dataset_train, dataset_val, ), nprocs=config.NGPUS, ips=arguments.ips) - - -if __name__ == "__main__": - main() diff --git a/image_classification/CycleMLP/run_train_multi_node.sh b/image_classification/CycleMLP/run_train_multi_node.sh deleted file mode 100644 index 8a6ad31f..00000000 --- a/image_classification/CycleMLP/run_train_multi_node.sh +++ /dev/null @@ -1,8 +0,0 @@ -CUDA_VISIBLE_DEVICES=0 \ -python main_multi_node.py \ --cfg='./configs/cyclemlp_b1.yaml' \ --dataset='imagenet2012' \ --batch_size=8 \ --data_path='/dataset/imagenet' \ --ips='172.18.0.2, 172.18.0.3, 172.18.0.4, 172.18.0.5' # the ips should be replaced -#-amp diff --git a/image_classification/ViT/vit.png b/image_classification/ViT/vit.png new file mode 100644 index 0000000000000000000000000000000000000000..a6929f74047cd663b33b407d1dd47fe706d27022 GIT binary patch literal 119352 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�TK6u4?aEFBDM;FMP#S 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