Rozproszone uczenie się z Apache MXNet i Horovod

Przekład artykułu przygotowany przed rozpoczęciem kursu „Przemysłowy ML na dużych danych“

Rozproszone uczenie na wielu do wysokiej wydajności instancjach obliczeniowych może skrócić czas uczenia nowoczesnych głębokich sieci neuronowych na dużych zbiorach danych z kilku tygodni do godzin, a nawet minut, co czyni tę technikę uczenia dominującą w praktycznym wykorzystaniu głębokiego uczenia. Użytkownicy muszą zrozumieć, jak dzielić się i synchronizować dane na wielu instancjach, co z kolei ma duży wpływ na efektywność skalowania. Oprócz tego użytkownicy muszą również wiedzieć, jak wdrożyć na wielu instancjach skrypt treningowy, który działa na jednej instancji.

W tym artykule omówimy szybki i prosty sposób rozproszonego uczenia przy użyciu otwartej biblioteki dla głębokiego uczenia Apache MXNet oraz frameworka rozproszonego uczenia Horovod. Zademonstrujemy zalety frameworka Horovod pod względem wydajności oraz pokażemy, jak napisać skrypt treningowy MXNet, aby działał rozproszony z Horovod.

Co to jest Apache MXNet

Apache MXNet – otwarty framework dla głębokiego uczenia, który służy do tworzenia, uczenia i wdrażania głębokich sieci neuronowych. MXNet abstrahuje problemy związane z implementacją sieci neuronowych, charakteryzuje się wysoką wydajnością i skalowalnością, a także oferuje API dla popularnych języków programowania, takich jak Python, C++, Clojure, Java, Julia, R, Scala i innych.

Rozproszone uczenie w MXNet z serwerem parametrów

Standardowy moduł rozproszonego uczenia w MXNet zastosowuje podejście serwera parametrów (parameter server). Wykorzystuje zestaw serwerów parametrów do zbierania gradientów z każdego robota, wykonywania agregacji i wysyłania zaktualizowanych gradientów z powrotem do robotów do następnej iteracji optymalizacji. Ustalenie właściwego stosunku serwerów do robotów to klucz do efektywnego skalowania. Jeśli jest tylko jeden serwer parametrów, może to stać się wąskim gardłem w przeprowadzaniu obliczeń. Z drugiej strony, jeśli jest zbyt wiele serwerów, połączenie „wielu-do-wielu” może zablokować wszystkie połączenia sieciowe.

Co to jest Horovod

Horovod – otwarty framework rozproszonego głębokiego uczenia, opracowany w Uberze. Wykorzystuje efektywne technologie komunikacji między wieloma GPU i węzłami, takie jak NVIDIA Collective Communications Library (NCCL) i Message Passing Interface (MPI), do rozdzielania i agregowania parametrów modelu między węzłami. Optymalizuje wykorzystanie przepustowości sieci i dobrze skalowalnie działa z modelami głębokich sieci neuronowych. Obecnie obsługuje kilka popularnych frameworków uczenia maszynowego, a mianowicie MXNet, Tensorflow, Keras i PyTorch.

Integracja MXNet i Horovod

MXNet integruje się z Horovod za pomocą API rozproszonego uczenia, określonego w Horovod. W Horovod komunikacyjne API horovod.broadcast(), horovod.allgather() i horovod.allreduce() są realizowane za pomocą asynchronicznych callbacków silnika MXNet, jako część jego grafu zadań. W ten sposób zależności danych między komunikacją a obliczeniami są łatwo przetwarzane przez silnik MXNet, aby uniknąć strat wydajności z powodu synchronizacji. Obiekt distributed optimizer, określony w Horovod horovod.DistributedOptimizer rozszerza Optimizer w MXNet w taki sposób, że wywołuje odpowiednie API Horovod do rozproszonej aktualizacji parametrów. Wszystkie te szczegóły implementacji są przejrzyste dla użytkowników końcowych.

Szybki start

Możesz szybko zacząć uczyć małą konwolucyjną sieć neuronową na zbiorze danych MNIST z użyciem MXNet i Horovod na swoim MacBooku.
Aby zacząć, zainstaluj mxnet i horovod z PyPI:

pip install mxnet
pip install horovod

