Acelere numpy, scikit y pandas 100 veces con Rust y LLVM: entrevista con el desarrollador Weld

Hola Habr! Les presento la traducción del artículo "Entrevista con el principal contribuyente de Weld: acelerar numpy, scikit y pandas hasta 100 veces con Rust y LLVM" .

Después de trabajar durante varias semanas con herramientas de ciencia de datos en Python y R, comencé a preguntarme si hay alguna representación intermedia (IR) como CUDA que se pueda usar en diferentes idiomas. Debe haber algo mejor que la reimplementación y la optimización de los mismos métodos en cada idioma. Además de esto, sería bueno tener un tiempo de ejecución común para optimizar todo el programa, en lugar de cada función individualmente.

Después de varios días de investigar y probar varios proyectos, encontré Weld(puedes leer el artículo académico ).

Para mi sorpresa, uno de los autores de Weld es Matei Zaharia (Matei Zaharia), el creador de Spark.

Entonces, contacté a Shoumik Palkar , el principal contribuyente de Weld, y lo entrevisté. Showmick es un estudiante graduado en el Departamento de Ciencias de la Computación de la Universidad de Stanford, donde ingresó con el asesoramiento de Matey Zakharia.

La soldadura aún no está lista para uso industrial, pero es muy prometedora. Si está interesado en el futuro de la ciencia de datos y Rust en particular, le encantará esta entrevista.

Anuncio del autor del artículo original.
image
«Not a Monad Tutorial», Weld . !

, mail@fcarrone.com @unbalancedparen.

¿Para qué fue diseñado Weld, qué problemas resuelve?


El objetivo de Weld es aumentar la productividad de las aplicaciones que utilizan API de alto nivel, como NumPy y Pandas. El principal problema que resuelve son las optimizaciones de funciones cruzadas y de bibliotecas cruzadas que no proporcionan otras bibliotecas en la actualidad. En particular, muchas bibliotecas ampliamente utilizadas tienen implementaciones modernas de algoritmos para funciones individuales (por ejemplo, el algoritmo de unión rápida implementado en Pandas por C, o la multiplicación de matriz rápida en NumPy), pero no ofrecen la posibilidad de optimizar la combinación de estas funciones. Por ejemplo, evitar escaneos innecesarios de memoria al realizar la multiplicación de matrices seguida de la agregación.

Weld proporciona un entorno de tiempo de ejecución común que permite a las bibliotecas expresar cálculos en una representación intermedia (IR) común. Este IR se puede optimizar utilizando el optimizador del compilador y luego se puede compilar sobre la marcha (JIT) en código máquina paralelo con optimizaciones como fusión de bucles, vectorización, etc. El IR de Weld es inicialmente paralelo, por lo que los programas expresados ​​en él siempre pueden ser paralelos trivialmente.

También tenemos un nuevo proyecto llamado Anotaciones divididas, que se integrará con Weld y se diseñará para reducir la barrera a la inclusión de tales optimizaciones en las bibliotecas existentes.

¿No sería más fácil optimizar numpy, pandas y scikit? ¿Cuánto más rápido es?


Weld proporciona una optimización de la combinación de funciones en estas bibliotecas, mientras que la optimización de las bibliotecas puede acelerar las llamadas de solo funciones individuales. De hecho, muchas de estas bibliotecas ya están muy bien optimizadas para cada función individual, pero proporcionan un rendimiento por debajo de los límites de los equipos modernos, porque no usan paralelismo o no usan la jerarquía de memoria de manera eficiente.

Por ejemplo, muchas funciones NumPy para matrices multidimensionales (ndarray) se implementan en el lenguaje C de bajo nivel, pero una llamada a cada función requiere un análisis completo de los datos de entrada. Si estas matrices no caben en los cachés de la CPU, la mayor parte del tiempo de ejecución se puede pasar cargando datos de la memoria principal, en lugar de realizar cálculos. Weld puede ver llamadas a funciones individuales y realizar optimizaciones, como combinar bucles que almacenarán datos en cachés o registros de CPU. Dichas optimizaciones pueden mejorar el rendimiento en más de un orden de magnitud en sistemas de múltiples núcleos, ya que proporcionan una mejor escalabilidad.

imagen

Las integraciones de los prototipos de Weld con Spark (arriba a la izquierda), NumPy (arriba a la derecha) y TensorFlow (abajo a la izquierda) muestran una mejora de hasta 30 veces sobre sus propias implementaciones de infraestructura sin cambios en el código de la aplicación del usuario. La optimización de bibliotecas cruzadas de Pandas y NumPy (abajo a la derecha) puede mejorar el rendimiento en dos órdenes de magnitud.

¿Qué es baloo?


Baloo es una biblioteca que implementa un subconjunto de la API de Pandas utilizando Weld. Fue desarrollado por Radu Jica, un Master en CWI (Centrum Wiskunde & Informatica, Amsterdam). El objetivo de Baloo es aplicar los tipos de optimización anteriores a Pandas para mejorar el rendimiento de un solo subproceso, reducir el uso de memoria y garantizar la concurrencia.

¿Weld / Baloo admite operaciones externas (como, por ejemplo, Dask) para procesar datos que no caben en la memoria?


