Aprendizaje distribuido con Apache MXNet y Horovod

La traducción del artículo se preparó la víspera del inicio del curso. "ML industrial sobre Big Data"

La capacitación distribuida en múltiples instancias informáticas de alto rendimiento puede reducir el tiempo de capacitación de las redes neuronales profundas modernas en grandes cantidades de datos de semanas a horas o incluso minutos, lo que hace que esta técnica de capacitación prevalezca en aplicaciones prácticas de aprendizaje profundo. Los usuarios deben comprender cómo compartir y sincronizar datos entre múltiples instancias, lo que a su vez tiene un impacto importante en la eficiencia del escalado. Además, los usuarios también deben saber cómo implementar un script de entrenamiento que se ejecuta en una sola instancia en varias instancias.

En este artículo hablaremos sobre una forma rápida y sencilla de distribuir el aprendizaje utilizando la biblioteca abierta de aprendizaje profundo Apache MXNet y el marco de aprendizaje distribuido Horovod. Demostraremos claramente los beneficios de rendimiento del marco Horovod y demostraremos cómo escribir un script de entrenamiento MXNet para que funcione de manera distribuida con Horovod.

¿Qué es Apache MXNet?

Apache MXnet es un marco de aprendizaje profundo de código abierto que se utiliza para crear, entrenar e implementar redes neuronales profundas. MXNet abstrae las complejidades asociadas con la implementación de redes neuronales, es altamente eficiente y escalable y ofrece API para lenguajes de programación populares como Python, C + +, Clojure, Java, Julia, R, Scala y otros.

Entrenamiento distribuido en MXNet con servidor de parámetros

Módulo de aprendizaje distribuido estándar en MXNet utiliza un enfoque de servidor de parámetros. Utiliza un conjunto de servidores de parámetros para recopilar gradientes de cada trabajador, realizar agregaciones y enviar gradientes actualizados a los trabajadores para la siguiente iteración de optimización. Determinar la proporción correcta de servidores por trabajadores es la clave para un escalamiento efectivo. Si sólo hay un servidor de parámetros, puede resultar un cuello de botella en los cálculos. Por el contrario, si se utilizan demasiados servidores, la comunicación de muchos a muchos puede obstruir todas las conexiones de red.

¿Qué es Horovod?

Horovod es un marco abierto de aprendizaje profundo distribuido desarrollado en Uber. Aprovecha tecnologías eficientes entre GPU y entre nodos, como la Biblioteca de comunicaciones colectivas de NVIDIA (NCCL) y la Interfaz de paso de mensajes (MPI) para distribuir y agregar parámetros de modelo entre vorecs. Optimiza el uso del ancho de banda de la red y se escala bien cuando se trabaja con modelos de redes neuronales profundas. Actualmente es compatible con varios marcos populares de aprendizaje automático, a saber MXNet, Tensorflow, Keras y PyTorch.

Integración de MXNet y Horovod

MXNet se integra con Horovod a través de las API de aprendizaje distribuido definidas en Horovod. API de comunicación de Horovod horovod.transmisión(), horovod.allgather() и horovod.allreduce() implementado utilizando devoluciones de llamadas asincrónicas del motor MXNet, como parte de su gráfico de tareas. De esta manera, el motor MXNet maneja fácilmente las dependencias de datos entre la comunicación y la computación para evitar pérdidas de rendimiento debido a la sincronización. Objeto optimizador distribuido definido en Horovod horovod.DistributedOptimizer se expande Optimizador en MXNet para que llame a las API de Horovod correspondientes para actualizaciones de parámetros distribuidos. Todos estos detalles de implementación son transparentes para los usuarios finales.

Comienzo rápido

Puede comenzar rápidamente a entrenar una pequeña red neuronal convolucional en el conjunto de datos MNIST usando MXNet y Horovod en su MacBook.
Primero, instale mxnet y horovod desde PyPI:

pip install mxnet
pip install horovod

Nota: Si encuentra un error durante pip instalar horovodtal vez necesites agregar una variable MACOSX_DEPLOYMENT_TARGET=10.vvDonde vv – esta es la versión de tu versión de MacOS, por ejemplo, para MacOSX Sierra necesitarás escribir MACOSX_DEPLOYMENT_TARGET=10.12 pips instalación horovod

Luego instale OpenMPI por lo tanto.

Al final, descargue el script de prueba. mxnet_mnist.py por lo tanto y ejecute los siguientes comandos en la terminal MacBook en el directorio de trabajo:

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

Esto ejecutará el entrenamiento en dos núcleos de su procesador. La salida será la siguiente:

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

Demostración de rendimiento

Al entrenar un modelo ResNet50-v1 en un conjunto de datos ImageNet en 64 GPU con ocho instancias p3.16xgrande EC2, cada una con 8 GPU NVIDIA Tesla V100 en la nube de AWS, logramos un rendimiento de entrenamiento de 45000 44 imágenes/seg (es decir, la cantidad de muestras entrenadas por segundo). El entrenamiento se completó en 90 minutos después de 75.7 épocas con una precisión máxima del XNUMX%.