Uwaga: Jeśli pojawi się błąd podczas pip install horovod, być może będziesz musiał dodać zmienną MACOSX_DEPLOYMENT_TARGET=10.vv, gdzie vv – to wersja twojego systemu operacyjnego MacOS, na przykład dla MacOSX Sierra trzeba będzie wpisać MACOSX_DEPLOYMENT_TARGET=10.12 pip install horovod

Następnie zainstaluj OpenMPI stąd.

Na koniec pobierz skrypt testowy mxnet_mnist.py stąd i wykonaj następujące polecenia w terminalu MacBooka w roboczej katalogu:

mpirun -np 2 -H localhost:2 -bind-to none -map-by slot python mxnet_mnist.py

W ten sposób uruchomisz trening na dwóch rdzeniach swojego procesora. Oto wynik:

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

Demonstracja wydajności

Podczas treningu modelu ResNet50-v1 na zbiorze danych ImageNet na 64 GPU z ośmioma instancjami p3.16xlarge EC2, z których każdy zawiera 8 GPU NVIDIA Tesla V100 w chmurze AWS, osiągnęliśmy przepustowość uczenia wynoszącą 45000 obrazów/s (tj. liczbę wprowadzonych próbek na sekundę). Uczenie kończyło się po 44 minutach po 90 epokach z najlepszą dokładnością wynoszącą 75,7%.

Porównaliśmy to z rozproszonym uczeniem MXNet przy podejściu wykorzystującym serwery parametrów przy 8, 16, 32 i 64 GPU z serwerem z jednym parametrem oraz stosunkiem serwerów do pracowników wynoszącym 1 do 1 i 2 do 1 odpowiednio. Wynik można zobaczyć na Rysunku 1 poniżej. Na osi y po lewej słupki odzwierciedlają liczbę obrazów do uczenia na sekundę, a linie odzwierciedlają efektywność skalowania (tj. stosunek rzeczywistej przepustowości do idealnej) na osi y po prawej. Jak widać, wybór liczby serwerów wpływa na efektywność skalowania. Jeśli serwer parametrów jest jeden, efektywność skalowania spada do 38% przy 64 GPU. Aby osiągnąć taką samą efektywność skalowania jak z Horovod, trzeba zwiększyć liczbę serwerów dwukrotnie w stosunku do liczby pracowników.

Rozproszone uczenie się z Apache MXNet i Horovod
Rysunek 1. Porównanie rozproszonego uczenia z wykorzystaniem MXNet z Horovod oraz z serwerem parametrów.

W Tabeli 1 poniżej porównaliśmy ostateczny koszt instancji przy przeprowadzaniu eksperymentów na 64 GPU. Użycie MXNet wraz z Horovod zapewnia najlepszą przepustowość przy najniższych kosztach.

Rozproszone uczenie się z Apache MXNet i Horovod
Tabela 1. Porównanie kosztów między Horovod a serwerem parametrów przy stosunku serwerów do pracowników wynoszącym 2 do 1.

Kroki do reprodukcji

W następnych krokach opiszemy, jak odtworzyć rezultat rozproszonego uczenia z użyciem MXNet i Horovod. Aby dowiedzieć się więcej o rozproszonym uczeniu z MXNet, przeczytaj ten post..

Krok 1

Utwórz klaster jednorodnych instancji z MXNet w wersji 1.4.0 lub wyższej i Horovod w wersji 0.16.0 lub wyższej, aby wykorzystać rozproszone uczenie. Będziesz również musiał zainstalować biblioteki do nauki na GPU. Dla naszych instancji wybraliśmy Ubuntu 16.04 Linux, z Driverem GPU 396.44, CUDA 9.2, biblioteką cuDNN 7.2.1, łącznikiem NCCL 2.2.13 i OpenMPI 3.1.1. Możesz także skorzystać z Amazon Deep Learning AMI, gdzie te biblioteki są już preinstalowane.

Krok 2

Dodaj możliwość korzystania z API Horovod w swoim skrypcie szkoleniowym MXNet. Poniższy skrypt bazujący na API MXNet Gluon można wykorzystać jako prosty szablon. Wyróżnione na grubą czcionkę linie są wymagane, jeśli masz już odpowiedni skrypt szkoleniowy. Oto kilka istotnych zmian, które należy wprowadzić, aby rozpocząć szkolenie z Horovod:

  • Ustal kontekst zgodnie z lokalnym rangi Horovod (linia 8), aby upewnić się, że szkolenie odbywa się na właściwym rdzeniu graficznym.
  • Przekaż początkowe parametry od jednego worker’a do wszystkich (linia 18), aby zapewnić, że wszystkie workery zaczynają pracę z tymi samymi początkowymi parametrami.
  • Utwórz Horovod DistributedOptimizer (linia 25), aby zaktualizować parametry w sposób rozproszony.

