Розподілене навчання з Apache MXNet та Horovod

Переклад статті підготовлений напередодні старту курсу "Промисловий ML на великих даних"

Розподілене навчання на кількох високопродуктивних обчислювальних примірниках може скоротити час навчання сучасних глибоких нейронних мереж на великому обсязі даних з кількох тижнів до годин або навіть хвилин, що робить цю техніку навчання переважаючою у практичному використанні глибокого навчання. Користувачі повинні розуміти, як ділитися та синхронізувати дані на кількох примірниках, що в свою чергу дуже впливає на ефективність масштабування. Крім цього, користувачі також повинні знати, як розгорнути на кількох примірниках навчальний скрипт, який працює на одному примірнику.

У цій статті ми поговоримо про швидкий та простий спосіб розподіленого навчання з використанням відкритої бібліотеки для глибокого навчання Apache MXNet та фреймворку розподіленого навчання Horovod. Ми наочно покажемо переваги фреймфорка Horovod у питаннях продуктивності та продемонструємо, як написати навчальний скрипт MXNet так, щоб він працював розподілено з Horovod.

Що таке Apache MXNet

Apache MX Net – відкритий фреймворк для глибокого навчання, який використовується для створення, навчання та розгортання глибоких нейронних мереж. MXNet абстрагує складності, пов'язані з реалізацією нейронних мереж, має високу продуктивність і масштабованість, а також пропонує API для популярних мов програмування, таких як Python, C + +, Clojure, Java, Юлія, R, масштаб та інших.

Розподілене навчання в MXNet із сервером параметрів

Стандартний модуль розподіленого навчання у MXNet використовує підхід сервера параметрів (parameter server). Він використовує набір серверів параметрів для збирання градієнтів з кожного воркера, виконання агрегації та відправки оновлених градієнтів назад до ворекрам для наступної ітерації оптимізації. Визначення правильного співвідношення серверів до воркерів – запорука ефективного масштабування. Якщо сервер параметрів лише один, він може виявитися пляшковим шийкою у проведенні обчислень. І навпаки, якщо використовується занадто багато серверів, то зв'язок «багатьом» може забити всі мережеві з'єднання.

Що таке Horovod

Горовод - Відкритий фреймворк розподіленого глибокого навчання, розроблений в Uber. Він використовує ефективні технології взаємодії між декількома GPU та вузлами, такі як NVIDIA Collective Communications Library (NCCL) та Message Passing Interface (MPI) для розподілу та агрегування параметрів моделі між злодійками. Він оптимізує використання пропускної спроможності мережі та добре масштабується під час роботи з моделями глибоких нейронних мереж. В даний час він підтримує кілька популярних фреймворків машинного навчання, а саме MX Net, Tensorflow, Keras, та PyTorch.

Інтеграція MXNet та Horovod

MXNet інтегрується з Horovod через API розподіленого навчання, визначені в Horovod. У Horovod комунікаційні API horovod.broadcast(), horovod.allgather() и horovod.allreduce() реалізовані за допомогою асинхронних коллбеків двигуна MXNet, як частина його графа завдань. Таким чином, залежності даних між комунікацією та обчисленнями з легкістю обробляються двигуном MXNet, щоб уникнути втрат продуктивності через синхронізацію. Об'єкт distributed optimizer, визначений Horovod horovod.DistributedOptimizer розширює Оптимізатор у 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 звідси та виконайте такі команди в терміналі 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.16 збільшити 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, потрібно збільшити кількість серверів у два рази по відношенню до кількості воркерів.

Розподілене навчання з Apache MXNet та Horovod
Рисунок 1. Порівняння розподіленого навчання з використанням MXNet з Horovod та з сервером параметрів

У Таблиці 1 нижче ми порівняли підсумкову вартість примірника при виконанні експериментів на 64 GPU. Використання MXNet разом з Horovod забезпечує найкращу пропускну здатність за найменших витрат.

Розподілене навчання з Apache 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. Також ви можете використовувати Amazon Deep Learning AMI, де ці бібліотеки вже встановлені.

Крок 2

Додайте до свого навчального скрипту MXNet можливість роботи з API Horovod. Нижче наведений нижче скрипт на основі MXNet Gluon API можна використовувати як простий шаблон. Рядки, виділені жирним, потрібні в тому випадку, якщо у вас вже є відповідний скрипт. Ось кілька критичних змін, які необхідно внести для навчання з Horovod:

  • Встановіть контекст відповідно до локального рангу Horovod (рядок 8), щоб зрозуміти, що навчання виконується на правильному графічному ядрі.
  • Передайте початкові параметри від одного воркера всім (рядок 18), щоб переконатися, що всі воркери починають роботу з однаковими початковими параметрами.
  • Створіть Horovod DistributedOptimizer (Рядок 25), щоб оновлювати параметри розподілено.

Щоб отримати повний скрипт, зверніться до прикладів Horovod-MXNet МНІСТ и IMAGEnet.

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 GPU). Параметри weight decay та momentum змінювалися в міру збільшення числа GPU. Ми використовували змішану точність навчання з типом даних float64 під час прямого проходу та float16 для градієнтів, щоб прискорити обчислення float32, підтримувані 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 і глибоким навчанням, перейдіть на сторінку установки MXNe, щоб спочатку зібрати MXNet. Також настійно рекомендуємо почитати статтю MXNet у 60 хвилин, щоб розпочати роботу.

Якщо ви вже працювали з MXNet і хочете спробувати розподілене навчання з Horovod, то завітайте на сторінку встановлення Horovod, зберіть його з MXNet і наслідуйте приклад МНІСТ або IMAGEnet.

*вартість розраховується на підставі погодинної ставки AWS для екземплярів EC2

Дізнатись докладніше про курс "Промисловий ML на великих даних"

Джерело: habr.com

Додати коментар або відгук