Comparamos esto con el enfoque de capacitación distribuida de MXNet de usar servidores de parámetros en 8, 16, 32 y 64 GPU con un único servidor de parámetros y una proporción de servidor por trabajador de 1 a 1 y 2 a 1, respectivamente. Puede ver el resultado en la Figura 1 a continuación. En el eje y de la izquierda, las barras representan la cantidad de imágenes a entrenar por segundo, las líneas reflejan la eficiencia de escalado (es decir, la relación entre el rendimiento real e ideal) en el eje y de la derecha. Como puede ver, la elección de la cantidad de servidores afecta la eficiencia de escalado. Si solo hay un servidor de parámetros, la eficiencia de escalado cae al 38% en 64 GPU. Para lograr la misma eficiencia de escalado que con Horovod, es necesario duplicar la cantidad de servidores en relación con la cantidad de trabajadores.

Aprendizaje distribuido con Apache MXNet y Horovod
Figura 1. Comparación del aprendizaje distribuido usando MXNet con Horovod y con el servidor de parámetros

En la Tabla 1 a continuación, comparamos el costo final por instancia al ejecutar experimentos en 64 GPU. El uso de MXNet con Horovod proporciona el mejor rendimiento al menor costo.

Aprendizaje distribuido con Apache MXNet y Horovod
Tabla 1. Comparación de costos entre Horovod y Parameter Server con una proporción de servidor por trabajador de 2 a 1.

pasos para reproducir

En los próximos pasos, le mostraremos cómo reproducir el resultado del entrenamiento distribuido usando MXNet y Horovod. Para obtener más información sobre el aprendizaje distribuido con MXNet, lea esta publicación.

Paso 1

Cree un grupo de instancias homogéneas con MXNet versión 1.4.0 o superior y Horovod versión 0.16.0 o superior para utilizar el aprendizaje distribuido. También necesitarás instalar bibliotecas para el entrenamiento de GPU. Para nuestros casos, elegimos Ubuntu 16.04 Linux, con GPU Driver 396.44, CUDA 9.2, biblioteca cuDNN 7.2.1, comunicador NCCL 2.2.13 y OpenMPI 3.1.1. También puedes usar AMI de aprendizaje profundo de Amazon, donde estas bibliotecas ya están preinstaladas.

Paso 2

Agregue la capacidad de trabajar con la API de Horovod a su script de entrenamiento MXNet. El siguiente script basado en la API MXNet Gluon se puede utilizar como una plantilla sencilla. Las líneas en negrita son necesarias si ya dispone del guión de formación correspondiente. Aquí hay algunos cambios críticos que debes realizar para aprender con Horovod:

  • Establezca el contexto de acuerdo con el rango Horovod local (línea 8) para comprender que el entrenamiento se realiza en el núcleo de gráficos correcto.
  • Pase los parámetros iniciales de un trabajador a todos (línea 18) para garantizar que todos los trabajadores comiencen con los mismos parámetros iniciales.
  • Crear un Horovod Optimizador distribuido (línea 25) para actualizar los parámetros de forma distribuida.

Para obtener el script completo, consulte los ejemplos de Horovod-MXNet. MNIST и ImagenNet.

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    ...

Paso 3

Inicie sesión en uno de los trabajadores para iniciar la capacitación distribuida utilizando la directiva MPI. En este ejemplo, el entrenamiento distribuido se ejecuta en cuatro instancias con 4 GPU cada una y un total de 16 GPU en el clúster. El optimizador Stochastic Gradient Descent (SGD) se utilizará con los siguientes hiperparámetros:

  • tamaño del mini lote: 256
  • tasa de aprendizaje: 0.1
  • impulso: 0.9
  • caída de peso: 0.0001

A medida que escalamos de una GPU a 64 GPU, escalamos linealmente la tasa de entrenamiento según la cantidad de GPU (de 0,1 para 1 GPU a 6,4 para 64 GPU), mientras manteníamos la cantidad de imágenes por GPU en 256 (de un lote de 256 imágenes para 1 GPU a 16 para 384 GPU). Los parámetros de disminución de peso y de impulso cambiaron a medida que aumentaba el número de GPU. Utilizamos un entrenamiento de precisión mixto con el tipo de datos float64 para el pase hacia adelante y float16 para los gradientes para acelerar los cálculos de float32 compatibles con las 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

Conclusión

En este artículo, analizamos un enfoque escalable para el entrenamiento de modelos distribuidos utilizando Apache MXNet y Horovod. Demostramos la eficiencia de escalado y la rentabilidad en comparación con el enfoque del servidor de parámetros en el conjunto de datos ImageNet en el que se entrenó el modelo ResNet50-v1. También hemos incluido pasos que puede utilizar para modificar un script existente para ejecutar entrenamiento de instancias múltiples usando Horovod.

Si recién está comenzando con MXNet y el aprendizaje profundo, vaya a la página de instalación MXNepara construir primero MXNet. También recomendamos encarecidamente leer el artículo. MXNet en 60 minutosPara empezar.

Si ya trabajó con MXNet y desea probar el aprendizaje distribuido con Horovod, eche un vistazo a Página de instalación de Horovod, compílelo desde MXNet y siga el ejemplo MNIST o ImagenNet.

*el costo se calcula en base a tarifas por hora AWS para instancias EC2

Más información sobre el curso "ML industrial sobre Big Data"

Fuente: habr.com

Añadir un comentario