Aby uzyskać pełny skrypt, zapoznaj się z przykładami Horovod-MXNet MNIST i ImageNet.

1  import mxnet as mx
2  import horovod.mxnet as hvd
3
4  # Horovod: inicjalizacja Horovod
5  hvd.init()
6
7  # Horovod: przypisz GPU do lokalnego rangi
8  context = mx.gpu(hvd.local_rank())
9
10 # Buduj model
11 model = ...
12
13 # Inicjalizuj parametry
14 model.initialize(initializer, ctx=context)
15 params = model.collect_params()
16
17 # Horovod: broadcastuj parametry
18 hvd.broadcast_parameters(params, root_rank=0)
19
20 # Utwórz optymalizator
21 optimizer_params = ...
22 opt = mx.optimizer.create('sgd', **optimizer_params)
23
24 # Horovod: opakuj optymalizator za pomocą DistributedOptimizer
25 opt = hvd.DistributedOptimizer(opt)
26
27 # Utwórz trenera i funkcję kosztu
28 trainer = mx.gluon.Trainer(params, opt, kvstore=None)
29 loss_fn = ...
30
31 # Szkolenie modelu
32 for epoch in range(num_epoch):
33    ...

Krok 3

Zaloguj się na jeden z workerów, aby uruchomić rozproszone szkolenie za pomocą dyrektywy MPI. W tym przykładzie rozproszone szkolenie uruchamiane jest na czterech instancjach z 4 GPU w każdej, co daje łącznie 16 GPU w klastrze. Użyty zostanie optymalizator stochastycznego spadku gradientu (SGD) z następującymi hiperparametrami:

  • rozmiar mini-batcha: 256
  • wskaźnik uczenia: 0.1
  • momentum: 0.9
  • spadek wagi: 0.0001

W miarę skalowania z jednego GPU do 64 GPU liniowo zwiększyliśmy wskaźnik uczenia proporcjonalnie do liczby GPU (od 0,1 dla 1 GPU do 6,4 dla 64 GPU), zachowując jednocześnie liczbę obrazów przypadających na jeden GPU na poziomie 256 (z batcha 256 obrazów dla 1 GPU do 16 384 dla 64 GPU). Parametry spadku wagi i momentum ulegały zmianom wraz z rosnącą liczbą GPU. Użyliśmy mieszanej precyzji przy uczeniu z typem danych float16 podczas przejścia wprzód oraz float32 dla gradientów, aby przyspieszyć obliczenia float16 obsługiwane przez 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

Podsumowanie

W tym artykule omówiliśmy skalowalne podejście do rozproszonego uczenia modelu z wykorzystaniem Apache MXNet i Horovod. Zademonstrowaliśmy efektywność skalowania i opłacalność w porównaniu do podejścia z wykorzystaniem serwera parametrów na zbiorze danych ImageNet, na którym trenowano model ResNet50-v1. Opisaliśmy też kroki, dzięki którym możesz zmodyfikować już istniejący skrypt, aby uruchomić uczenie na wielu instancjach z Horovod.

Jeśli dopiero zaczynasz pracować z MXNet i głębokim uczeniem, przejdź do strony instalacji MXNe, aby najpierw zbudować MXNet. Ponadto zdecydowanie zalecamy przeczytanie artykułu MXNet w 60 minut, aby rozpocząć pracę.

Jeśli już pracowałeś z MXNet i chcesz spróbować rozproszonego uczenia z Horovod, zajrzyj na stronę instalacji Horovod, zbuduj go z MXNet i postępuj zgodnie z przykładem MNIST lub ImageNet.

*koszt obliczany jest na podstawie stawki godzinowej AWS dla instancji EC2

Teoria i praktyka użycia ClickHouse w rzeczywistych aplikacjach. Aleksandr Zajcew (2018r) „Przemysłowy ML na dużych danych“

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster