6 bibliotecas de Python para procesamiento paralelo

Python es muy práctico y amigable para los programadores, pero no es el lenguaje de programación más rápido que existe. Algunas de sus limitaciones de velocidad se deben a que su implementación predeterminada, cPython, es de un solo subproceso. Es decir, cPython no usa más de un hilo de hardware a la vez.

Y aunque puede usar el threadingmódulo integrado en Python para acelerar las cosas, threadingsolo le brinda simultaneidad , no paralelismo . Es bueno para ejecutar varias tareas que no dependen de la CPU, pero no hace nada para acelerar varias tareas que requieren una CPU completa. 

Python incluye una forma nativa de ejecutar una carga de trabajo de Python en varias CPU. El multiprocessingmódulo genera varias copias del intérprete de Python, cada una en un núcleo separado, y proporciona primitivas para dividir las tareas en los núcleos. Pero a veces ni siquiera  multiprocessing es suficiente.

A veces, el trabajo requiere distribuir el trabajo no solo en varios núcleos , sino también en varias máquinas . Ahí es donde entran en juego estas seis bibliotecas y marcos de trabajo de Python. Los seis kits de herramientas de Python a continuación le permiten tomar una aplicación de Python existente y distribuir el trabajo en múltiples núcleos, múltiples máquinas o ambos.

Rayo

Desarrollado por un equipo de investigadores de la Universidad de California, Berkeley, Ray respalda varias bibliotecas distribuidas de aprendizaje automático. Pero Ray no se limita solo a las tareas de aprendizaje automático, incluso si ese fuera su caso de uso original. Cualquier tarea de Python se puede dividir y distribuir entre sistemas con Ray.

La sintaxis de Ray es mínima, por lo que no es necesario volver a trabajar en gran medida las aplicaciones existentes para paralelizarlas. El @ray.remotedecorador distribuye esa función entre todos los nodos disponibles en un clúster de Ray, con parámetros opcionalmente especificados para cuántas CPU o GPU usar. Los resultados de cada función distribuida se devuelven como objetos de Python, por lo que son fáciles de administrar y almacenar, y la cantidad de copias a través o dentro de los nodos se mantiene al mínimo. Esta última característica es útil cuando se trata de matrices NumPy, por ejemplo.

Ray incluso incluye su propio administrador de clúster integrado, que puede activar automáticamente los nodos según sea necesario en el hardware local o en plataformas populares de computación en la nube.

Vídeo relacionado: Uso multiprocessingpara acelerar Python

Dask

Desde fuera, Dask se parece mucho a Ray. También es una biblioteca para computación paralela distribuida en Python, con su propio sistema de programación de tareas, conocimiento de los marcos de datos de Python como NumPy y la capacidad de escalar de una máquina a muchas.

Dask funciona de dos formas básicas. La primera es a través de estructuras de datos paralelizadas, esencialmente, las propias versiones de Dask de matrices, listas o Pandas DataFrames de NumPy. Cambie las versiones Dask de esas construcciones por sus valores predeterminados, y Dask distribuirá automáticamente su ejecución en su clúster. Por lo general, esto implica poco más que cambiar el nombre de una importación, pero a veces puede ser necesario volver a escribir para que funcione por completo.

La segunda forma es a través de los mecanismos de paralelización de bajo nivel de Dask, incluidos los decoradores de funciones, que distribuyen los trabajos en los nodos y devuelven los resultados de forma sincrónica (modo "inmediato") o asincrónica ("lazy"). Ambos modos también se pueden mezclar según sea necesario.

Una diferencia clave entre Dask y Ray es el mecanismo de programación. Dask utiliza un programador centralizado que maneja todas las tareas de un clúster. Ray está descentralizado, lo que significa que cada máquina ejecuta su propio programador, por lo que cualquier problema con una tarea programada se maneja a nivel de la máquina individual, no de todo el clúster.

Dask también ofrece una función avanzada y aún experimental llamada "actores". Un actor es un objeto que apunta a un trabajo en otro nodo Dask. De esta manera, un trabajo que requiere mucho estado local puede ejecutarse en el lugar y ser llamado de forma remota por otros nodos, por lo que el estado del trabajo no tiene que ser replicado. Ray carece de algo parecido al modelo de actor de Dask para soportar una distribución de trabajo más sofisticada.

Dispy

Dispy le permite distribuir programas Python completos o solo funciones individuales en un grupo de máquinas para la ejecución en paralelo. Utiliza mecanismos nativos de la plataforma para la comunicación en red para mantener las cosas rápidas y eficientes, por lo que las máquinas Linux, MacOS y Windows funcionan igualmente bien.

