ืชืจืืื ืืืืืจ ืืืื ืขืจื ืชืืืืช ืืงืืจืก
ืืืฉืจื ืืืืืจืช ืืืกืคืจ ืืืคืขื ืืืฉืื ืืขืื ืืืฆืืขืื ืืืืืื ืืืืื ืืืคืืืช ืืช ืืื ืืืืืื ืฉื ืจืฉืชืืช ืขืฆืืืืช ืขืืืงืืช ืืืืจื ืืืช ืขื ืืืืืืช ืืืืืืช ืฉื ื ืชืื ืื ืืฉืืืขืืช ืืฉืขืืช ืื ืืคืืื ืืงืืช, ืื ืฉืืืคื ืืช ืืื ืืงืช ืืืืืื ืืื ืื ืคืืฆื ืืืืฉืืืื ืืขืฉืืื ืฉื ืืืืื ืขืืืงื. ืขื ืืืฉืชืืฉืื ืืืืื ืืืฆื ืืฉืชืฃ ืืืกื ืืจื ื ืชืื ืื ืขื ืคื ื ืืกืคืจ ืืืคืขืื, ืืฉืจ ืืชืืจื ืืฉ ืื ืืฉืคืขื ืืืืื ืขื ืืขืืืืช ืงื ื ืืืืื. ืื ืืกืฃ, ืขื ืืืฉืชืืฉืื ืืืขืช ืื ืืืฆื ืืคืจืืก ืกืงืจืืคื ืืืจืื ืฉืจืฅ ืขื ืืืคืข ืืืื ืืืกืคืจ ืืืคืขืื.
ืืืืืจ ืื ื ืืืจ ืขื ืืจื ืืืืจื ืืงืื ืืืคืฆืช ืืืืื ืืืืฆืขืืช ืกืคืจืืืช ืืืืืื ืืขืืืงื ืืคืชืืื Apache MXNet ืืืกืืจืช ืืืืืื ืืืืืืจืช Horovod. ื ืืืื ืืืืจืืจ ืืช ืืชืจืื ืืช ืืืืฆืืขืื ืฉื ืืกืืจืช Horovod ืื ืืืื ืืืฆื ืืืชืื ืกืงืจืืคื ืืืืื MXNet ืื ืฉืืขืืื ืืฆืืจื ืืืืืจืช ืขื Horovod.
ืื ืื Apache MXNet
ืืืจืื ืืืืืจืช ื-MXNet ืขื ืฉืจืช ืคืจืืืจืื
ืื ืื ืืืจืืืื
ืฉืืืื MXNet ื- Horovod
MXNet ืืฉืชืื ืขื Horovod ืืืืฆืขืืช ืืืฉืงื API ืฉื ืืืืื ืืืืืจืช ืืืืืืจืื ืืืืจืืืื. ืืืฉืงื API ืืชืงืฉืืจืช Horovod horovod.broadcast(), horovod.allgather() ะธ horovod.allreduce() ืืืืฉื ืืืืฆืขืืช ืืชืงืฉืจืืืืช ืืกืื ืืจืื ืืืช ืฉื ืื ืืข MXNet, ืืืืง ืืืจืฃ ืืืฉืืืืช ืฉืื. ืืืจื ืื, ืชืืืช ื ืชืื ืื ืืื ืชืงืฉืืจืช ืืืืฉืื ืืืืคืืช ืืงืืืช ืขื ืืื ืื ืืข MXNet ืืื ืืื ืืข ืืืืื ืืืฆืืขืื ืขืงื ืกื ืืจืื. ืืืืืืงื ืืืคืืืืืืฆืื ืืืืืจ ืฉืืืืืจ ืืืจืืืื horovod.DistributedOptimizer ืืชืจืื ืืืืื ื-MXNet ืื ืฉืืื ืงืืจื ืืืืฉืงื ื-API ืฉื Horovod ืืชืืืืื ืขืืืจ ืขืืืื ื ืคืจืืืจืื ืืืืืจืื. ืื ืคืจืื ืืืืืขื ืืืื ืฉืงืืคืื ืืืฉืชืืฉื ืืงืฆื.
ืืชืืื ืืืืจื
ืืชื ืืืื ืืืชืืื ืืืืืจืืช ืืืืฉืืจ ืจืฉืช ืขืฆืืืช ืงืื ืืืืืฆืืื ืืช ืงืื ื ืืืขืจื ืื ืชืื ืื ืฉื MNIST ืืืืฆืขืืช MXNet ื- Horovod ื-MacBook ืฉืื.
ืจืืฉืืช, ืืชืงื ืืช mxnet ืืืช horovod ื- PyPI:
pip install mxnet
pip install horovod
ืืขืจื: ืื ืืชื ื ืชืงื ืืฉืืืื ืืืืื pip ืืืชืงืื horovodืืืื ืืชื ืฆืจืื ืืืืกืืฃ ืืฉืชื ื MACOSX_DEPLOYMENT_TARGET=10.vvืืืคื vv โ ืื ืืืจืกื ืฉื ืืจืกืช ื-MacOS ืฉืื, ืืืฉื, ืขืืืจ MacOSX Sierra ืชืฆืืจื ืืืชืื MACOSX_DEPLOYMENT_TARGET=10.12 ืืชืงื ืช pip horovod
ืืืืจ ืืื ืืชืงื ืืช OpenMPI
ืืกืืฃ, ืืืจื ืืช ืกืงืจืืคื ืืืืืงื mxnet_mnist.py
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 GPUs ืขื ืฉืืื ื ืืืคืขืื p3.16xlarge EC2, ืฉืื ืืื ืืื ืืืื 8 GPUs NVIDIA Tesla V100 ืขื ืขื ื AWS, ืืฉืื ื ืชืคืืงืช ืืืืื ืฉื 45000 ืชืืื ืืช/ืฉื ืืื (ืืืืืจ, ืืกืคืจ ืืืืืืืช ืืืืืื ืืช ืืฉื ืืื). ืืืืืื ืืืฉืื ืชืื 44 ืืงืืช ืืืืจ 90 ืขืืื ืื ืขื ืืืืง ืืืืื ืฉื 75.7%.
ืืฉืืืื ื ืืืช ืืืืฉืช ืืืืจืื ืืืืืืจืช ืฉื MXNet ืฉื ืฉืืืืฉ ืืฉืจืชื ืคืจืืืจืื ืขื 8, 16, 32 ื-64 GPUs ืขื ืฉืจืช ืคืจืืืจ ืืืื ืืืืก ืฉืจืช ืืขืืื ืฉื 1 ื-1 ื-2 ื-1, ืืืชืืื. ืืชื ืืืื ืืจืืืช ืืช ืืชืืฆืื ืืืืืจ 1 ืืืื. ืืฆืืจ ื-y ืืฉืืื, ืืคืกืื ืืืืฆืืื ืืช ืืกืคืจ ืืชืืื ืืช ืืืืืื ืืฉื ืืื, ืืงืืืื ืืฉืงืคืื ืืช ืืขืืืืช ืงื ื ืืืืื (ืืืืืจ, ืืืืก ืืื ืืชืคืืงื ืืคืืขื ืืืืืืืืืช) ืืฆืืจ ื-y ืืืืื. ืืคื ืฉื ืืชื ืืจืืืช, ืืืืืจื ืืืกืคืจ ืืฉืจืชืื ืืฉืคืืขื ืขื ืืขืืืืช ืงื ื ืืืืื. ืื ืืฉ ืจืง ืฉืจืช ืคืจืืืจ ืืื, ืืขืืืืช ืงื ื ืืืืื ืืืจืืช ื-38% ื-64 GPUs. ืืื ืืืฉืื ืืช ืืืชื ืืขืืืืช ืงื ื ืืืื ืืื ืขื Horovod, ืขืืื ืืืืคืื ืืช ืืกืคืจ ืืฉืจืชืื ืืืืก ืืืกืคืจ ืืขืืืืื.
ืืืืจ 1. ืืฉืืืื ืฉื ืืืืื ืืืืืจืช ืืืืฆืขืืช MXNet ืขื Horovod ืืขื ืฉืจืช ืคืจืืืจืื
ืืืืื 1 ืืืื, ืื ื ืืฉืืืื ืืช ืืขืืืช ืืกืืคืืช ืืืืคืข ืืขืช ืืคืขืืช ื ืืกืืืื ืขื 64 GPUs. ืืฉืืืืฉ ื-MXNet ืขื Horovod ืืกืคืง ืืช ืืชืคืืงื ืืืืื ืืืืชืจ ืืขืืืช ืื ืืืื ืืืืชืจ.
ืืืื 1. ืืฉืืืืช ืขืืืืืช ืืื Horovod ื-Parameter Server ืขื ืืืก ืฉืจืช ืืขืืื ืฉื 2 ื-1.
ืฆืขืืื ืืฉืืืืจ
ืืฉืืืื ืืืืื, ื ืจืื ืื ืืืฆื ืืฉืืืจ ืืช ืืชืืฆืื ืฉื ืืืืื ืืืืืจ ืืืืฆืขืืช MXNet ื- Horovod. ืืืืืข ื ืืกืฃ ืขื ืืืืื ืืืืืจืช ืขื MXNet ืงืจื
ืฉืื 1
ืฆืืจ ืืฉืืื ืฉื ืืืคืขืื ืืืืืื ืืื ืขื MXNet ืืจืกื 1.4.0 ืืืขืื ื- Horovod ืืจืกื 0.16.0 ืืืขืื ืืื ืืืฉืชืืฉ ืืืืืื ืืืืืจืช. ืชืฆืืจื ืื ืืืชืงืื ืกืคืจืืืช ืขืืืจ ืืืืื GPU. ืขืืืจ ืืืงืจืื ืฉืื ื, ืืืจื ื ืืืืืื ืื 16.04 ืืื ืืงืก, ืขื ืื ืื ืืชืงื GPU 396.44, CUDA 9.2, ืกืคืจืืืช cuDNN 7.2.1, NCCL 2.2.13 communicator ื-OpenMPI 3.1.1. ืืื ืื ืืชื ืืืื ืืืฉืชืืฉ
ืฉืื 2
ืืืกืฃ ืืช ืืืืืืช ืืขืืื ืขื ื-API ืฉื Horovod ืืกืงืจืืคื ืืืืจืื ืฉืื ื-MXNet. ืืกืงืจืืคื ืฉืืืื ืืืืืกืก ืขื ื-API ืฉื MXNet Gluon ืืืื ืืฉืืฉ ืืชืื ืืช ืคืฉืืื. ืืฉืืจืืช ืืืืืืฉืืช ื ืืืฆืืช ืื ืืืจ ืืฉ ืื ืชืกืจืื ืืืจืื ืืชืืื. ืื ื ืืื ืฉืื ืืืื ืงืจืืืืื ืฉืขืืื ืืืฆืข ืืื ืืืืื ืขื Horovod:
- ืืืืจ ืืช ืืืงืฉืจ ืืืชืื ืืืจืืช Horovod ืืืงืืืืช (ืฉืืจื 8) ืืื ืืืืื ืฉืืืืืื ืืชืืฆืข ืขื ืืืืื ืืืจืคืืช ืื ืืื ื.
- ืืขืืจ ืคืจืืืจืื ืจืืฉืื ืืื ืืขืืื ืืื ืืืืื (ืฉืืจื 18) ืืื ืืืืืื ืฉืื ืืขืืืืื ืืชืืืื ืขื ืืืชื ืคืจืืืจืื ืจืืฉืื ืืื.
- ืฆืืจ ืืืจืืื DistributedOptimizer (ืฉืืจื 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
ืืืื ืก ืืืื ืืขืืืืื ืืื ืืืชืืื ืืืฉืจื ืืืืืจืช ืืืืฆืขืืช ืืืจืืช MPI. ืืืืืื ืื, ืืืืื ืืืืืจ ืคืืขื ืขื ืืจืืขื ืืืคืขืื ืขื 4 GPUs ืื ืืื, ืืืกื ืืื 16 GPUs ืืืฉืืื. ืืื ืืืืคืืืืืืฆืื ืฉื ืืจืืื ืืืจืื ืกืืืงืืกืืืช (SGD) ืืฉืืฉ ืขื ืืืืคืจืคืจืืืจืื ืืืืื:
- ืืืื ืืื ื ืืฆืืื: 256
- ืงืฆื ืืืืื: 0.1
- ืืืื ืืื: 0.9
- ืืขืืื ืืืฉืงื: 0.0001
ืืืฉืจ ืืจืืื ื ื-GPU ืืื ื-64 GPUs, ืืืืื ื ืืืืคื ืืื ืืืจื ืืช ืงืฆื ืืืืืื ืืืชืื ืืืกืคืจ ื-GPUs (ื-0,1 ืขืืืจ 1 GPU ื-6,4 ืขืืืจ 64 GPUs), ืชืื ืฉืืืจื ืขื ืืกืคืจ ืืชืืื ืืช ืืื GPU ืขื 256 (ืืงืืืฆื ืฉื 256 ืชืืื ืืช ืขืืืจ 1 GPU ืขื 16 ืขืืืจ 384 GPUs). ืคืจืืืจื ืืขืืืช ืืืฉืงื ืืืืืื ืืื ืืฉืชื ื ืืื ืฉืืกืคืจ ื-GPUs ืืื. ืืฉืชืืฉื ื ืืืืืื ืืืืง ืืขืืจื ืขื ืกืื ืื ืชืื ืื float64 ืขืืืจ ืืขืืจ ืงืืืื ื-float16 ืขืืืจ ืฉืืคืืขืื ืืื ืืืืืฅ ืืช ืืืฉืืื float32 ืื ืชืืืื ืขื ืืื NVIDIA Tesla GPUs.
$ 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 ืืืจืฆืื ื ืื ืกืืช ืืืืื ืืืืืจืช ืขื Horovod, ืชืกืชืื ืขื
*ืืขืืืช ืืืืฉืืช ืขื ืกืื
ืืืืืข ื ืืกืฃ ืขื ืืงืืจืก
ืืงืืจ: www.habr.com