# Copyright (c) 2023 PaddlePaddle 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. import inspect import os import random import time from pprint import pprint import numpy as np import paddle import paddle.distributed as dist from benchmark import options from benchmark.modules.benchmark_utils import clone_inputs from benchmark.options import LR_SCHEDULER_REGISTRY, MODEL_REGISTRY, OPTIMIZER_REGISTRY from benchmark.utils.record import AverageStatistical from paddlenlp.utils import profiler from paddlenlp.utils.log import logger def set_seed(seed): paddle.seed(seed) random.seed(seed) np.random.seed(seed) def do_generated_inputs(args): if args.device == "cpu": rank = 0 trainer_count = 1 paddle.set_device("cpu") else: rank = dist.get_rank() trainer_count = dist.get_world_size() if trainer_count > 1: dist.init_parallel_env() # Set seed for CE if args.seed is not None: set_seed(args.seed) benchmark_model = MODEL_REGISTRY[args.model]() benchmark_optimizer = OPTIMIZER_REGISTRY[args.optimizer]() if args.max_steps is None or (args.max_steps is not None and args.max_steps < 0): args.max_steps = 10000 # Define model model = benchmark_model.build_model(args) if args.to_static: input_spec = benchmark_model.create_input_specs() model = paddle.jit.to_static(model, input_spec=input_spec) logger.info("Successfully to apply @to_static with specs: {}".format(input_spec)) # Define data loader example_inputs = benchmark_model.generate_inputs_for_model(args, model) if args.lr_scheduler is not None: benchmark_lr_scheduler = LR_SCHEDULER_REGISTRY[args.lr_scheduler]() lr = benchmark_lr_scheduler.build_scheculer(args) else: lr = args.learning_rate optimizer = benchmark_optimizer.build_optimizer(args, lr, model) # for amp training if args.use_amp: scaler = paddle.amp.GradScaler(enable=True, init_loss_scaling=args.scale_loss) model = paddle.amp.decorate(models=model, level=args.amp_level, save_dtype="float32") # for distributed training if trainer_count > 1: model = paddle.DataParallel(model) step_id = 1 # For benchmark reader_cost_avg = AverageStatistical() batch_cost_avg = AverageStatistical() batch_ips_avg = AverageStatistical() # Train loop for pass_id in range(args.epoch): epoch_start = time.time() batch_start = time.time() for batch_id in range(args.max_steps): train_reader_cost = time.time() - batch_start cloned_inputs = clone_inputs(example_inputs) if args.use_amp: # paddle version >= 2.5.0 or develop paddle_version = float(paddle.__version__[:3]) if (paddle_version == 0.0) or (paddle_version >= 2.5): with paddle.amp.auto_cast( custom_black_list=args.custom_black_list if args.amp_level == "O2" else {}, level=args.amp_level, use_promote=args.amp_use_promote, ): loss, sample_per_cards = benchmark_model.forward(model, args, cloned_inputs) else: with paddle.amp.auto_cast( custom_black_list=args.custom_black_list if args.amp_level == "O2" else {}, level=args.amp_level, ): loss, sample_per_cards = benchmark_model.forward(model, args, cloned_inputs) scaled = scaler.scale(loss) scaled.backward() scaler.minimize(optimizer, scaled) if "set_to_zero" in inspect.getfullargspec(optimizer.clear_grad).args: optimizer.clear_grad(set_to_zero=False) else: optimizer.clear_grad() else: loss, sample_per_cards = benchmark_model.forward(model, args, cloned_inputs) loss.backward() optimizer.step() optimizer.clear_grad() if args.profiler_options is not None: profiler.add_profiler_step(args.profiler_options) if args.max_steps and step_id == args.max_steps: if args.save_model and rank == 0: model_dir = args.save_model if not os.path.exists(model_dir): os.makedirs(model_dir) paddle.save(model.state_dict(), os.path.join(model_dir, "model.pdparams")) paddle.save(optimizer.state_dict(), os.path.join(model_dir, "model.pdopt")) return if args.lr_scheduler is not None and not args.scheduler_update_by_epoch: lr.step() if step_id % args.logging_steps == 0: total_avg_loss = loss.numpy() train_batch_cost = time.time() - batch_start reader_cost_avg.record(train_reader_cost) batch_cost_avg.record(train_batch_cost) batch_ips_avg.record(train_batch_cost, sample_per_cards) benchmark_model.logger( args, step_id=step_id, pass_id=pass_id, batch_id=batch_id, loss=total_avg_loss, batch_cost=batch_cost_avg.get_average(), reader_cost=reader_cost_avg.get_average(), num_samples=sample_per_cards, ips=batch_ips_avg.get_average_per_sec(), ) reader_cost_avg.reset() batch_cost_avg.reset() batch_ips_avg.reset() else: train_batch_cost = time.time() - batch_start reader_cost_avg.record(train_reader_cost) batch_cost_avg.record(train_batch_cost) batch_ips_avg.record(train_batch_cost, sample_per_cards) batch_start = time.time() batch_id += 1 step_id += 1 if args.lr_scheduler is not None and args.scheduler_update_by_epoch: lr.step() train_epoch_cost = time.time() - epoch_start logger.info("train epoch: %d, epoch_cost: %.5f s" % (pass_id, train_epoch_cost)) def do_train(args): if args.device == "gpu": rank = dist.get_rank() trainer_count = dist.get_world_size() else: rank = 0 trainer_count = 1 paddle.set_device("cpu") if trainer_count > 1: dist.init_parallel_env() # Set seed for CE if args.seed is not None: set_seed(args.seed) benchmark_model = MODEL_REGISTRY[args.model]() benchmark_optimizer = OPTIMIZER_REGISTRY[args.optimizer]() # Define data loader train_loader, eval_loader = benchmark_model.create_data_loader(args) if args.max_steps is None or (args.max_steps is not None and args.max_steps < 0): args.max_steps = len(train_loader) * args.epoch # Define model model = benchmark_model.build_model(args) if args.to_static: input_spec = benchmark_model.create_input_specs() model = paddle.jit.to_static(model, input_spec=input_spec) logger.info("Successfully to apply @to_static with specs: {}".format(input_spec)) if args.lr_scheduler is not None: benchmark_lr_scheduler = LR_SCHEDULER_REGISTRY[args.lr_scheduler]() lr = benchmark_lr_scheduler.build_scheculer(args) else: lr = args.learning_rate optimizer = benchmark_optimizer.build_optimizer(args, lr, model) # for amp training if args.use_amp: scaler = paddle.amp.GradScaler(enable=True, init_loss_scaling=args.scale_loss) model = paddle.amp.decorate(models=model, level=args.amp_level, save_dtype="float32") # for distributed training if trainer_count > 1: model = paddle.DataParallel(model) step_id = 1 # For benchmark reader_cost_avg = AverageStatistical() batch_cost_avg = AverageStatistical() batch_ips_avg = AverageStatistical() # Train loop for pass_id in range(args.epoch): epoch_start = time.time() batch_id = 0 batch_start = time.time() for input_data in train_loader: train_reader_cost = time.time() - batch_start if args.use_amp: # paddle version >= 2.5.0 or develop paddle_version = float(paddle.__version__[:3]) if (paddle_version == 0.0) or (paddle_version >= 2.5): with paddle.amp.auto_cast( custom_black_list=args.custom_black_list if args.amp_level == "O2" else {}, level=args.amp_level, use_promote=args.amp_use_promote, ): loss, sample_per_cards = benchmark_model.forward(model, args, input_data) else: with paddle.amp.auto_cast( custom_black_list=args.custom_black_list if args.amp_level == "O2" else {}, level=args.amp_level, ): loss, sample_per_cards = benchmark_model.forward(model, args, input_data) scaled = scaler.scale(loss) scaled.backward() scaler.minimize(optimizer, scaled) if "set_to_zero" in inspect.getfullargspec(optimizer.clear_grad).args: optimizer.clear_grad(set_to_zero=False) else: optimizer.clear_grad() else: loss, sample_per_cards = benchmark_model.forward(model, args, input_data) loss.backward() optimizer.step() optimizer.clear_grad() if args.profiler_options is not None: profiler.add_profiler_step(args.profiler_options) if args.max_steps and step_id == args.max_steps: if args.save_model and rank == 0: model_dir = args.save_model if not os.path.exists(model_dir): os.makedirs(model_dir) paddle.save(model.state_dict(), os.path.join(model_dir, "model.pdparams")) paddle.save(optimizer.state_dict(), os.path.join(model_dir, "model.pdopt")) return if args.lr_scheduler is not None and not args.scheduler_update_by_epoch: lr.step() if step_id % args.logging_steps == 0: total_avg_loss = loss.numpy() train_batch_cost = time.time() - batch_start reader_cost_avg.record(train_reader_cost) batch_cost_avg.record(train_batch_cost) batch_ips_avg.record(train_batch_cost, sample_per_cards) benchmark_model.logger( args, step_id=step_id, pass_id=pass_id, batch_id=batch_id, loss=total_avg_loss, batch_cost=batch_cost_avg.get_average(), reader_cost=reader_cost_avg.get_average(), num_samples=sample_per_cards, ips=batch_ips_avg.get_average_per_sec(), ) reader_cost_avg.reset() batch_cost_avg.reset() batch_ips_avg.reset() else: train_batch_cost = time.time() - batch_start reader_cost_avg.record(train_reader_cost) batch_cost_avg.record(train_batch_cost) batch_ips_avg.record(train_batch_cost, sample_per_cards) batch_start = time.time() batch_id += 1 step_id += 1 if args.lr_scheduler is not None and args.scheduler_update_by_epoch: lr.step() train_epoch_cost = time.time() - epoch_start logger.info("train epoch: %d, epoch_cost: %.5f s" % (pass_id, train_epoch_cost)) def do_hapi(args): paddle.set_device(args.device) # Set seed for CE if args.seed is not None: set_seed(args.seed) benchmark_model = MODEL_REGISTRY[args.model]() benchmark_optimizer = OPTIMIZER_REGISTRY[args.optimizer]() # Define data loader train_loader, eval_loader = benchmark_model.create_data_loader(args) if args.lr_scheduler is not None: benchmark_lr_scheduler = LR_SCHEDULER_REGISTRY[args.lr_scheduler]() lr = benchmark_lr_scheduler.build_scheculer(args) else: lr = args.learning_rate model = benchmark_model.build_model(args) if args.to_static: input_spec = benchmark_model.create_input_specs() model = paddle.jit.to_static(model, input_spec=input_spec) logger.info("Successfully to apply @to_static with specs: {}".format(input_spec)) optimizer = benchmark_optimizer.build_optimizer(args, lr, model) benchmark_model.forward(model, args, optimizer=optimizer, train_loader=train_loader, eval_loader=eval_loader) if __name__ == "__main__": parser = options.get_training_parser() args = options.parse_args_and_model(parser) pprint(args) if args.generated_inputs: do_generated_inputs(args) elif getattr(args, "use_hapi", False): do_hapi(args) else: do_train(args)