La sintaxis de Dispy se parece un poco a multiprocessing que crea explícitamente un clúster (donde multiprocessingdebería crear un grupo de procesos), envía el trabajo al clúster y luego recupera los resultados. Es posible que se requiera un poco más de trabajo para modificar los trabajos para que funcionen con Dispy, pero también obtiene un control preciso sobre cómo se envían y devuelven esos trabajos. Por ejemplo, puede devolver resultados provisionales o parcialmente completados, transferir archivos como parte del proceso de distribución de trabajos y utilizar el cifrado SSL al transferir datos.

Pandaral·lel

Pandaral·lel, como su nombre lo indica, es una forma de paralelizar trabajos de Pandas en múltiples nodos. La desventaja es que Pandaral·lel solo funciona  con Pandas. Pero si Pandas es lo que está usando y todo lo que necesita es una forma de acelerar los trabajos de Pandas en múltiples núcleos en una sola computadora, Pandaral·lel está enfocado en la tarea.

Tenga en cuenta que, aunque Pandaral·lel se ejecuta en Windows, solo se ejecutará desde sesiones de Python iniciadas en el subsistema de Windows para Linux. Los usuarios de MacOS y Linux pueden ejecutar Pandaral·lel tal cual. 

Ipyparallel

Ipyparallel es otro sistema de multiprocesamiento y distribución de tareas estrechamente enfocado, específicamente para paralelizar la ejecución del código del cuaderno de Jupyter en un clúster. Los proyectos y equipos que ya están trabajando en Jupyter pueden comenzar a usar Ipyparallel inmediatamente.

Ipyparallel admite muchos enfoques para paralelizar código. En el extremo simple, está map, que aplica cualquier función a una secuencia y divide el trabajo de manera uniforme entre los nodos disponibles. Para trabajos más complejos, puede decorar funciones específicas para que siempre se ejecuten de forma remota o en paralelo.

Los cuadernos de Jupyter admiten "comandos mágicos" para acciones que solo son posibles en un entorno de portátil. Ipyparallel agrega algunos comandos mágicos propios. Por ejemplo, puede prefijar cualquier declaración de Python %pxpara paralelizarla automáticamente.

Joblib

Joblib tiene dos objetivos principales: ejecutar trabajos en paralelo y no volver a calcular los resultados si nada ha cambiado. Estas eficiencias hacen que Joblib sea adecuado para la informática científica, donde los resultados reproducibles son sacrosantos. La documentación de Joblib proporciona muchos ejemplos sobre cómo utilizar todas sus funciones.

La sintaxis de Joblib para paralelizar el trabajo es bastante simple: equivale a un decorador que puede usarse para dividir trabajos entre procesadores o para almacenar en caché los resultados. Los trabajos paralelos pueden utilizar subprocesos o procesos.

Joblib incluye una caché de disco transparente para los objetos de Python creados por trabajos de computación. Esta caché no solo ayuda a Joblib a evitar la repetición del trabajo, como se indicó anteriormente, sino que también se puede usar para suspender y reanudar trabajos de larga ejecución, o retomar el trabajo donde se quedó después de un bloqueo. El caché también está optimizado de forma inteligente para objetos grandes como matrices NumPy. Las regiones de datos se pueden compartir en la memoria entre procesos en el mismo sistema usando numpy.memmap.

Una cosa que Joblib no ofrece es una forma de distribuir trabajos en varias computadoras separadas. En teoría, es posible usar la canalización de Joblib para hacer esto, pero probablemente sea más fácil usar otro marco que lo admita de forma nativa. 

Leer más sobre Python

  • ¿Qué es Python? Programación potente e intuitiva
  • ¿Qué es PyPy? Python más rápido sin dolor
  • ¿Qué es Cython? Python a la velocidad de C
  • Tutorial de Cython: Cómo acelerar Python
  • Cómo instalar Python de forma inteligente
  • Las mejores características nuevas en Python 3.8
  • Mejor gestión de proyectos de Python con Poetry
  • Virtualenv y venv: explicación de los entornos virtuales de Python
  • Python virtualenv y venv qué hacer y qué no hacer
  • Explicación de subprocesos y subprocesos de Python
  • Cómo usar el depurador de Python
  • Cómo usar timeit para perfilar el código Python
  • Cómo usar cProfile para perfilar el código Python
  • Comience con async en Python
  • Cómo usar asyncio en Python
  • Cómo convertir Python a JavaScript (y viceversa)
  • Python 2 EOL: Cómo sobrevivir al final de Python 2
  • 12 pitones para cada necesidad de programación
  • 24 bibliotecas de Python para cada desarrollador de Python
  • 7 dulces IDE de Python que quizás te hayas perdido
  • 3 deficiencias principales de Python y sus soluciones
  • 13 marcos web de Python comparados
  • 4 marcos de prueba de Python para acabar con sus errores
  • 6 fantásticas funciones nuevas de Python que no querrá perderse
  • 5 distribuciones de Python para dominar el aprendizaje automático
  • 8 fantásticas bibliotecas de Python para el procesamiento del lenguaje natural