ืชืจืืื ืืืืืจ ืืืื ืขืจื ืชืืืืช ืืงืืจืก
ืืืืื ืืืืืจ ืขื ืคื ื ืืกืคืจ ืืืคืขื ืืืฉืื ืืขืื ืืืฆืืขืื ืืืืืื ืืืื ืืืคืืืช ืืช ืืื ืืืืืื ืฉื ืจืฉืชืืช ืขืฆืืืืช ืขืืืงืืช ืืืืจื ืืืช ืขื ืืขืจืื ื ืชืื ืื ืืืืืื ืืฉืืืขืืช ืืฉืขืืช ืื ืืคืืื ืืงืืช, ืื ืฉืืืคื ืืช ืืื ืืงืช ืืืืืื ืืื ืื ืคืืฆื ืืฉืืืืฉ ืืืขืฉื ืฉื ืืืืื ืขืืืงื. ืขื ืืืฉืชืืฉืื ืืืืื ืืืฆื ืืฉืชืฃ ืืืกื ืืจื ื ืชืื ืื ืขื ืคื ื ืืกืคืจ ืืืคืขืื, ืื ืฉืืชืืจื ืืฉืคืืข ืืืืคื ืืฉืืขืืชื ืขื ืืืืืช ืืืจืืื. ืืชืจ ืขื ืื, ืขื ืืืฉืชืืฉืื ืืืขืช ืื ืืืฆื ืืคืจืืก ืกืงืจืืคื ืืืืื ืืคืืขื ืขื ืืืคืข ืืืื ืืืกืคืจ ืืืคืขืื.
ืืืืืจ ืื, ื ืืื ืืฉืืื ืืืืจื ืืงืื ืืืืืื ืืืืืจ ืืืืฆืขืืช ืกืคืจืืืช ืืืืืื ืืขืืืงื ืฉื Apache MXNet ืืงืื ืคืชืื ืืืกืืจืช ืืืืืื ืืืืืืจืช Horovod. ื ืืืื ืืช ืืชืจืื ืืช ืืืืฆืืขืื ืฉื ืืกืืจืช Horovod ืื ืจืื ืืืฆื ืืืชืื ืกืงืจืืคื ืืืืื MXNet ืฉืคืืขื ืืืืคื ืืืืืจ ืขื Horovod.
ืื ืื ืืคืืฆ'ื MXNet?
MXNet ืืื ืืกืืจืช ืืืืื ืขืืืงื ืืงืื ืคืชืื ืืืฉืืฉืช ืืืฆืืจื, ืืืืื ืืคืจืืกื ืฉื ืจืฉืชืืช ืขืฆืืืืช ืขืืืงืืช. MXNet ืืคืฉืืช ืืช ืืืืจืืืืืืช ืืงืฉืืจืืช ืืืืฉืื ืจืฉืชืืช ืขืฆืืืืช, ืืกืคืงืช ืืืฆืืขืื ืืืืืื ืืืืืฉืืช, ืืืฆืืขื ืืืฉืงื API ืืฉืคืืช ืชืื ืืช ืคืืคืืืจืืืช ืืืื , , , , , , ืืขืื.
ืืืจืื ืืืืืจืช ื-MXNet ืขื ืฉืจืช ืคืจืืืจืื
ืืฉืชืืฉ ืืืืฉืช ืฉืจืช ืคืจืืืจืื. ืืื ืืฉืชืืฉืช ืืงืืืฆืช ืฉืจืชื ืคืจืืืจืื ืืื ืืืกืืฃ ืืจืืืื ืืื ืืื ืขืืื, ืืืฆืข ืฆืืืจื ืืืฉืืื ืืจืืืื ืืื ืืขืืืื ืื ืืืืจื ืืขืืืืื ืขืืืจ ืืืืจืฆืืืช ืืืืคืืืืืืฆืื ืืืื. ืงืืืขืช ืืืืก ืื ืืื ืืื ืฉืจืชืื ืืขืืืืื ืืื ืืืคืชื ืืงื ื ืืืื ืืขืื. ืื ืืฉืชืืฉืื ืจืง ืืฉืจืช ืคืจืืืจืื ืืื, ืืื ืืืื ืืืคืื ืืฆืืืืจ ืืงืืืง ืืืฉืืื. ืืขืืืช ืืืช, ืื ืืฉืชืืฉืื ืืืืชืจ ืืื ืฉืจืชืื, ืืงืฉืจ ืฉื ืจืืื ืืจืืื ืืืื ืืืจืืืช ืืช ืื ืืืืืจื ืืจืฉืช.
ืื ืื ืืืจืืืื?
โ ืืกืืจืช ืืืืื ืขืืืงื ืืืืืจืช ืืงืื ืคืชืื ืฉืคืืชืื ืืืืืจ. ืืื ืืฉืชืืฉืช ืืืื ืืืืืืืช ืืขืืืืช ืืชืงืฉืืจืช ืืื ืืกืคืจ ืืขืืืื ืืจืคืืื ืืฆืืชืื, ืืืื ืกืคืจืืืช ืืชืงืฉืืจืช ืืงืืืงืืืืืช ืฉื NVIDIA (NCCL) ืืืืฉืง ืืขืืจืช ืืืืขืืช (MPI), ืืื ืืืคืืฅ ืืืฆืืืจ ืคืจืืืจืื ืฉื ืืืืืื ืขื ืคื ื ืืขืจืืืืืช. ืืื ืืืืืช ืืช ื ืืฆืื ืจืืื ืืคืก ืฉื ืืจืฉืช ืืืชืืืื ืืช ืขืฆืื ืืืื ืืขืช ืืคืขืืช ืืืืืื ืฉื ืจืฉืชืืช ืขืฆืืืืช ืขืืืงืืช. ืืื ืชืืืืช ืืืื ืืืกืคืจ ืืกืืจืืช ืคืืคืืืจืืืช ืฉื ืืืืืช ืืืื ื, ืืืืื ื , Tensorflow, Keras ื-PyTorch.
ืืื ืืืจืฆืื ืืื MXNet ื-Horovod
MXNet ืืฉืชืื ืขื Horovod ืืจื ืืืฉืงื ื-API ืฉื ืืืืื ืืืืืจืช ืืืืืืจืื ื-Horovod. ืืืฉืงื ื-API ืฉื ืืชืงืฉืืจืช ืฉื Horovod horovod.broadcast(), horovod.allgather() ะธ horovod.allreduce() ืืืืฉืืื ืืืืฆืขืืช ืงืจืืืืช ืืืืจืืช ืืกืื ืืจืื ืืืช ืฉื ืื ืืข MXNet ืืืืง ืืืจืฃ ืืืฉืืืืช ืฉืื. ืืืจื ืื, ืชืืืืืช ื ืชืื ืื ืืื ืชืงืฉืืจืช ืืืืฉืื ืืืืคืืืช ืืงืืืช ืขื ืืื ืื ืืข MXNet ืืื ืืื ืืข ืืคืกืื ืืืฆืืขืื ืขืงื ืกื ืืจืื. ืืืืืืงื ืืืืคืืืืืืฆืื ืืืืืืจ, ืืืืืืจ ื-Horovod horovod.DistributedOptimizer ืืชืจืื ืืืืื ื-MXNet ืื ืฉืืื ืืงืจื ื-API ืฉื Horovod ืืืชืืืืื ืขืืืจ ืขืืืื ื ืคืจืืืจืื ืืืืืจืื. ืื ืคืจืื ืืืืฉืื ืืืื ืฉืงืืคืื ืืืฉืชืืฉื ืืงืฆื.
ืืชืืื ืืืืจื
ื ืืชื ืืืชืืื ืืืืืจืืช ืืืื ืจืฉืช ื ืืืจืื ืื ืงืื ืืืืืฆืืื ืืช ืงืื ื ืขื ืงืืืฆืช ืื ืชืื ืื MNIST ืืืืฆืขืืช MXNet ื-Horovod ืืืืฉื ื-MacBook ืฉืืื.
ืืื ืืืชืืื, ืืชืงืื ื ืืช mxnet ื-horovod ื-PyPI:
pip install mxnet
pip install horovodืืขืจื: ืื ื ืชืงืืช ืืฉืืืื ืืืืื ืคืืค ืืชืงืื ืืืจืืืื, ืืืชืื ืฉืชืฆืืจื ืืืืกืืฃ ืืฉืชื ื MACOSX_DEPLOYMENT_TARGET=10.vvืืืคื vv โ ืืืื ืืจืกืช ื-MacOS ืฉืื, ืืืืืื, ืขืืืจ MacOSX Sierra ืชืฆืืจื ืืืชืื MACOSX_DEPLOYMENT_TARGET=10.12 ืืชืงื ืช pip horovod
ืืืืจ ืืื ืืชืงื ืืช OpenMPI .
ืืกืืฃ, ืืขืื ืืช ืกืงืจืืคื ืืืืืงื mxnet_mnist.py ืืืจืฅ ืืช ืืคืงืืืืช ืืืืืช ืืืกืืฃ ื-MacBook ืืกืคืจืืืช ืืขืืืื:
mpirun -np 2 -H localhost:2 -bind-to none -map-by slot python mxnet_mnist.pyืคืขืืื ืื ืชืคืขืื ืืืืื ืขื ืฉืชื ืืืืืช ืฉื ืืืขืื ืฉืื. ืืคืื ืืืื:
INFO:root:Epoch[0] Batch [0-50] Speed: 2248.71 samples/sec accuracy=0.583640
INFO:root:Epoch[0] Batch [50-100] Speed: 2273.89 samples/sec accuracy=0.882812
INFO:root:Epoch[0] Batch [50-100] Speed: 2273.39 samples/sec accuracy=0.870000ืืืืืช ืืืฆืืขืื
ืืขืช ืืืืื ืืืื ResNet50-v1 ืขื ืงืืืฆืช ืื ืชืื ืื ImageNet ืขื 64 ืืืืืืช GPU ืขื ืฉืืื ื ืืืคืขืื p3.16xlarge ืืืืฆืขืืช ืฉืจืชื EC2, ืฉืื ืืื ืืื ืืืื ืฉืืื ื ืืขืืื GPU ืฉื NVIDIA Tesla V100 ืขื ืืื AWS Cloud, ืืฉืื ื ืชืคืืงืช ืืืืื ืฉื 45000 ืชืืื ืืช/ืฉื ืืื (ืืืืืจ, ืืกืคืจ ืืืืืืืช ืฉืืืื ื ืืฉื ืืื). ืืืืืื ืืืฉืื ืชืื 44 ืืงืืช ืืืืจ 90 ืชืงืืคืืช, ืขื ืืืืง ืืืคืืืืื ืฉื 75.7%.
ืืฉืืืื ื ืืืช ืืืืืื ืืืืืจ ืฉื MXNet ืืืืฆืขืืช ืฉืจืชื ืคืจืืืจืื ืขื ืืื 8, 16, 32 ื-64 ืืขืืืื ืืจืคืืื ืขื ืฉืจืช ืคืจืืืจ ืืืื ืืืืก ืฉืจืช-ืืขืืื ืฉื 1:1 ื-2:1, ืืืชืืื. ืืชืืฆืืืช ืืืฆืืืช ืืืืืจ 1 ืืืื. ืืขืืืืืช ืืฆืืจ ื-y ืืฉืืืื ืืืืฆืืืช ืืช ืืกืคืจ ืชืืื ืืช ืืืืืื ืืฉื ืืื, ืืืงืืืื ืืฆืืจ ื-y ืืืื ื ืืืืฆืืื ืืช ืืขืืืืช ืงื ื ืืืืื (ืืืืืจ, ืืืืก ืืื ืืชืคืืงื ืืคืืขื ืืชืคืืงื ืืืืืืืืืช). ืืคื ืฉื ืืชื ืืจืืืช, ืืืืจืช ืืกืคืจ ืืฉืจืชืื ืืฉืคืืขื ืขื ืืขืืืืช ืงื ื ืืืืื. ืขื ืฉืจืช ืคืจืืืจ ืืืื, ืืขืืืืช ืงื ื ืืืืื ืืืจืืช ื-38% ืขื 64 ืืขืืืื ืืจืคืืื. ืืื ืืืฉืื ืืช ืืืชื ืืขืืืืช ืงื ื ืืืื ืืื ืขื Horovod, ืืฉ ืืืืคืื ืืช ืืกืคืจ ืืฉืจืชืื ืืืืก ืืืกืคืจ ืืขืืืืื.

