ΠΠ΅ΡΠ΅Π²ΠΎΠ΄ ΡΡΠ°ΡΡΠΈ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²Π»Π΅Π½ Π² ΠΏΡΠ΅Π΄Π΄Π²Π΅ΡΠΈΠΈ ΡΡΠ°ΡΡΠ° ΠΊΡΡΡΠ°
Π Π°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠ΅ Π½Π° Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ Π²ΡΡΠΎΠΊΠΎΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΡΡ Π²ΡΡΠΈΡΠ»ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°Ρ ΠΌΠΎΠΆΠ΅Ρ ΡΠΎΠΊΡΠ°ΡΠΈΡΡ Π²ΡΠ΅ΠΌΡ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ Π³Π»ΡΠ±ΠΎΠΊΠΈΡ Π½Π΅ΠΉΡΠΎΠ½Π½ΡΡ ΡΠ΅ΡΠ΅ΠΉ Π½Π° Π±ΠΎΠ»ΡΡΠΎΠΌ ΠΎΠ±ΡΠ΅ΠΌΠ΅ Π΄Π°Π½Π½ΡΡ Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ Π½Π΅Π΄Π΅Π»Ρ Π΄ΠΎ ΡΠ°ΡΠΎΠ² ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ ΠΌΠΈΠ½ΡΡ, ΡΡΠΎ Π΄Π΅Π»Π°Π΅Ρ ΡΡΡ ΡΠ΅Ρ Π½ΠΈΠΊΡ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ ΠΏΡΠ΅Π²Π°Π»ΠΈΡΡΡΡΠ΅ΠΉ Π² Π²ΠΎΠΏΡΠΎΡΠ°Ρ ΠΏΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ Π³Π»ΡΠ±ΠΎΠΊΠΎΠ³ΠΎ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ. ΠΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠ½ΠΈΠΌΠ°ΡΡ, ΠΊΠ°ΠΊ Π΄Π΅Π»ΠΈΡΡΡΡ ΠΈ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ Π΄Π°Π½Π½ΡΠ΅ Π½Π° Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°Ρ , ΡΡΠΎ Π² ΡΠ²ΠΎΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π±ΠΎΠ»ΡΡΠΎΠ΅ Π²Π»ΠΈΡΠ½ΠΈΠ΅ Π½Π° ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΡ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΡ. ΠΠΎΠΌΠΈΠΌΠΎ ΡΡΠΎΠ³ΠΎ, ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΠΈ ΡΠ°ΠΊΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ Π·Π½Π°ΡΡ, ΠΊΠ°ΠΊ ΡΠ°Π·Π²Π΅ΡΠ½ΡΡΡ Π½Π° Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°Ρ ΠΎΠ±ΡΡΠ°ΡΡΠΈΠΉ ΡΠΊΡΠΈΠΏΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π½Π° ΠΎΠ΄Π½ΠΎΠΌ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ΅.
Π ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ ΠΌΡ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡΠΈΠΌ ΠΏΡΠΎ Π±ΡΡΡΡΡΠΉ ΠΈ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠΏΠΎΡΠΎΠ± ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΎΡΠΊΡΡΡΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π΄Π»Ρ Π³Π»ΡΠ±ΠΎΠΊΠΎΠ³ΠΎ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ Apache MXNet ΠΈ ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊΠ° ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ Horovod. ΠΡ Π½Π°Π³Π»ΡΠ΄Π½ΠΎ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π° ΡΡΠ΅ΠΉΠΌΡΠΎΡΠΊΠ° Horovod Π² Π²ΠΎΠΏΡΠΎΡΠ°Ρ
ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΈ ΠΏΡΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΠ΅ΠΌ, ΠΊΠ°ΠΊ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΠΎΠ±ΡΡΠ°ΡΡΠΈΠΉ ΡΠΊΡΠΈΠΏΡ MXNet ΡΠ°ΠΊ, ΡΡΠΎΠ±Ρ ΠΎΠ½ ΡΠ°Π±ΠΎΡΠ°Π» ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎ Ρ Horovod.
Π§ΡΠΎ ΡΠ°ΠΊΠΎΠ΅ Apache MXNet
Π Π°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠ΅ Π² MXNet Ρ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ²
Π§ΡΠΎ ΡΠ°ΠΊΠΎΠ΅ Horovod
ΠΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ MXNet ΠΈ Horovod
MXNet ΠΈΠ½ΡΠ΅Π³ΡΠΈΡΡΠ΅ΡΡΡ Ρ Horovod ΡΠ΅ΡΠ΅Π· API ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ, ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠ΅ Π² Horovod. Π Horovod ΠΊΠΎΠΌΠΌΡΠ½ΠΈΠΊΠ°ΡΠΈΠΎΠ½Π½ΡΠ΅ API horovod.broadcast(), horovod.allgather() ΠΈ horovod.allreduce() ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΡΡ ΠΊΠΎΠ»Π»Π±ΡΠΊΠΎΠ² Π΄Π²ΠΈΠΆΠΊΠ° MXNet, ΠΊΠ°ΠΊ ΡΠ°ΡΡΡ Π΅Π³ΠΎ Π³ΡΠ°ΡΠ° Π·Π°Π΄Π°Ρ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ Π΄Π°Π½Π½ΡΡ ΠΌΠ΅ΠΆΠ΄Ρ ΠΊΠΎΠΌΠΌΡΠ½ΠΈΠΊΠ°ΡΠΈΠ΅ΠΉ ΠΈ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡΠΌΠΈ Ρ Π»Π΅Π³ΠΊΠΎΡΡΡΡ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡΡΡ Π΄Π²ΠΈΠΆΠΊΠΎΠΌ MXNet, ΡΡΠΎΠ±Ρ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΠΏΠΎΡΠ΅ΡΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΈΠ·-Π·Π° ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ. ΠΠ±ΡΠ΅ΠΊΡ distributed optimizer, ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΉ Π² Horovod horovod.DistributedOptimizer ΡΠ°ΡΡΠΈΡΡΠ΅Ρ Optimizer Π² MXNet ΡΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΡΡΠΎΠ±Ρ ΠΎΠ½ Π²ΡΠ·ΡΠ²Π°Π» ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ API Horovod Π΄Π»Ρ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ². ΠΡΠ΅ ΡΡΠΈ Π΄Π΅ΡΠ°Π»ΠΈ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΡΠΎΠ·ΡΠ°ΡΠ½Ρ Π΄Π»Ρ ΠΊΠΎΠ½Π΅ΡΠ½ΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ.
ΠΡΡΡΡΡΠΉ ΡΡΠ°ΡΡ
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π±ΡΡΡΡΠΎ Π½Π°ΡΠ°ΡΡ ΠΎΠ±ΡΡΠ°ΡΡ Π½Π΅Π±ΠΎΠ»ΡΡΡΡ ΡΠ²Π΅ΡΡΠΎΡΠ½ΡΡ Π½Π΅ΠΉΡΠΎΠ½Π½ΡΡ ΡΠ΅ΡΡ Π½Π° Π½Π°Π±ΠΎΡΠ΅ Π΄Π°Π½Π½ΡΡ
MNIST Ρ ΠΏΠΎΠΌΠΎΡΡΡ MXNet ΠΈ Horovod Π½Π° Π²Π°ΡΠ΅ΠΌ MacBook.
ΠΠ»Ρ Π½Π°ΡΠ°Π»Π° ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ mxnet ΠΈ horovod ΠΈΠ· PyPI:
pip install mxnet
pip install horovod
ΠΡΠΈΠΌΠ΅ΡΠ°Π½ΠΈΠ΅: ΠΡΠ»ΠΈ Ρ Π²Π°Ρ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ ΠΎΡΠΈΠ±ΠΊΠ° Π²ΠΎ Π²ΡΠ΅ΠΌΡ pip install horovod, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π²Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ MACOSX_DEPLOYMENT_TARGET=10.vv, Π³Π΄Π΅ vv β ΡΡΠΎ Π²Π΅ΡΡΠΈΡ Π²Π°ΡΠ΅ΠΉ Π²Π΅ΡΡΠΈΠΈ MacOS, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π»Ρ MacOSX Sierra Π½ΡΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ Π½Π°ΠΏΠΈΡΠ°ΡΡ MACOSX_DEPLOYMENT_TARGET=10.12 pip install 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 GPU Ρ Π²ΠΎΡΠ΅ΠΌΡΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°ΠΌΠΈ p3.16xlarge EC2, ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· ΠΊΠΎΡΠΎΡΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ 8 GPU NVIDIA Tesla V100 Π½Π° AWS cloud, ΠΌΡ Π΄ΠΎΡΡΠΈΠ³Π»ΠΈ ΠΏΡΠΎΠΏΡΡΠΊΠ½ΠΎΠΉ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΠΈ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ 45000 ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ/ΡΠ΅ΠΊ (Ρ.Π΅. ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΎΠ±ΡΡΠ΅Π½Π½ΡΡ ΡΡΠΌΠΏΠ»ΠΎΠ² Π² ΡΠ΅ΠΊΡΠ½Π΄Ρ). ΠΠ±ΡΡΠ΅Π½ΠΈΠ΅ Π·Π°Π²Π΅ΡΡΠ°Π»ΠΎΡΡ Π·Π° 44 ΠΌΠΈΠ½ΡΡΡ ΠΏΠΎΡΠ»Π΅ 90 ΡΠΏΠΎΡ Ρ Π»ΡΡΡΠ΅ΠΉ ΡΠΎΡΠ½ΠΎΡΡΡΡ Π² 75.7%.
ΠΡ ΡΡΠ°Π²Π½ΠΈΠ»ΠΈ ΡΡΠΎ Ρ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΌ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠ΅ΠΌ MXNet Ρ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΠ΅ΡΠ²Π΅ΡΠΎΠ² ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² Π½Π° 8, 16, 32 ΠΈ 64 GPU Ρ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ Ρ ΠΎΠ΄Π½ΠΈΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠΌ ΠΈ ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΠ΅ΡΠ²Π΅ΡΠΎΠ² ΠΊ Π²ΠΎΡΠΊΠ΅ΡΠ°ΠΌ 1 ΠΊ 1 ΠΈ 2 ΠΊ 1 ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ. Π Π΅Π·ΡΠ»ΡΡΠ°Ρ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ²ΠΈΠ΄Π΅ΡΡ Π½Π° Π ΠΈΡΡΠ½ΠΊΠ΅ 1 Π½ΠΈΠΆΠ΅. ΠΠΎ ΠΎΡΠΈ y ΡΠ»Π΅Π²Π° ΡΡΠΎΠ»Π±ΡΡ ΠΎΡΡΠ°ΠΆΠ°ΡΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Π΄Π»Ρ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ Π² ΡΠ΅ΠΊΡΠ½Π΄Ρ, Π»ΠΈΠ½ΠΈΠΈ ΠΎΡΡΠ°ΠΆΠ°ΡΡ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΡ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΡ (ΡΠΎ Π΅ΡΡΡ ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠ΅ ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΏΡΠΎΠΏΡΡΠΊΠ½ΠΎΠΉ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΠΈ ΠΊ ΠΈΠ΄Π΅Π°Π»ΡΠ½ΠΎΠΉ) Π½Π° ΠΎΡΠΈ y ΡΠΏΡΠ°Π²Π°. ΠΠ°ΠΊ Π²ΠΈΠ΄ΠΈΡΠ΅ Π²ΡΠ±ΠΎΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° ΡΠ΅ΡΠ²Π΅ΡΠΎΠ² ΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π²Π»ΠΈΡΠ½ΠΈΠ΅ Π½Π° ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΡ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΡ. ΠΡΠ»ΠΈ ΡΠ΅ΡΠ²Π΅Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΎΠ΄ΠΈΠ½, ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΡ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΠ°Π΄Π°Π΅Ρ Π΄ΠΎ 38% Π½Π° 64 GPU. ΠΠ»Ρ Π΄ΠΎΡΡΠΈΠΆΠ΅Π½ΠΈΡ ΡΠ°ΠΊΠΎΠΉ ΠΆΠ΅ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΊΠ°ΠΊ Ρ Horovod Π½ΡΠΆΠ½ΠΎ ΡΠ²Π΅Π»ΠΈΡΠΈΡΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠ΅ΡΠ²Π΅ΡΠΎΠ² Π² Π΄Π²Π° ΡΠ°Π·Π° ΠΏΠΎ ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΡ ΠΊ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Ρ Π²ΠΎΡΠΊΠ΅ΡΠΎΠ².
Π ΠΈΡΡΠ½ΠΎΠΊ 1. Π‘ΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ MXNet Ρ Horovod ΠΈ Ρ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ²
Π Π’Π°Π±Π»ΠΈΡΠ΅ 1 Π½ΠΈΠΆΠ΅ ΠΌΡ ΡΡΠ°Π²Π½ΠΈΠ»ΠΈ ΠΈΡΠΎΠ³ΠΎΠ²ΡΡ ΡΡΠΎΠΈΠΌΠΎΡΡΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° ΠΏΡΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΎΠ² Π½Π° 64 GPU. ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ MXNet Π²ΠΌΠ΅ΡΡΠ΅ Ρ Horovod ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ Π½Π°ΠΈΠ»ΡΡΡΡΡ ΠΏΡΠΎΠΏΡΡΠΊΠ½ΡΡ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΡ ΠΏΡΠΈ Π½Π°ΠΈΠΌΠ΅Π½ΡΡΠΈΡ Π·Π°ΡΡΠ°ΡΠ°Ρ .
Π’Π°Π±Π»ΠΈΡΠ° 1. Π‘ΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ Π·Π°ΡΡΠ°Ρ ΠΌΠ΅ΠΆΠ΄Ρ Horovod ΠΈ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² Ρ ΡΠΎΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΠ΅ΡΠ²Π΅ΡΠΎΠ² ΠΊ Π²ΠΎΡΠΊΠ΅ΡΠ°ΠΌ 2 ΠΊ 1.
Π¨Π°Π³ΠΈ Π΄Π»Ρ Π²ΠΎΡΠΏΡΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΡ
Π ΡΠ»Π΅Π΄ΡΡΡΠΈΡ
ΡΠ°Π³Π°Ρ
ΠΌΡ ΡΠ°ΡΡΠΊΠ°ΠΆΠ΅ΠΌ, ΠΊΠ°ΠΊ Π²ΠΎΡΠΏΡΠΎΠΈΠ·Π²Π΅ΡΡΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ MXNet ΠΈ Horovod. Π§ΡΠΎΠ±Ρ ΡΠ·Π½Π°ΡΡ Π±ΠΎΠ»ΡΡΠ΅ ΠΎ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠΈ Ρ MXNet ΠΏΡΠΎΡΠΈΡΠ°ΠΉΡΠ΅
Π¨Π°Π³ 1
Π‘ΠΎΠ·Π΄Π°ΠΉΡΠ΅ ΠΊΠ»Π°ΡΡΠ΅Ρ ΠΎΠ΄Π½ΠΎΡΠΎΠ΄Π½ΡΡ
ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² Ρ MXNet Π²Π΅ΡΡΠΈΠΈ 1.4.0 ΠΈΠ»ΠΈ Π²ΡΡΠ΅ ΠΈ Horovod Π²Π΅ΡΡΠΈΠΈ 0.16.0 ΠΈΠ»ΠΈ Π²ΡΡΠ΅, ΡΡΠΎΠ±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠ΅. ΠΠ°ΠΌ ΡΠ°ΠΊΠΆΠ΅ Π½ΡΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π΄Π»Ρ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ Π½Π° GPU. ΠΠ»Ρ Π½Π°ΡΠΈΡ
ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² ΠΌΡ Π²ΡΠ±ΡΠ°Π»ΠΈ Ubuntu 16.04 Linux, Ρ GPU Driver 396.44, CUDA 9.2, Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ cuDNN 7.2.1, ΠΊΠΎΠΌΠΌΡΠ½ΠΈΠΊΠ°ΡΠΎΡ NCCL 2.2.13 ΠΈ OpenMPI 3.1.1. Π’Π°ΠΊΠΆΠ΅ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
Π¨Π°Π³ 2
ΠΠΎΠ±Π°Π²ΡΡΠ΅ Π² ΡΠ²ΠΎΠΉ ΠΎΠ±ΡΡΠ°ΡΡΠΈΠΉ ΡΠΊΡΠΈΠΏΡ MXNet Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΠ°Π±ΠΎΡΡ Ρ API Horovod. ΠΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΡΠΉ Π½ΠΈΠΆΠ΅ ΡΠΊΡΠΈΠΏΡ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ MXNet Gluon API ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΊΠ°ΠΊ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠ°Π±Π»ΠΎΠ½. Π‘ΡΡΠΎΠΊΠΈ, Π²ΡΠ΄Π΅Π»Π΅Π½Π½ΡΠ΅ ΠΆΠΈΡΠ½ΡΠΌ, Π½ΡΠΆΠ½Ρ Π² ΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅, Π΅ΡΠ»ΠΈ Ρ Π²Π°Ρ ΡΠΆΠ΅ Π΅ΡΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ ΠΎΠ±ΡΡΠ°ΡΡΠΈΠΉ ΡΠΊΡΠΈΠΏΡ. ΠΠΎΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π²Π½Π΅ΡΡΠΈ Π΄Π»Ρ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ Ρ Horovod:
- Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ Π² ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠΈ Ρ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠΌ ΡΠ°Π½Π³ΠΎΠΌ Horovod (ΡΡΡΠΎΠΊΠ° 8), ΡΡΠΎΠ±Ρ ΠΏΠΎΠ½ΠΈΠΌΠ°ΡΡ, ΡΡΠΎ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠ΅ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π½Π° ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠΌ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠΌ ΡΠ΄ΡΠ΅.
- ΠΠ΅ΡΠ΅Π΄Π°ΠΉΡΠ΅ Π½Π°ΡΠ°Π»ΡΠ½ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΎΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π²ΠΎΡΠΊΠ΅ΡΠ° ΠΊΠΎ Π²ΡΠ΅ΠΌ (ΡΡΡΠΎΠΊΠ° 18), ΡΡΠΎΠ±Ρ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ, ΡΡΠΎ Π²ΡΠ΅ Π²ΠΎΡΠΊΠ΅ΡΡ Π½Π°ΡΠΈΠ½Π°ΡΡ ΡΠ°Π±ΠΎΡΡ Ρ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΡΠΌΠΈ Π½Π°ΡΠ°Π»ΡΠ½ΡΠΌΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ.
- Π‘ΠΎΠ·Π΄Π°ΠΉΡΠ΅ Horovod 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 GPU Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ, ΠΈ Ρ 16 GPU Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ ΠΏΠΎ ΠΈΡΠΎΠ³Ρ. ΠΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΎΡ ΡΡΠΎΡ Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ Π³ΡΠ°Π΄ΠΈΠ΅Π½ΡΠ½ΠΎΠ³ΠΎ ΡΠΏΡΡΠΊΠ° (SGD) ΡΠΎ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌΠΈ Π³ΠΈΠΏΠ΅ΡΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ:
- mini-batch size: 256
- learning rate: 0.1
- momentum: 0.9
- weight decay: 0.0001
ΠΠΎ ΠΌΠ΅ΡΠ΅ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΎΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ GPU ΠΊ 64 GPU ΠΌΡ Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π»ΠΈ ΡΠΊΠΎΡΠΎΡΡΡ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ Π² ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠΈ Ρ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎΠΌ GPU (ΠΎΡ 0,1 Π΄Π»Ρ 1 GPU Π΄ΠΎ 6,4 Π΄Π»Ρ 64 GPU), ΡΠΎΡ ΡΠ°Π½ΡΡ ΠΏΡΠΈ ΡΡΠΎΠΌ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ, ΠΏΡΠΈΡ ΠΎΠ΄ΡΡΠΈΡ ΡΡ Π½Π° ΠΎΠ΄ΠΈΠ½ GPU, ΡΠ°Π²Π½ΡΠΌ 256 (ΠΎΡ ΠΏΠ°ΠΊΠ΅ΡΠ° Π² 256 ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Π΄Π»Ρ 1 GPU Π΄ΠΎ 16 384 Π΄Π»Ρ 64 GPU). ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ weight decay ΠΈ momentum ΠΈΠ·ΠΌΠ΅Π½ΡΠ»ΠΈΡΡ ΠΏΠΎ ΠΌΠ΅ΡΠ΅ ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ΠΈΡ ΡΠΈΡΠ»Π° GPU. ΠΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΠΈ ΡΠΌΠ΅ΡΠ°Π½Π½ΡΡ ΡΠΎΡΠ½ΠΎΡΡΡ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ Ρ ΡΠΈΠΏΠΎΠΌ Π΄Π°Π½Π½ΡΡ float16 ΠΏΡΠΈ ΠΏΡΡΠΌΠΎΠΌ ΠΏΡΠΎΡ ΠΎΠ΄Π΅ ΠΈ float32 Π΄Π»Ρ Π³ΡΠ°Π΄ΠΈΠ΅Π½ΡΠΎΠ², ΡΡΠΎΠ±Ρ ΡΡΠΊΠΎΡΠΈΡΡ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ float16, ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΠ΅ GPU 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 ΠΈ Ρ
ΠΎΡΠΈΡΠ΅ ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°ΡΡ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠ΅ Ρ Horovod, ΡΠΎ Π·Π°Π³Π»ΡΠ½ΠΈΡΠ΅ Π½Π°
*ΡΡΠΎΠΈΠΌΠΎΡΡΡ ΡΠ°ΡΡΡΠΈΡΡΠ²Π°Π΅ΡΡΡ Π½Π° ΠΎΡΠ½ΠΎΠ²Π°Π½ΠΈΠΈ
Π£Π·Π½Π°ΡΡ ΠΏΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅ ΠΎ ΠΊΡΡΡΠ΅
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com