工作小結六


一. torch數據並行

DataParallel是單進程,多線程情況,DistributedDataParallel支持多進程多線程(當然你可以當做單進程多線程使用)。

關於更細致的解釋不多說:參考

關於進程的執行:

  • 粗暴的方式,直接在多個命令行執行多個python train.py --rank 0,通過命令行參數控制進程的ID。比如torch的多進程通過控制rank控制ID,通訊端口相同,解碼器相同,這里代碼參考:代碼
def main():  
    parser = argparse.ArgumentParser()  
    parser.add_argument('-n', '--nodes', default=1,  
                        type=int, metavar='N')  
    parser.add_argument('-g', '--gpus', default=1, type=int,  
                        help='number of gpus per node')  
    parser.add_argument('-nr', '--nr', default=0, type=int,  
                        help='ranking within the nodes')  
    parser.add_argument('--epochs', default=2, type=int,  
                        metavar='N',  
                        help='number of total epochs to run')  
    args = parser.parse_args()  
    #########################################################  
    args.world_size = args.gpus * args.nodes                #  
    os.environ['MASTER_ADDR'] = '10.57.23.164'              #  
    os.environ['MASTER_PORT'] = '8888'                      #  
    mp.spawn(train, nprocs=args.gpus, args=(args,))         #  
    #########################################################  
  • 通過python自帶的multiprocessing執行多進程,通過一個循環執行和傳入的參數執行不同的ID。這里參考官方代碼,已修改部分代碼代碼
def main():
    #args = parse_args()
    #update_config(cfg, args)

    cudnn.deterministic = cfg.SYSTEM.DETERMINISTIC

    if cfg.TRAIN.DIST.IS_MULTI_DISTRIBUTE:
        # Use torch.multiprocessing.spawn to launch distributed processes: the
        # main_worker process function
        mp.spawn(main_worker, nprocs=len(cfg.SYSTEM.GPU_ID), args=())
    else:
        # Simply call main_worker function
        main_worker(cfg.SYSTEM.GPU_ID)
def main_worker(cur_gpu):
    global models#, g_rank, g_batch, g_numwork, logger

    # Since we have ngpus_per_node processes per node, the total world_size
    # needs to be adjusted accordingly
    cfg.TRAIN.DIST.WORLD_SIZE = len(cfg.SYSTEM.GPU_ID) * cfg.TRAIN.DIST.WORLD_SIZE #FIXME get error when put out side

    if cfg.TRAIN.DIST.IS_MULTI_DISTRIBUTE:
        # For multiprocessing distributed training, rank needs to be the
        # global rank among all the processes
        cfg.TRAIN.DIST.RANK = cfg.TRAIN.DIST.RANK * len(cfg.SYSTEM.GPU_ID) + cur_gpu
        dist.init_process_group(backend=cfg.TRAIN.DIST.BACKEND,
                                init_method=cfg.TRAIN.DIST.METHOD,
                                world_size=cfg.TRAIN.DIST.WORLD_SIZE,
                                rank=cfg.TRAIN.DIST.RANK)

    if cfg.TRAIN.IS_LOAD_PRETRAINED:
        models.load_state_dict(torch.load(cfg.FILE.PRETRAINED,map_location=torch.device('cpu')))

    if cfg.TRAIN.DIST.IS_MULTI_DISTRIBUTE:
        # For multiprocessing distributed, DistributedDataParallel constructor
        # should always set the single device scope, otherwise,
        # DistributedDataParallel will use all available devices.
        torch.cuda.set_device(cur_gpu)
        models.cuda(cur_gpu)
        # When using a single GPU per process and per
        # DistributedDataParallel, we need to divide the batch size
        # ourselves based on the total number of GPUs we have
        cfg.TRAIN.BATCH_SIZE = int(cfg.TRAIN.BATCH_SIZE / len(cfg.SYSTEM.GPU_ID))
        cfg.SYSTEM.NUM_WORKERS = int((cfg.SYSTEM.NUM_WORKERS + len(cfg.SYSTEM.GPU_ID) - 1) / len(cfg.SYSTEM.GPU_ID))
        models = torch.nn.parallel.DistributedDataParallel(models, device_ids=[cur_gpu])
        logger.info('\nCreat process world size:{}, rank:{}, gpu:{}, num_work:{}, batch_sieze:{} ' \
                    .format(cfg.TRAIN.DIST.WORLD_SIZE, \
                            cfg.TRAIN.DIST.RANK, cur_gpu,\
                            cfg.SYSTEM.NUM_WORKERS,\
                            cfg.TRAIN.BATCH_SIZE))
    else :
        models = models.cuda(cur_gpu[0])
        models = nn.DataParallel(models, device_ids=cur_gpu)

    train_sampler = None
    if cfg.TRAIN.DIST.IS_MULTI_DISTRIBUTE:
        train_sampler = torch.utils.data.distributed.DistributedSampler(
                                RHDDataset(dataset_dir=cfg.DATASET.RHD_HAND.DATA_ROOT, is_train=True))
    train_loader = DataLoaderX(
                                RHDDataset(dataset_dir=cfg.DATASET.RHD_HAND.DATA_ROOT, is_train=True),
                                shuffle = True if train_sampler is None else False,
                                pin_memory=cfg.SYSTEM.PIN_MEMORY,
                                batch_size=cfg.TRAIN.BATCH_SIZE,
                                num_workers=cfg.SYSTEM.NUM_WORKERS,
                                sampler=train_sampler)
    optimizer = optim.Adam(params=models.parameters(), lr=cfg.TRAIN.LR_RATE)
    scheduler = WarmupCosineLR()
    cudnn.benchmark = True
    
    #Train epochs
    #........

關於注意事項:

  • torch已經封裝的很好了,而且還有demo。其實僅僅修改batchsize和rank即可,代碼很簡單。
  • 注意GPU的數量,前面使用os.environ去控制一下比較好。
  • 我這里看單進程4GPU:大概75%的利用率,四進程4GPU:大概85%的利用率。抖動有點嚴重,有時候60%-99%,看數據分散情況。

二. No Modules

關於No Moudules,這個不同編譯器不同。

關於VScode:

  • 安裝python或conda環境之后,提示找不到python或者找不到XXX modules,比如python-opencv在命令行可以使用,但是在vscode顯示找不到cv2.

使用sys.executable查看當前的python環境,看看是不是你使用的環境?

如果不是,那三種方法:

如果當前環境沒錯,看看模塊名是不是和文件名重復了(盡量別重復)。
F5調試,然后在錯誤的地方F11進入(進不了說明os.getcwd()有問題,自己檢查項目根目錄),查看內部具體是哪個import有問題,針對修改即可。

如果上面都完成解決不了,那就自己強制加一句話:"env": {"PYTHONPATH":"${workspaceRoot}"}
如果是debug,那就在debug的launch.json里面加。如果是run,那就在.vscode目錄下的文件夾,launch.json里面加。

關於pycharm

  • 設置中的環境不能弄錯。

  • 使用os.getpwd()查看當前所在目錄,根據當前目錄進行更改即可。

  • 同一個文件夾下,文件名和函數名最好別重復,最好別引發歧義。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM