Instancias vs. núcleos cuando se usa EC2

12

Trabajando en lo que a menudo se podría llamar proyectos de "datos medios", he podido paralelizar mi código (principalmente para modelar y predecir en Python) en un solo sistema en cualquier lugar de 4 a 32 núcleos. Ahora estoy buscando escalar a los clústeres en EC2 (probablemente con StarCluster / IPython, pero también abierto a otras sugerencias), y me ha intrigado cómo reconciliar el trabajo de distribución entre núcleos en una instancia frente a instancias en un clúster.

¿Es incluso práctico paralelizar entre instancias y entre núcleos en cada instancia? Si es así, ¿alguien puede dar un resumen rápido de las ventajas y desventajas de ejecutar muchas instancias con pocos núcleos cada una versus algunas instancias con muchos núcleos? ¿Existe una regla general para elegir la proporción correcta de instancias a núcleos por instancia?

El ancho de banda y la RAM son preocupaciones no triviales en mis proyectos, pero es fácil detectar cuándo son los cuellos de botella y el reajuste. Es mucho más difícil, me imagino, comparar la combinación correcta de núcleos con instancias sin pruebas repetidas, y mis proyectos varían demasiado para que una sola prueba se aplique a todas las circunstancias. Gracias de antemano, y si no pude buscar en Google correctamente, ¡no dudes en señalarme la respuesta correcta en otro lugar!

Therriault
fuente

Respuestas:

11

Al usar IPython, casi no tiene que preocuparse por ello (a expensas de alguna pérdida de eficiencia / mayor sobrecarga de comunicación). El complemento paralelo de IPython en StarCluster iniciará por defecto un motor por núcleo físico en cada nodo (creo que esto es configurable pero no estoy seguro de dónde). Simplemente ejecute lo que desee en todos los motores utilizando la API de DirectView (map_sync, apply_sync, ...) o los comandos mágicos% px. Si ya está utilizando IPython en paralelo en una máquina, usarlo en un clúster no es diferente.

Abordar algunas de sus preguntas específicas:

"cómo conciliar el trabajo de distribución entre núcleos en una instancia frente a instancias en un clúster": obtienes un motor por núcleo (al menos); el trabajo se distribuye automáticamente en todos los núcleos y en todas las instancias.

"¿Es incluso práctico paralelizar entre instancias y entre núcleos en cada instancia?" - Sí :) Si el código que está ejecutando es vergonzosamente paralelo (exactamente el mismo algoritmo en varios conjuntos de datos), entonces puede ignorar principalmente dónde se está ejecutando un motor en particular. Si el núcleo requiere mucha comunicación entre motores, entonces, por supuesto, debe estructurarlo para que los motores se comuniquen principalmente con otros motores en la misma máquina física; pero ese tipo de problema no es ideal para IPython, creo.

"Si es así, ¿alguien puede dar un resumen rápido de las ventajas y desventajas de ejecutar muchas instancias con pocos núcleos cada una versus algunas instancias con muchos núcleos? ¿Existe una regla general para elegir la proporción correcta de instancias a núcleos por instancia? " - Utilice las instancias c3 más grandes para problemas vinculados a cómputo y los más pequeños para problemas vinculados a ancho de banda de memoria; para problemas relacionados con el paso de mensajes, también use las instancias más grandes, pero intente particionar el problema para que cada partición se ejecute en una máquina física y la mayoría de los mensajes pasen dentro de la misma partición. Los problemas que se ejecutarían significativamente más lentamente en N cuádruples c3 instancias que en 2N doble c3 son raros (un ejemplo artificial puede ser la ejecución de múltiples filtros simples en una gran cantidad de imágenes, donde revisa todas las imágenes para cada filtro en lugar de todos los filtros para el misma imagen)

Alex I
fuente
1
Creo que debe tener en cuenta que para los procesos en una sola máquina puede asignar variables de memoria con joblib / Numpy. Pierdes esa capacidad para procesos en diferentes máquinas.
gallamine
11

Una regla general es no distribuir hasta que sea necesario. Por lo general, es más eficiente tener N servidores de cierta capacidad que servidores 2N de la mitad de esa capacidad. La mayor parte del acceso a los datos será local y, por lo tanto, rápida en la memoria versus lenta en la red.

En cierto punto, la ampliación de escala de una máquina se vuelve poco rentable porque el costo de recursos adicionales aumenta más que linealmente. Sin embargo, este punto sigue siendo asombrosamente alto.

Sin embargo, en Amazon en particular, la economía de cada tipo de instancia puede variar mucho si está utilizando instancias de mercado spot. El precio predeterminado más o menos significa que la misma cantidad de recursos cuesta aproximadamente lo mismo, independientemente del tipo de instancia, que puede variar mucho; Las instancias grandes pueden ser más baratas que las pequeñas, o N instancias pequeñas pueden ser mucho más baratas que una máquina grande con recursos equivalentes.

Una consideración masiva aquí es que el paradigma de cómputo puede cambiar bastante cuando se mueve de una máquina a varias máquinas. Las compensaciones que induce la sobrecarga de la comunicación pueden obligarlo a, por ejemplo, adoptar un paradigma de datos paralelos para escalar. Eso significa una elección diferente de herramientas y algoritmo. Por ejemplo, SGD se ve bastante diferente en la memoria y en Python que en MapReduce. Por lo tanto, tendría que considerar esto antes de hacer paralelo.

Puede elegir distribuir el trabajo en un clúster, incluso si un solo nodo y paradigmas no distribuidos funcionan para usted, para mayor confiabilidad. Si falla un solo nodo, pierde todo el cálculo; un cálculo distribuido puede potencialmente recuperar y completar solo la parte del cálculo que se perdió.

Sean Owen
fuente
6

Todas las cosas consideradas iguales (costo, rendimiento de la CPU, etc.) podrían elegir la instancia más pequeña que pueda almacenar todo mi conjunto de datos en la memoria y escalar. De esa manera

  • asegúrese de no inducir latencias innecesarias debido a las comunicaciones de red, y
  • tiende a maximizar el ancho de banda de memoria disponible en general para sus procesos.

Suponiendo que está ejecutando algún tipo de esquema de validación cruzada para optimizar algún metaparámetro de su modelo, asigne a cada núcleo un valor para probar y elija muchas instancias según sea necesario para cubrir todo el espacio de parámetros en tan pocas rondas como mejor le parezca.

Si sus datos no caben en la memoria de un sistema, por supuesto, deberá distribuirlos entre las instancias. Entonces se trata de equilibrar la latencia de la memoria (mejor con muchas instancias) con la latencia de la red (mejor con menos instancias), pero dada la naturaleza de EC2, apuesto a que a menudo preferirás trabajar con pocas instancias gordas.

damienfrancois
fuente