Apache MXNet - rozproszone szkolenie

Ten rozdział dotyczy rozproszonego szkolenia w Apache MXNet. Zacznijmy od zrozumienia, jakie są tryby obliczeń w MXNet.

Tryby obliczeń

MXNet, wielojęzyczna biblioteka ML, oferuje swoim użytkownikom następujące dwa tryby obliczeń -

Tryb rozkazujący

Ten tryb obliczeń udostępnia interfejs, taki jak NumPy API. Na przykład w MXNet użyj następującego imperatywnego kodu, aby skonstruować tensor zer zarówno na CPU, jak i GPU -

import mxnet as mx
tensor_cpu = mx.nd.zeros((100,), ctx=mx.cpu())
tensor_gpu= mx.nd.zeros((100,), ctx=mx.gpu(0))

Jak widać w powyższym kodzie, MXNets określa lokalizację, w której należy przechowywać tensor, w procesorze lub urządzeniu GPU. W powyższym przykładzie jest to lokalizacja 0. MXNet osiąga niesamowite wykorzystanie urządzenia, ponieważ wszystkie obliczenia są wykonywane leniwie, a nie natychmiastowo.

Tryb symboliczny

Chociaż tryb imperatywny jest całkiem przydatny, ale jedną z wad tego trybu jest jego sztywność, tj. Wszystkie obliczenia muszą być znane wcześniej wraz z predefiniowanymi strukturami danych.

Z drugiej strony tryb symboliczny udostępnia wykres obliczeniowy, taki jak TensorFlow. Eliminuje wady imperatywnego interfejsu API, umożliwiając MXNet pracę z symbolami lub zmiennymi zamiast ustalonych / wstępnie zdefiniowanych struktur danych. Następnie symbole można zinterpretować jako zbiór operacji w następujący sposób -

import mxnet as mx
x = mx.sym.Variable(“X”)
y = mx.sym.Variable(“Y”)
z = (x+y)
m = z/100

Rodzaje równoległości

Apache MXNet obsługuje szkolenia rozproszone. Umożliwia nam wykorzystanie wielu maszyn do szybszego i efektywnego treningu.

Poniżej przedstawiono dwa sposoby, w jakie możemy rozłożyć obciążenie związane z trenowaniem sieci NN na wiele urządzeń, procesor lub urządzenie GPU -

Równoległość danych

W tego rodzaju równoległości każde urządzenie przechowuje pełną kopię modelu i współpracuje z inną częścią zestawu danych. Urządzenia również zbiorczo aktualizują udostępniony model. Możemy zlokalizować wszystkie urządzenia na jednym komputerze lub na wielu komputerach.

Równoległość modelu

To inny rodzaj równoległości, który przydaje się, gdy modele są tak duże, że nie mieszczą się w pamięci urządzenia. W równoległości modelu różne urządzenia mają zadanie uczenia się różnych części modelu. Ważną kwestią, na którą należy zwrócić uwagę, jest to, że obecnie Apache MXNet obsługuje równoległość modeli tylko w jednej maszynie.

Działanie szkolenia rozproszonego

Poniższe koncepcje są kluczem do zrozumienia działania rozproszonego szkolenia w Apache MXNet -

Rodzaje procesów

Procesy komunikują się ze sobą, aby ukończyć szkolenie modelu. Apache MXNet ma następujące trzy procesy -

Pracownik

Zadaniem węzła roboczego jest przeprowadzenie szkolenia na partii próbek szkoleniowych. Węzły robocze będą pobierać wagi z serwera przed przetworzeniem każdej partii. Węzły Worker wyślą gradienty na serwer po przetworzeniu partii.

serwer

MXNet może mieć wiele serwerów do przechowywania parametrów modelu i komunikacji z węzłami roboczymi.

Planista

Zadaniem harmonogramu jest skonfigurowanie klastra, co obejmuje oczekiwanie na komunikaty, które nadszedł każdy węzeł i którego portu nasłuchuje. Po skonfigurowaniu klastra program planujący informuje wszystkie procesy o każdym innym węźle w klastrze. Dzieje się tak, ponieważ procesy mogą się ze sobą komunikować. Jest tylko jeden program planujący.

Sklep KV

Sklepy KV oznaczają Key-Valuesklep. Jest to krytyczny komponent używany do treningu na wielu urządzeniach. Jest to ważne, ponieważ komunikacja parametrów między urządzeniami na jednym, a także na wielu maszynach jest przesyłana przez jeden lub więcej serwerów z KVStore dla parametrów. Zrozummy działanie KVStore za pomocą następujących punktów -

  • Każda wartość w KVStore jest reprezentowana przez key i a value.

  • Każda tablica parametrów w sieci ma przypisany plik key a wagi tej tablicy parametrów są określane przez value.

  • Następnie węzły robocze pushgradienty po przetworzeniu partii. Oni teżpull zaktualizowane wagi przed przetworzeniem nowej partii.

Pojęcie serwera KVStore istnieje tylko podczas szkolenia rozproszonego, a tryb rozproszony jest włączany przez wywołanie mxnet.kvstore.create funkcja z argumentem w postaci łańcucha zawierającego słowo dist -

kv = mxnet.kvstore.create(‘dist_sync’)

Dystrybucja kluczy

Nie jest konieczne, aby wszystkie serwery przechowywały wszystkie tablice parametrów lub klucze, ale są one rozmieszczone na różnych serwerach. Taka dystrybucja kluczy między różnymi serwerami jest obsługiwana w sposób przejrzysty przez KVStore, a decyzja o tym, który serwer przechowuje określony klucz, jest podejmowana losowo.

KVStore, jak omówiono powyżej, zapewnia, że ​​za każdym razem, gdy klucz jest ściągany, jego żądanie jest wysyłane do tego serwera, który ma odpowiednią wartość. Co jeśli wartość jakiegoś klucza jest duża? W takim przypadku może być współużytkowany na różnych serwerach.

Podziel dane treningowe

Jako użytkownicy chcemy, aby każda maszyna pracowała na różnych częściach zestawu danych, zwłaszcza podczas przeprowadzania rozproszonego szkolenia w trybie równoległym do danych. Wiemy, że aby podzielić partię próbek dostarczonych przez iterator danych do równoległego szkolenia danych na jednym pracowniku, możemy użyćmxnet.gluon.utils.split_and_load a następnie załaduj każdą część partii na urządzenie, które będzie dalej ją przetwarzać.

Z drugiej strony, w przypadku szkolenia rozproszonego, na początku musimy podzielić zbiór danych na nróżne części, tak aby każdy pracownik otrzymał inną część. Gdy już to zrobisz, każdy pracownik może użyćsplit_and_loadaby ponownie podzielić tę część zbioru danych na różne urządzenia na jednym komputerze. Wszystko to dzieje się za pośrednictwem iteratora danych.mxnet.io.MNISTIterator i mxnet.io.ImageRecordIter są dwa takie iteratory w MXNet, które obsługują tę funkcję.

Aktualizacja wag

Aby zaktualizować wagi, KVStore obsługuje następujące dwa tryby -

  • Pierwsza metoda agreguje gradienty i aktualizuje wagi przy użyciu tych gradientów.

  • W drugiej metodzie serwer tylko agreguje gradienty.

Jeśli korzystasz z Gluon, istnieje możliwość wyboru między wyżej wymienionymi metodami przez przejście update_on_kvstorezmienna. Zrozummy to, tworząc pliktrainer obiekt w następujący sposób -

trainer = gluon.Trainer(net.collect_params(), optimizer='sgd',
   optimizer_params={'learning_rate': opt.lr,
      'wd': opt.wd,
      'momentum': opt.momentum,
      'multi_precision': True},
      kvstore=kv,
   update_on_kvstore=True)

Tryby rozproszonego szkolenia

Jeśli ciąg tworzenia KVStore zawiera słowo dist, oznacza to, że rozproszone uczenie jest włączone. Poniżej przedstawiono różne tryby szkolenia rozproszonego, które można włączyć za pomocą różnych typów KVStore -

dist_sync

Jak sama nazwa wskazuje, oznacza synchroniczne szkolenie rozproszone. W tym przypadku wszyscy pracownicy używają tego samego zsynchronizowanego zestawu parametrów modelu na początku każdej partii.

Wadą tego trybu jest to, że po każdej partii serwer powinien czekać na otrzymanie gradientów od każdego pracownika, zanim zaktualizuje parametry modelu. Oznacza to, że jeśli pracownik ulegnie awarii, zatrzyma to postęp wszystkich pracowników.

dist_async

Jak sama nazwa wskazuje, oznacza synchroniczne szkolenie rozproszone. W tym przypadku serwer otrzymuje gradienty od jednego pracownika i natychmiast aktualizuje swój magazyn. Serwer używa zaktualizowanego magazynu, aby odpowiedzieć na wszelkie dalsze ściągnięcia.

Zaletą w porównaniu z dist_sync mode, polega na tym, że pracownik, który zakończy przetwarzanie partii, może pobrać bieżące parametry z serwera i rozpocząć następną. Pracownik może to zrobić, nawet jeśli drugi pracownik nie zakończył jeszcze przetwarzania wcześniejszej partii. Jest również szybszy niż tryb dist_sync, ponieważ zbieżność może zająć więcej epok bez żadnych kosztów synchronizacji.

dist_sync_device

Ten tryb jest taki sam jak dist_synctryb. Jedyna różnica polega na tym, że w każdym węźle używanych jest wiele procesorów graficznychdist_sync_device agreguje gradienty i aktualizuje wagi na GPU, podczas gdy, dist_sync agreguje gradienty i aktualizuje wagi w pamięci procesora.

Zmniejsza kosztowną komunikację między GPU i CPU. Dlatego jest szybszy niżdist_sync. Wadą jest to, że zwiększa zużycie pamięci na GPU.

dist_async_device

Ten tryb działa tak samo jak dist_sync_device tryb, ale w trybie asynchronicznym.