| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| from __future__ import print_function |
|
|
| import argparse |
| import datetime |
| import logging |
| import os |
| import torch |
| import yaml |
|
|
| import torch.distributed as dist |
|
|
| from torch.distributed.elastic.multiprocessing.errors import record |
| from wenet.utils.common import lrs_to_str, TORCH_NPU_AVAILABLE |
|
|
| from wenet.utils.executor import Executor |
| from wenet.utils.config import override_config |
| from wenet.utils.init_model import init_model |
| from wenet.utils.init_tokenizer import init_tokenizer |
| from wenet.utils.train_utils import ( |
| add_fsdp_args, add_model_args, add_dataset_args, add_ddp_args, |
| add_deepspeed_args, add_trace_args, init_distributed, |
| init_dataset_and_dataloader, check_modify_and_save_config, |
| init_optimizer_and_scheduler, init_scaler, trace_and_print_model, |
| wrap_cuda_model, init_summarywriter, save_model, log_per_epoch, |
| add_lora_args, reinit_lora) |
|
|
|
|
| def get_args(): |
| parser = argparse.ArgumentParser(description='training your network') |
| parser.add_argument('--train_engine', |
| default='torch_ddp', |
| choices=['torch_ddp', 'torch_fsdp', 'deepspeed'], |
| help='Engine for paralleled training') |
| |
| parser.add_argument('--device', |
| type=str, |
| default='cuda', |
| choices=["cpu", "npu", "cuda"], |
| help='accelerator for training') |
| parser = add_model_args(parser) |
| parser = add_dataset_args(parser) |
| parser = add_ddp_args(parser) |
| parser = add_lora_args(parser) |
| parser = add_deepspeed_args(parser) |
| parser = add_fsdp_args(parser) |
| parser = add_trace_args(parser) |
| args = parser.parse_args() |
| if args.train_engine == "deepspeed": |
| args.deepspeed = True |
| assert args.deepspeed_config is not None |
| return args |
|
|
|
|
| |
| |
| @record |
| def main(): |
| args = get_args() |
| logging.basicConfig(level=logging.DEBUG, |
| format='%(asctime)s %(levelname)s %(message)s') |
|
|
| |
| torch.manual_seed(777) |
|
|
| |
| with open(args.config, 'r') as fin: |
| configs = yaml.load(fin, Loader=yaml.FullLoader) |
| if len(args.override_config) > 0: |
| configs = override_config(configs, args.override_config) |
|
|
| |
| tokenizer = init_tokenizer(configs) |
|
|
| |
| _, _, rank = init_distributed(args) |
|
|
| |
| train_dataset, cv_dataset, train_data_loader, cv_data_loader = \ |
| init_dataset_and_dataloader(args, configs, tokenizer) |
|
|
| |
| configs = check_modify_and_save_config(args, configs, |
| tokenizer.symbol_table) |
|
|
| |
| model, configs = init_model(args, configs) |
|
|
| if hasattr(args, 'lora_reinit') and args.lora_reinit: |
| reinit_lora(model, args, configs, tokenizer) |
|
|
| |
| trace_and_print_model(args, model) |
|
|
| |
| writer = init_summarywriter(args) |
|
|
| |
| model, device = wrap_cuda_model(args, model, configs) |
|
|
| |
| model, optimizer, scheduler = init_optimizer_and_scheduler( |
| args, configs, model) |
|
|
| |
| save_model(model, |
| info_dict={ |
| "save_time": |
| datetime.datetime.now().strftime('%d/%m/%Y %H:%M:%S'), |
| "tag": |
| "init", |
| **configs |
| }) |
|
|
| |
| tag = configs["init_infos"].get("tag", "init") |
| executor = Executor(global_step=configs["init_infos"].get('step', -1), |
| device=device) |
|
|
| |
| scaler = init_scaler(args) |
|
|
| |
| start_epoch = configs["init_infos"].get('epoch', 0) + int("epoch_" in tag) |
| |
| end_epoch = configs.get('max_epoch', |
| 100) if "save_interval" not in configs else 1 |
| assert start_epoch <= end_epoch |
| configs.pop("init_infos", None) |
| final_epoch = None |
| for epoch in range(start_epoch, end_epoch): |
| configs['epoch'] = epoch |
|
|
| lrs = [group['lr'] for group in optimizer.param_groups] |
| logging.info('Epoch {} Step {} TRAIN info lr {} rank {}'.format( |
| epoch, executor.step, lrs_to_str(lrs), rank)) |
|
|
| dist.barrier( |
| ) |
| |
| group_join = dist.new_group( |
| backend="gloo", timeout=datetime.timedelta(seconds=args.timeout)) |
| executor.train(model, optimizer, scheduler, train_data_loader, |
| cv_data_loader, writer, configs, scaler, group_join) |
| dist.destroy_process_group(group_join) |
|
|
| dist.barrier( |
| ) |
| loss_dict = executor.cv(model, cv_data_loader, configs) |
| info_dict = { |
| 'epoch': epoch, |
| 'lrs': [group['lr'] for group in optimizer.param_groups], |
| 'step': executor.step, |
| 'save_time': datetime.datetime.now().strftime('%d/%m/%Y %H:%M:%S'), |
| 'tag': "epoch_{}".format(epoch), |
| 'loss_dict': loss_dict, |
| **configs |
| } |
| |
| log_per_epoch(writer, info_dict=info_dict) |
| save_model(model, info_dict=info_dict) |
|
|
| final_epoch = epoch |
|
|
| if final_epoch is not None and rank == 0: |
| final_model_path = os.path.join(args.model_dir, 'final.pt') |
| os.remove(final_model_path) if os.path.exists( |
| final_model_path) else None |
| os.symlink('{}.pt'.format(final_epoch), final_model_path) |
| writer.close() |
| dist.barrier( |
| ) |
| dist.destroy_process_group() |
|
|
|
|
| if __name__ == '__main__': |
| main() |
|
|