zoukankan      html  css  js  c++  java
  • MindSpore分布式并行训练 (GPU-Docker)mindspore—1.2.1—gpu—docker版本运行报错,Failed to init nccl communicator for group,init nccl communicator for group nccl_world_group

    如题目所述:

    计算框架MindSpore分布式并行训练报错,具体版本:docker-gpu-1.2.1

    运行环境:

    硬件:Intel CPU, 4卡泰坦

    软件:Ubuntu18.04宿主机,docker容器运行MindSpore-gpu-1.2.1-docker版本

                 

    相关软件安装与免密登陆配置:

    docker容器中安装:

    OpenMPI-4.0.3:MindSpore采用的多进程通信库。

    OpenMPI-4.0.3源码下载地址:https://www.open-mpi.org/software/ompi/v4.0/,选择openmpi-4.0.3.tar.gz下载。

    参考OpenMPI官网教程安装:https://www.open-mpi.org/faq/?category=building#easy-build

    NCCL-2.7.6:Nvidia集合通信库。

    NCCL-2.7.6下载地址:https://developer.nvidia.com/nccl/nccl-legacy-downloads

    参考NCCL官网教程安装:https://docs.nvidia.com/deeplearning/nccl/install-guide/index.html#debian

    免密登陆配置:

     主机间免密登陆(涉及多机训练时需要)。若训练涉及多机,则需要配置多机间免密登陆,可参考以下步骤进行配置:

    • 每台主机确定同一个用户作为登陆用户(不推荐root);
    • 执行ssh-keygen -t rsa -P ""生成密钥;
    • 执行ssh-copy-id DEVICE-IP设置需要免密登陆的机器IP;
    • 执行ssh DEVICE-IP,若不需要输入密码即可登录,则说明以上配置成功;
    • 在所有机器上执行以上命令,确保两两互通。

    具体操作参考:

    https://www.mindspore.cn/tutorial/training/zh-CN/r1.2/advanced_use/distributed_training_gpu.html

    ==========================================================

    配置容器内环境后,运行报错:

    运行代码:(      test_nonlinear.py    

    from mindspore import context
    from mindspore.communication.management import init
    context.set_context(mode=context.GRAPH_MODE, device_target="GPU")
    init()
    
    import numpy as np
    from mindspore import dataset as ds
    from mindspore import nn, Tensor, Model
    import time
    from mindspore.train.callback import Callback, LossMonitor, ModelCheckpoint, CheckpointConfig
    from mindspore.context import ParallelMode
    import mindspore as ms
    ms.common.set_seed(0)
    
    start_time = time.time()
    def get_data(num, a=2.0, b=3.0, c=5.0):
        for _ in range(num):
            x = np.random.uniform(-1.0, 1.0)
            y = np.random.uniform(-1.0, 1.0)
            noise = np.random.normal(0, 0.03)
            z = a * x ** 2 + b * y ** 3 + c + noise
            yield np.array([[x**2], [y**3]],dtype=np.float32).reshape(1,2), np.array([z]).astype(np.float32)
    
    def create_dataset(num_data, batch_size=16, repeat_size=1):
        input_data = ds.GeneratorDataset(list(get_data(num_data)), column_names=['xy','z'])
        input_data = input_data.batch(batch_size)
        input_data = input_data.repeat(repeat_size)
        return input_data
    
    data_number = 1600
    batch_number = 64 
    repeat_number = 20
    
    context.set_auto_parallel_context(parallel_mode=ParallelMode.DATA_PARALLEL)
    ds_train = create_dataset(data_number, batch_size=batch_number, repeat_size=repeat_number)
    dict_datasets = next(ds_train.create_dict_iterator())
    
    class LinearNet(nn.Cell):
        def __init__(self):
            super(LinearNet, self).__init__()
            self.fc = nn.Dense(2, 1, 0.02, 0.02)
    
        def construct(self, x):
            x = self.fc(x)
            return x
    
    net = LinearNet()
    model_params = net.trainable_params()
    print ('Param Shape is: {}'.format(len(model_params)))
    for net_param in net.trainable_params():
        print(net_param, net_param.asnumpy())
    net_loss = nn.loss.MSELoss()
    
    optim = nn.Momentum(net.trainable_params(), learning_rate=0.01, momentum=0.6)
    ckpt_config = CheckpointConfig()
    ckpt_callback = ModelCheckpoint(prefix='data_parallel', config=ckpt_config)
    
    model = Model(net, net_loss, optim)
    
    epoch = 1000
    #model.train(epoch, ds_train, dataset_sink_mode=True)
    #model.train(epoch, ds_train, callbacks=[ckpt_callback], dataset_sink_mode=True)
    model.train(epoch, ds_train, callbacks=[LossMonitor(500)], dataset_sink_mode=True)
    
    for net_param in net.trainable_params():
        print(net_param, net_param.asnumpy())
    
    print ('The total time cost is: {}s'.format(time.time() - start_time))

    代码原地址:

    https://www.cnblogs.com/dechinphy/p/dms.html

    由于运行的服务器是有4卡泰坦服务器,因此我们的运行命令如下:

    mpirun -n 4  python ./test_nonlinear.py

    运行结果报错:

    Failed to init nccl communicator for group

     

    init nccl communicator for group nccl_world_group

     对于上面的报错信息比较懵,不过大致可以判断是nccl的问题,

    于是网上找到了一个可以打印nccl信息的操作(https://blog.csdn.net/m0_37426155/article/details/108129952

    打印nccl的日志,在环境变量里添加:

    export NCCL_DEBUG=info
    export NCCL_SOCKET_IFNAME=eth0
    export NCCL_IB_DISABLE=1

    再次运行,打印出详细的报错详细:

    78244:78465 [0] NCCL INFO Call to connect returned Connection timed out, retrying                                                                                                                                                                                            
    78244:78466 [1] NCCL INFO Call to connect returned Connection timed out, retrying                                                                                                                                                                                            
    78244:78465 [0] NCCL INFO Call to connect returned Connection timed out, retrying                                                                                                                                                                                            
    78244:78466 [1] NCCL INFO Call to connect returned Connection timed out, retrying 

     NCCL_ERROR_SYSTEM_ERROR: unhandled system error

     按照再次运行打印出的详细信息,找到这个帖子:(https://github.com/pytorch/pytorch/issues/49095

     虽然这个帖子讲的是分布式运行pytorch,但是报错信息和我这里的基本一致,由于她们实现分布式的原理和依赖的框架完全一致,由此大致判断问题相同。

    比较有帮助的内容如下:

     

    根据帖子上的解决方案就是如果使用docker容器启动,那么就需要设置项:   --ipc=host

    根据帖子上的方法,重新建立容器,在建立时加入设置:   --ipc=host

    完整命令:

    sudo docker run -it --ipc=host -v /dev/shm:/dev/shm -v /data/devil/data:/data -p 7999:22 -p 8000:8000 -p 8001:8080 -p 8002:8002 -p 8003:8003 -p 8004:8004 -p 8005:8005 --runtime=nvidia --privileged=true swr.cn-south-1.myhuaweicloud.com/mindspore/mindspore-gpu:1.2.1 /bin/bash

    可以看到这个建立容器的命令与官网提供的最大区别就是加上了:  --ipc=host

    经过一些已经发现问题出现是由于 nccl 需要使用多进程共享内存的功能,而启动的docker容器如果不加   --ipc=host  ,那么则无法使用该功能因此报错。

    最终答案:

    启动容器时加入:      --ipc=host

    =============================================================

    官网提供的最新分布式说明文档地址:

    https://www.mindspore.cn/tutorials/zh-CN/r1.3/intermediate/distributed_training/distributed_training_gpu.html

    本博客是博主个人学习时的一些记录,不保证是为原创,个别文章加入了转载的源地址还有个别文章是汇总网上多份资料所成,在这之中也必有疏漏未加标注者,如有侵权请与博主联系。
  • 相关阅读:
    16 | 网络优化(中):复杂多变的移动网络该如何优化?
    Understanding Temporal Metrics
    Objective-C Runtime 大佬系列文章整理
    面向对象编程中的封装、抽象、继承、多态特性以及应用
    面向接口编程原理
    一次HTTP请求的完整过程——协议篇(DNS、TCP、HTTP)
    计算机网络 | 图解 DNS & HTTPDNS 原理
    CDN的加速原理是什么?
    让WKWebview支持NSURLProtocol总结
    WKWebView 请求拦截
  • 原文地址:https://www.cnblogs.com/devilmaycry812839668/p/15022320.html
Copyright © 2011-2022 走看看