ืืืืจ 1. ืืฉืืืื ืืื ืืืืื ืืืืืจ ืืืืฆืขืืช MXNet ืขื Horovod ืืขื ืฉืจืช ืคืจืืืจืื
ืืืื 1 ืืืื ืืฉืืื ืืช ืืขืืืช ืืืืืืช ืืื ืืืคืข ืืขืช ืืคืขืืช ื ืืกืืืื ืขื 64 ืืขืืืื ืืจืคืืื. ืฉืืืืฉ ื-MXNet ืขื Horovod ืืกืคืง ืืช ืืชืคืืงื ืืืืื ืืืืชืจ ืืขืืืช ืื ืืืื ืืืืชืจ.

ืืืื 1. ืืฉืืืืช ืขืืืืืช ืืื Horovod ืืฉืจืช ืคืจืืืจืื ืขื ืืืก ืฉืจืช-ืืขืืื ืฉื 2:1.
ืฉืืืื ืืืชืจืืืช
ืืฉืืืื ืืืืื, ื ืจืื ืืื ืืืฆื ืืฉืืืจ ืืช ืชืืฆืืช ืืืืืื ืืืืืืจืช ืืืืฆืขืืช MXNet ื-Horovod. ืืืืืข ื ืืกืฃ ืขื ืืืืื ืืืืืจ ืขื MXNet, ืงืจืื .
ืฉืื 1
ืฆืืจ ืืฉืืื ืฉื ืืืคืขืื ืืืืืื ืืื ืขื MXNet ืืจืกื 1.4.0 ืืืขืื ื-Horovod ืืจืกื 0.16.0 ืืืขืื ืืื ืืืฉืชืืฉ ืืืืืื ืืืืืจ. ืชืฆืืจื ืื ืืืชืงืื ืืช ืืกืคืจืืืช ืืืืืื GPU. ืขืืืจ ืืืืคืขืื ืฉืื ื, ืืืจื ื Ubuntu 16.04 Linux, ืขื ืื ืื ืืชืงื GPU 396.44, CUDA 9.2, ืกืคืจืืืช cuDNN 7.2.1, NCCL communicator 2.2.13 ื-OpenMPI 3.1.1. ื ืืชื ืื ืืืฉืชืืฉ , ืืืฉืจ ืกืคืจืืืช ืืื ืืืจ ืืืชืงื ืืช ืืจืืฉ.
ืฉืื 2
ืฉืคืจื ืืช ืกืงืจืืคื ืืืืืื ืฉื MXNet ืฉืืื ืืขืืจืช ืืืฉืง ื-API ืฉื Horovod. ืืกืงืจืืคื ืฉืืืื, ืืืืืกืก ืขื ืืืฉืง ื-API ืฉื MXNet Gluon, ืืืื ืืฉืืฉ ืืชืื ืืช ืคืฉืืื. ืืฉืืจืืช ืืืืืืฉืืช ื ืืจืฉืืช ืื ืืืจ ืืฉ ืืื ืกืงืจืืคื ืืืืื ืชืืื. ืื ื ืืื ืฉืื ืืืื ืงืจืืืืื ืฉืขืืืื ืืืฆืข ืืื ืืืชืืื ืขื Horovod:
- ืืืืจ ืืช ืืืงืฉืจ ืื ืฉืืชืืื ืืืืจืื Horovod ืืืงืืื (ืฉืืจื 8) ืืื ืืืืืื ืฉืืืืืื ืืืืฆืข ืขื ืืืืช ื-GPU ืื ืืื ื.
- ืืขืืืจื ืคืจืืืจืื ืืชืืืชืืื ืืขืืื ืืื ืืืืื (ืฉืืจื 18) ืืื ืืืืืื ืฉืื ืืขืืืืื ืืชืืืื ืขื ืืืชื ืคืจืืืจืื ืืชืืืชืืื.
- ืฆืืจ ืืืจืืืื ืืืคืืืืืืฆืื ืืืืืจืช (ืฉืืจื 25) ืืื ืืขืืื ืืช ืืคืจืืืจืื ืืฆืืจื ืืืืืจืช.
ืืงืืืช ืืกืงืจืืคื ืืืื, ืื ื ืขืืื ื ืืืืืืืืช ืฉื Horovod-MXNet. ะธ .
1 import mxnet as mx
2 import horovod.mxnet as hvd
3
4 # Horovod: initialize Horovod
5 hvd.init()
6
7 # Horovod: pin a GPU to be used to local rank
8 context = mx.gpu(hvd.local_rank())
9
10 # Build model
11 model = ...
12
13 # Initialize parameters
14 model.initialize(initializer, ctx=context)
15 params = model.collect_params()
16
17 # Horovod: broadcast parameters
18 hvd.broadcast_parameters(params, root_rank=0)
19
20 # Create optimizer
21 optimizer_params = ...
22 opt = mx.optimizer.create('sgd', **optimizer_params)
23
24 # Horovod: wrap optimizer with DistributedOptimizer
25 opt = hvd.DistributedOptimizer(opt)
26
27 # Create trainer and loss function
28 trainer = mx.gluon.Trainer(params, opt, kvstore=None)
29 loss_fn = ...
30
31 # Train model
32 for epoch in range(num_epoch):
33 ...ืฉืื 3
ืืชืืืจ ืืืื ืื-workers ืืื ืืืจืืฅ ืืืืื ืืืืืจ ืืืืฆืขืืช ืืืจืืช MPI. ืืืืืื ืื, ืืืืื ืืืืืจ ืืืคืขื ืขื ืืจืืขื ืืืคืขืื ืขื ืืจืืขื GPU ืื ืืื, ืืกื ืืื 16 GPU ืืืฉืืื. ืืืขืฉื ืฉืืืืฉ ืืืืื ืกืืืืกืื ืฉื ืืจืืืื ื ืืืจื (SGD) ืขื ืืืืคืจ-ืคืจืืืจืื ืืืืื:
- ืืืื ืืื ื-ืืฆืืื: 256
- ืงืฆื ืืืืื: 0.1
- ืชื ืข: 0.9
- ืืขืืืช ืืฉืงื: 0.0001
ืืืฉืจ ืืืื ื ืืืขืื ืืจืคื ืืืื ื-64 ืืขืืืื ืืจืคืืื, ืฉืืจืื ื ืืช ืืืืจืืช ืืืืืื ืืืืคื ืืื ืืืจื ืขื ืืกืคืจ ืืืขืืืื ืืืจืคืืื (ื-0,1 ืขืืืจ ืืขืื ืืจืคื ืืื ื-6,4 ืขืืืจ 64 ืืขืืืื ืืจืคืืื) ืชืื ืฉืืืจื ืขื ืืกืคืจ ืืชืืื ืืช ืืื ืืขืื ืืจืคื ืขื 256 (ืืงืืืฆื ืฉื 256 ืชืืื ืืช ืขืืืจ ืืขืื ืืจืคื ืืื ื-16,384 ืขืืืจ 64 ืืขืืืื ืืจืคืืื). ืคืจืืืจื ืืขืืืช ืืืฉืงื ืืืชื ืข ืืืชืืื ืืื ืฉืืกืคืจ ืืืขืืืื ืืืจืคืืื ืืื. ืืฉืชืืฉื ื ืืืืืื ืืืืืง ืืขืืจื ืขื ืกืืื ื ืชืื ืื float16 ืขืืืจ ืืขืืจ ืงืืืื ื-float32 ืขืืืจ ืืจืืืื ืืื ืืื ืืืืืฅ ืืช ืืืฉืืื float16 ืื ืชืืืื ืขื ืืื ืืขืืื ืืจืคืืื ืฉื NVIDIA Tesla.
$ mpirun -np 16
-H server1:4,server2:4,server3:4,server4:4
-bind-to none -map-by slot
-mca pml ob1 -mca btl ^openib
python mxnet_imagenet_resnet50.pyืืกืงื ื
ืืืืืจ ืื, ืืื ื ืืืฉื ื ืืชื ืช ืืืจืืื ืืืืืื ืืืืืื ืืืืืจืื ืืืืฆืขืืช Apache MXNet ื-Horovod. ืืืืื ื ืืช ืืืืจืืืืช ืืืืขืืืืช ืืขืืืชืืช ืืืฉืืืื ืืืืฉืช ืฉืจืช ืคืจืืืจืื ืขื ืงืืืฆืช ืื ืชืื ืื ImageNet, ืืฉืจ ืฉืืืฉื ืืืืืื ืืืื ResNet50-v1. ืชืืืจื ื ืื ืืช ืืฉืืืื ืฉื ืืชื ืื ืงืื ืืื ืืฉื ืืช ืกืงืจืืคื ืงืืื ืืื ืืืจืืฅ ืืืืื ืขื ืืกืคืจ ืืืคืขืื ืืืืฆืขืืช Horovod.
ืื ืืชื ืจืง ืืชืืืืื ืขื MXNet ืืืืืื ืขืืืงื, ืืฉื ืืืฃ ืืืชืงื ื. , ืืื ืืื ืืช ืชืืืื ืืช MXNet. ืื ื ืืืืืฆืื ืืืื ืื ืืงืจืื ืืช ืืืืืจ ืืื ืืืชืืื.
ืื ืืืจ ืขืืืชื ืขื MXNet ืืจืืฆืื ืื ืกืืช ืืืืื ืืืืืจืช ืขื Horovod, ืืืงื ืืช , ืงืืืคืื ืืืชื ืขื MXNet ืืคืขื ืืคื ืืืืืื ืื .
*ืืขืืืช ืืืืฉืืช ืขื ืกืื AWS ืขืืืจ ืืืคืขื EC2
ืืืืืข ื ืืกืฃ ืขื ืืงืืจืก
ืืงืืจ: www.habr.com