Weld y Baloo actualmente no admiten operaciones externas (fuera de núcleo, memoria externa), aunque estaremos encantados de recibir desarrollos de código abierto en esta dirección.

¿Por qué elegiste Rust y LLVM para implementar Weld? ¿Viniste a Rust de inmediato?


Elegimos Rust porque:

  • Tiene un tiempo de ejecución mínimo (de hecho, simplemente verifica los límites de las matrices) y es fácil de integrar en otros lenguajes como Java y Python
  • Contiene paradigmas de programación funcionales, como la coincidencia de patrones, que facilitan la escritura de código, por ejemplo, para optimizar el compilador de coincidencia de patrones
  • ( Rust crates), .

Elegimos LLVM porque es un marco de compilación de código abierto que es ampliamente utilizado y compatible. Generamos LLVM directamente en lugar de C / C ++, por lo que no necesitamos el compilador de C. También reduce el tiempo de compilación, ya que no analizamos el código de C / C ++.

Rust no fue el primer idioma en que se implementó Weld. La primera implementación fue en Scala, que fue elegida por sus tipos de datos algebraicos y la presencia de una característica tan poderosa como la coincidencia de patrones. Esto simplificó la escritura del optimizador, que es la parte principal del compilador. Nuestro optimizador original se hizo como Catalyst, un optimizador extensible en Spark SQL.

Nos alejamos de Scala porque era demasiado difícil integrar el lenguaje basado en JVM en otros tiempos de ejecución e idiomas.

Weld CPU GPU, RAPIDS, data science Python GPU?


La principal diferencia entre Weld y sistemas como RAPIDS es que tiene como objetivo optimizar aplicaciones que contienen diferentes núcleos (funciones en términos CUDA) compilando sobre la marcha, y no optimizando implementaciones de funciones individuales. Por ejemplo, el backend GPU Weld compilará un solo núcleo CUDA optimizado para la aplicación final, en lugar de invocar núcleos separados.

Además, Weld IR es independiente del hardware, lo que le permite ser utilizado tanto para la GPU como para la CPU, así como también para equipos no estándar como los procesadores vectoriales.
Por supuesto, Weld esencialmente se cruza con otros proyectos en el mismo campo, incluido RAPIDS, y se crea bajo su influencia.

Los entornos de tiempo de ejecución como Bohrium (implementa la computación diferida en NumPy) y Numba (biblioteca de Python, compilador de código JIT) comparten los objetivos de alto nivel de Weld. Y los sistemas optimizadores como Spark SQL influyen directamente en el diseño de Weld.

¿Weld tiene otros usos además de las optimizaciones de la biblioteca de ciencia de datos?


Uno de los aspectos más interesantes de Weld IR es que admite de forma nativa la concurrencia de datos. Esto significa que la paralelización de bucle en Weld IR siempre es segura. Esto hace que Weld IR sea atractivo para nuevos tipos de equipos.

Por ejemplo, los empleados de NEC usaron Weld para ejecutar cargas de trabajo de Python en un procesador de vectores de alto ancho de banda personalizado, simplemente agregando un nuevo back-end a un IR de Weld existente.

IR también se puede utilizar para implementar una capa de operaciones físicas en una base de datos. Y planeamos agregar características que también nos permitirán compilar un subconjunto de Python en el código de Weld.

¿Están las bibliotecas listas para usar en proyectos reales? Y si no, ¿cuándo puede esperar un resultado final?


Muchos de los ejemplos y puntos de referencia en los que probamos estas bibliotecas se toman de la carga de trabajo real. Por lo tanto, realmente nos gustaría que los usuarios prueben la versión actual en sus aplicaciones y dejen sus comentarios. Y, lo mejor de todo, propusieron sus propios parches.

En general, por el momento no se puede decir que en aplicaciones reales todo saldrá de la caja.

Nuestros próximos lanzamientos en los próximos meses se centrarán exclusivamente en la usabilidad y confiabilidad de las bibliotecas de Python. Nuestro objetivo es hacer que las bibliotecas sean lo suficientemente buenas para su inclusión en proyectos reales. Y también la capacidad de usar versiones de la biblioteca que no sean de Weld en lugares donde aún no se ha agregado soporte.

Como señalé en la primera pregunta, el proyecto de anotaciones Split ( código fuente y artículo académico ) debería simplificar esta transición.

Las anotaciones divididas es un sistema que le permite agregar anotaciones al código existente para determinar cómo dividirlo, transformarlo y paralelizarlo. Proporciona la optimización que consideramos más efectiva en Weld (almacenando fragmentos de datos en cachés de CPU entre llamadas de función, en lugar de escanear todo el conjunto de datos). Pero las anotaciones divididas son mucho más fáciles de integrar que Weld, ya que utilizan el código de la biblioteca existente sin depender del compilador IR. También facilita el mantenimiento y la depuración, lo que a su vez mejora la fiabilidad.

Las bibliotecas que aún no tienen soporte de soldadura completo pueden usar anotaciones divididas. Esto nos permitirá agregar gradualmente el soporte de Weld en función de los comentarios de los usuarios, al tiempo que incorpora nuevas optimizaciones.

All Articles