📜  Apache MXNet-分布式培训(1)

📅  最后修改于: 2023-12-03 15:13:26.076000             🧑  作者: Mango

Apache MXNet-分布式培训

介绍

Apache MXNet是一款多领域深度学习框架,由Amazon公司主导开发,旨在实现高效、灵活、可扩展的深度学习。

MXNet通过支持多种编程语言、能够自动并行处理等特点,发挥了异构计算资源(CPU、GPU、FPGA)的优势,让用户快速训练高质量的模型。

此外,MXNet还支持分布式训练,能够通过多个机器协同训练,进一步提高训练效率。

分布式训练

MXNet的分布式训练基于Parameter Server(参数服务器)模式,将模型参数划分为多个部分,分配到不同的服务器上进行计算。

分布式训练的主要有两个步骤:参数分发和梯度聚合。

其中,参数分发指将模型参数分配到不同的服务器上进行计算;而梯度聚合则是指在每个迭代周期结束后,将不同服务器上得到的梯度合并为一个梯度,并更新参数。

MXNet分布式训练支持多种不同的分发和聚合方式,用户可以根据实际情况选择最合适的方式。

分发方式

MXNet目前支持三种不同的参数分发方式:

  1. 以实例为单位分发:将数据集划分为多个小批量,每个实例只负责计算一个小批量的数据。该方式适用于数据集较大的情况,可以提高训练速度。

    代码示例:

    # 实例分发
    dist.init_process_group("gloo")
    ddp_model = DDP(model, find_unused_parameters=True, device_ids=[args.local_rank], output_device=args.local_rank)
    train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)
    train_loader = torch.utils.data.DataLoader(train_dataset,
                                               batch_size=args.batch_size,
                                               sampler=train_sampler,
                                               num_workers=args.num_workers,
                                               pin_memory=True)
    
  2. 以参数为单位分发:将模型参数划分为多个部分,分配到不同的服务器上计算。该方式适用于模型参数较大的情况。

    代码示例:

    # 参数分发
    dist.init_process_group("nccl")
    model = DDP(model, device_ids=[args.local_rank], output_device=args.local_rank, bucket_cap_mb=args.bucket_cap_mb)
    train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)
    train_loader = torch.utils.data.DataLoader(train_dataset,
                                               batch_size=args.batch_size,
                                               sampler=train_sampler,
                                               num_workers=args.num_workers,
                                               pin_memory=True)
    
  3. 混合分发:将数据集和模型参数同时分配到不同的服务器上进行计算。该方式适用于数据集和模型参数都较大的情况。

    代码示例:

    # 混合分发
    dist.init_process_group("nccl")
    model = DDP(model, device_ids=[args.local_rank], output_device=args.local_rank, find_unused_parameters=True)
    train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)
    train_loader = torch.utils.data.DataLoader(train_dataset,
                                               batch_size=args.batch_size,
                                               sampler=train_sampler,
                                               num_workers=args.num_workers,
                                               pin_memory=True)
    
聚合方式

MXNet目前支持两种不同的梯度聚合方式:

  1. averager聚合器:将不同服务器上的梯度求平均,再更新模型参数。

    代码示例:

    # averager聚合器
    from mxnet.contrib.ndarray import ps_initializer
    
    # 创建参数服务器,将参数划分为4个部分,分配到4台主机上
    kv = mx.kv.create('dist_sync', num_workers=4)
    kv.set_optimizer(mx.optimizer.create('sgd', learning_rate=0.01))
    kv.init(3, mx.nd.zeros((3,)), ps_initializer(mx.init.Xavier(rnd_type='gaussian')))
    
    # 同步更新参数
    for i in range(num_epochs):
        for batch in data_iterator:
            kv.push(batch.data[0], batch.label[0])
            kv.pull(0, out=model.weight.data(), priority=-i)
    
  2. row_sparse聚合器:将不同服务器上的梯度按照行稀疏方式聚合,再更新模型参数。

    代码示例:

    # row_sparse聚合器
    from mxnet.contrib.ndarray import ps_initializer
    
    # 创建参数服务器,将参数划分为4个部分,分配到4台主机上
    kv = mx.kv.create('dist_sync', num_workers=4)
    kv.set_optimizer(mx.optimizer.create('sgd', learning_rate=0.01))
    kv.init(3, mx.nd.zeros((3,)), ps_initializer(mx.init.Xavier(rnd_type='gaussian')))
    
    # 同步更新参数
    for i in range(num_epochs):
        for batch in data_iterator:
            kv.push(batch.data[0], batch.label[0])
            kv.pull(0, out=model.weight.data(), priority=-i, row_ids=batch.index[0])
    
结论

MXNet是一款支持分布式训练,能够发挥异构计算资源优势的多领域深度学习框架。

通过合适的参数分发和梯度聚合方式,MXNet可以快速训练高质量的模型,提高训练效率。