Acelera los modelos de última generación en Hugging Face 🤗 hasta un 2300 % (25 veces más rápido) con Databricks, Nvidia y Spark NLP 🚀 ViT Soy uno de los colaboradores del proyecto de código abierto y, recientemente, esta biblioteca comenzó a admitir modelos de extremo a extremo. Utilizo Spark NLP y otras bibliotecas de código abierto ML/DL para el trabajo diario y he decidido implementar una canalización de ViT para una tarea de clasificación de imágenes de última generación y proporcionar comparaciones detalladas entre y . Spark NLP Vision Transformers (ViT) Hugging Face Spark NLP El propósito de este artículo es demostrar cómo escalar los modelos Vision Transformer (ViT) de Hugging Face e implementarlos en entornos listos para producción para una inferencia acelerada y de alto rendimiento. Al final, escalaremos un modelo ViT de Hugging Face mediante el uso de Databricks, Nvidia y Spark NLP. 25 veces (2300 %) En este artículo voy a: Una breve introducción a Vision Transformer (ViT) Benchmark Hugging Face dentro del servidor Dell en CPU y GPU Benchmark Spark NLP dentro del servidor Dell en CPU y GPU Benchmark Hugging Face dentro de Databricks Single Node en CPU y GPU Benchmark Spark NLP dentro de Databricks Single Node en CPU y GPU Benchmark Spark NLP dentro de Databricks escalado a 10x Nodos con CPU y GPU ¡Resume todo! Con el espíritu de total transparencia, todos los cuadernos con sus registros, capturas de pantalla e incluso la hoja de Excel con números se proporcionan . aquí en GitHub Introducción a los modelos Vision Transformer (ViT) En 2017, un grupo de investigadores de Google AI publicó un artículo que introdujo una arquitectura de modelo de transformador que cambió todos los estándares de procesamiento de lenguaje natural (NLP). El documento describe un mecanismo novedoso llamado autoatención como un modelo nuevo y más eficiente para las aplicaciones del lenguaje. Por ejemplo, las dos familias más populares de modelos basados en transformadores son GPT y BERT. Un poco de historia de Transformer https://huggingface.co/course/chapter1/4 Hay un gran capítulo sobre " que recomiendo leer si está interesado. Cómo funcionan los transformadores " Aunque estos nuevos modelos basados en Transformer parecen estar revolucionando las tareas de NLP, su uso en Computer Vision (CV) se mantuvo bastante limitado. El campo de la visión artificial ha estado dominado por el uso de redes neuronales convolucionales (CNN) y existen arquitecturas populares basadas en CNN (como ResNet). Este había sido el caso hasta que otro equipo de investigadores, esta vez en Google Brain, presentó el (ViT) en junio de 2021 en un artículo titulado: "Transformador de visión" " Una imagen vale 16x16 palabras: transformadores para el reconocimiento de imágenes a escala ". Este documento representa un gran avance en lo que respecta al reconocimiento de imágenes mediante el uso del mismo mecanismo de autoatención que se utiliza en los modelos basados en transformadores, como BERT y GPT, como acabamos de analizar. En modelos de lenguaje basados en Transformed como BERT, la entrada es una oración (por ejemplo, una lista de palabras). Sin embargo, en los modelos ViT, primero dividimos una imagen en una cuadrícula de parches de subimagen, luego incrustamos cada parche con un proyecto lineal antes de que cada parche incrustado se convierta en un token. El resultado es una secuencia de parches de incrustaciones que pasamos al modelo similar a BERT. Una descripción general de la estructura del modelo ViT tal como se presentó en el artículo original de Google Research de 2021 Vision Transformer se enfoca en una mayor precisión pero con menos tiempo de cómputo. Al observar los puntos de referencia publicados en el documento, podemos ver que el tiempo de entrenamiento con el conjunto de datos (publicado por Google en junio de 2020) se redujo en un 80 %, aunque el estado de precisión es más o menos el mismo. Para obtener más información sobre el desempeño de ViT hoy, debe visitar su página en de Noisy Student Papers With Code : Comparación con el estado del arte en los puntos de referencia de clasificación de imágenes populares. ( ) https://arxiv.org/pdf/2010.11929.pdf También es importante mencionar que una vez que haya entrenado un modelo a través de la arquitectura ViT, puede entrenar previamente y ajustar su transformador tal como lo hace en NLP. (¡eso es genial en realidad!) Si comparamos los modelos ViT con las CNN, podemos ver que tienen una mayor precisión con un costo mucho menor para los cálculos. Puede usar modelos ViT para una variedad de tareas posteriores en Computer Vision, como la clasificación de imágenes, la detección de objetos y la segmentación de imágenes. Esto también puede ser específico del dominio en Atención médica, puede pre-entrenar/afinar sus modelos ViT para , , , y fracturas de fémur enfisema cáncer de mama COVID-19 enfermedad de Alzheimer.¹ Dejaré referencias al final de este artículo en caso de que quiera profundizar en cómo funcionan los modelos ViT. [1]: Inmersión profunda: Vision Transformers en Hugging Face Optimum Graphcore https://huggingface.co/blog/vision-transformers Algunos modelos ViT en acción Modelo Vision Transformer (ViT) ( ) entrenado previamente en ImageNet-21k (14 millones de imágenes, 21 843 clases) a una resolución de 224x224 y ajustado en ImageNet 2012 (1 millón de imágenes, 1000 clases) en resolución 224x224: vit-base-patch16–224 https://huggingface.co/google/vit-base-patch16-224 Modelos ViT perfeccionados utilizados para la clasificación de alimentos: — https://huggingface.co/nateraw/food https://huggingface.co/julien-c/hotdog-not-hotdog Sin embargo, existen limitaciones y restricciones para cualquier modelo DL/ML en lo que respecta a la predicción. No existe un modelo con una precisión del 100 %, así que tenlo en cuenta cuando los utilices para algo importante como el cuidado de la salud: https://www.akc.org/expert-advice/lifestyle/do-you-live-in-dog-state-or-cat-state/ — : https://huggingface.co /julien-c/hotdog-no-hotdog La imagen se tomó de: Modelo ViT ¿Podemos usar estos modelos de Hugging Face o ajustar nuevos modelos de ViT y usarlos para inferencia en producción real? ¿Cómo podemos escalarlos mediante el uso de servicios administrados para cómputos distribuidos como AWS EMR, Azure Insight, GCP Dataproc o Databricks? Con suerte, algunos de estos serán respondidos al final de este artículo. ¡Que comiencen los puntos de referencia! Algunos detalles sobre nuestros puntos de referencia: ImageNet mini: (>3K) — (>34K) 1- Conjunto de datos: muestra completo He descargado el conjunto de datos ImageNet 1000 (mini) de Kaggle: https://www.kaggle.com/datasets/ifigotin/imagenetmini-1000 Elegí el directorio de trenes con más de y lo llamé ya que todo lo que necesitaba eran suficientes imágenes para hacer puntos de referencia que toman más tiempo. Además, seleccioné aleatoriamente menos del 10 % del conjunto de datos completo y lo llamé que tiene para mis puntos de referencia más pequeños y también para ajustar los parámetros correctos, como el tamaño del lote. 34K imágenes imagenet-mini imagenet-mini-sample, 3544 imágenes El “ ” de Google 2- Modelo: vit-base-patch16–224 Usaremos este modelo de Google alojado en Hugging Face: https://huggingface.co/google/vit-base-patch16-224 🤗 & 🚀 3- Bibliotecas: Transformers Spark NLP Evaluación comparativa de Hugging Face en un servidor Bare Metal Modelo ViT en un Dell PowerEdge C4130 ¿Qué es un servidor bare-metal? Un servidor - es solo una computadora física que solo está siendo utilizada por un usuario. No hay hipervisor instalado en esta máquina, no hay virtualizaciones y todo se ejecuta directamente en el sistema operativo principal (Linux — Ubuntu): las especificaciones detalladas de las CPU, las GPU y la memoria de esta máquina están dentro de las computadoras portátiles. bare metal Como han revelado mis pruebas iniciales y casi todas las publicaciones de blog escritas por el equipo de ingeniería de Hugging Face que comparan la velocidad de inferencia entre los motores DL, el mejor rendimiento para la inferencia en la biblioteca Hugging Face (Transformer) se logra usando PyTorch sobre TensorFlow. No estoy seguro de si esto se debe a que TensorFlow es un ciudadano de segunda clase en Hugging Face debido a menos funciones compatibles, menos modelos compatibles, menos ejemplos, tutoriales obsoletos y encuestas anuales durante los últimos 2 años respondidas por usuarios que preguntan más por TensorFlow. o PyTorch simplemente tiene una latencia más baja en la inferencia tanto en la CPU como en la GPU. TensorFlow sigue siendo el marco de aprendizaje profundo más utilizado Independientemente de la razón, elegí PyTorch en la biblioteca Hugging Face para obtener los mejores resultados para nuestros puntos de referencia de clasificación de imágenes. Este es un fragmento de código simple para usar un modelo ViT (PyTorch, por supuesto) en Hugging Face: from PIL import Image import requests from transformers import ViTFeatureExtractor, ViTForImageClassification url = 'http://images.cocodataset.org/val2017/000000039769.jpg' image = Image.open(requests.get(url, stream= True ).raw) feature_extractor = ViTFeatureExtractor.from_pretrained( 'google/vit-base-patch16-224' ) model = ViTForImageClassification.from_pretrained( 'google/vit-base-patch16-224' ) inputs = feature_extractor(images=image, return_tensors= "pt" ) outputs = model(**inputs) logits = outputs.logits # model predicts one of the 1000 ImageNet classes predicted_class_idx = logits.argmax(- 1 ).item() print("Predicted class:", model.config.id2label [predicted_class_idx] ) Esto puede parecer sencillo para predecir una imagen como entrada, pero no es adecuado para grandes cantidades de imágenes, especialmente en una GPU. Para evitar predecir imágenes secuencialmente y aprovechar hardware acelerado como GPU, es mejor alimentar el modelo con lotes de imágenes, lo que es posible en Hugging Face a través de . No hace falta decir que puede implementar su técnica de procesamiento por lotes ya sea extendiendo las tuberías de Hugging Face o haciéndolo por su cuenta. Pipelines Una tubería simple para la se verá así: clasificación de imágenes from transformers import ViTFeatureExtractor, ViTForImageClassification from transformers import pipeline feature_extractor = ViTFeatureExtractor.from_pretrained( 'google/vit-base-patch16-224' ) model = ViTForImageClassification.from_pretrained( 'google/vit-base-patch16-224' ) pipe = pipeline( "image-classification" , model=model, feature_extractor=feature_extractor, device=- 1 ) Según la documentación, he descargado/cargado para el extractor de características y el modelo (puntos de control de PyTorch, por supuesto) para usarlos en la canalización con la clasificación de imágenes como tarea. Hay 3 cosas en esta tubería que son importantes para nuestros puntos de referencia: google/vit-base-patch16–224 : si es -1 (predeterminado), solo usará CPU, mientras que si es un número int positivo, ejecutará el modelo en la identificación del dispositivo CUDA asociado (es mejor ocultar las GPU y obligar a PyTorch a usar CPU y no solo confíe en este número aquí). > dispositivo cuando la canalización usará (al pasar un conjunto de datos, en GPU para un modelo Pytorch), el tamaño del lote a usar, para la inferencia, no siempre es beneficioso. > tamaño_lote: DataLoader Debe usar DataLoader o PyTorch Dataset para aprovechar al máximo el procesamiento por lotes en canalizaciones Hugging Face en una GPU. > Antes de avanzar con los puntos de referencia, debe saber una cosa sobre el procesamiento por lotes en Hugging Face Pipelines para la inferencia, que no siempre funciona. Como se indica en la documentación de Hugging Face, es posible que configurar no aumente en absoluto el rendimiento de su canalización. Puede ralentizar su canalización: batch_size https://huggingface.co/docs/transformers/main_classes/pipelines#pipeline-batching Para ser justos, en mis puntos de referencia utilicé una variedad de tamaños de lote a partir de 1 para asegurarme de que puedo encontrar el mejor resultado entre ellos. Así es como comparé la canalización Hugging Face en la CPU: from transformers import pipeline pipe = pipeline( "image-classification" , model=model, feature_extractor=feature_extractor, device=- 1 ) for batch_size in [ 1 , 8 , 32 , 64 , 128 ]: print ( "-" * 30 ) print ( f"Streaming batch_size= {batch_size} " ) for out in tqdm(pipe(dataset, batch_size=batch_size), total= len (dataset)): pass Echemos un vistazo a los resultados de nuestro primer punto de referencia para la tubería de clasificación de imágenes Hugging Face en CPU sobre el conjunto de datos ImageNet de muestra (3K): Tubería de clasificación de imágenes Hugging Face en CPU: predicción de 3544 imágenes Como se puede ver, tomó alrededor de 3 minutos ( terminar de procesar alrededor de del conjunto de datos de muestra. Ahora que sé qué tamaño de lote (8) es el mejor para mi tubería/conjunto de datos/hardware, puedo usar la misma tubería en un conjunto de datos más grande ( ) con este tamaño de lote: 188 segundos) 3544 imágenes imágenes de 34K Tubería de clasificación de imágenes Hugging Face en CPU: predicción de 34745 imágenes Esta vez tomó alrededor de 31 minutos ( ) terminar de predecir clases para en CPU. 1879 segundos 34745 imágenes Para mejorar la mayoría de los modelos de aprendizaje profundo, especialmente estos nuevos modelos basados en transformadores, se debe usar hardware acelerado como GPU. Echemos un vistazo a cómo comparar la misma canalización con los mismos conjuntos de datos, pero esta vez en un dispositivo . Como se mencionó anteriormente, necesitamos cambiar el a una identificación de dispositivo CUDA como 0 (la primera GPU): GPU dispositivo model = model.to(device) from transformers import ViTFeatureExtractor, ViTForImageClassification from transformers import pipeline import torch device = "cuda:0" if torch.cuda.is_available() else "cpu" print (device) feature_extractor = ViTFeatureExtractor.from_pretrained( 'google/vit-base-patch16-224' ) model = ViTForImageClassification.from_pretrained( 'google/vit-base-patch16-224' ) pipe = pipeline( "image-classification" , model=model, feature_extractor=feature_extractor, device= 0 ) for batch_size in [ 1 , 8 , 32 , 64 , 128 , 256 , 512 , 1024 ]: print ( "-" * 30 ) print ( f"Streaming batch_size= {batch_size} " ) for out in tqdm(pipe(dataset, batch_size=batch_size), total= len (dataset)): pass Además de establecer device=0, también seguí la forma recomendada de ejecutar un modelo PyTorch en un dispositivo GPU a través de .to(device). Dado que usamos hardware acelerado (GPU), también aumenté el tamaño máximo de lote para mis pruebas a 1024 para encontrar el mejor resultado. Echemos un vistazo a nuestra canalización de clasificación de imágenes Hugging Face en un dispositivo GPU sobre el conjunto de datos de ImageNet de muestra (3K): Tubería de clasificación de imágenes Hugging Face en una GPU: predicción de 3544 imágenes Como se puede ver, tomó alrededor de terminar de procesar alrededor de de nuestro conjunto de datos de minimuestra de imagenet en un . El procesamiento por lotes mejoró la velocidad, especialmente en comparación con los resultados provenientes de las CPU, sin embargo, las mejoras se detuvieron alrededor del tamaño de lote de 32. Aunque los resultados son los mismos después del tamaño de lote 32, he elegido el tamaño de lote para mi punto de referencia más grande para utilizar suficiente memoria GPU también. 50 segundos 3544 imágenes dispositivo GPU 256 Tubería de clasificación de imágenes Hugging Face en una GPU: predicción de 34745 imágenes Esta vez, nuestro punto de referencia tomó alrededor de 8:17 minutos ( ) para terminar de predecir clases para en un dispositivo . Si comparamos los resultados de nuestros puntos de referencia en CPU y un dispositivo GPU, podemos ver que la GPU aquí es la ganadora: 497 segundos 34745 imágenes GPU Hugging Face (PyTorch) es hasta 3,9 veces más rápido en GPU que en CPU Utilicé Hugging Face Pipelines para cargar los puntos de control de ViT PyTorch, cargar mis datos en el conjunto de datos de la antorcha y usar el procesamiento por lotes provisto listo para usar en el modelo tanto en la CPU como en la GPU. La es hasta más rápida en comparación con la ejecución de las mismas canalizaciones en las CPU. GPU ~3,9 veces Hemos mejorado nuestra canalización de ViT para realizar la clasificación de imágenes mediante el uso de un en lugar de CPU, pero ¿podemos aún más nuestra canalización tanto en como en en una sola máquina antes de escalarla a varias máquinas? Echemos un vistazo a la biblioteca Spark NLP. dispositivo de GPU mejorar CPU GPU Spark NLP: procesamiento de lenguaje natural de última generación Spark NLP es una biblioteca de procesamiento de lenguaje natural de última generación de código abierto ( ) https://github.com/JohnSnowLabs/spark-nlp Spark NLP es una biblioteca de procesamiento de lenguaje natural de última generación construida sobre Apache Spark. Proporciona anotaciones de NLP simples, eficaces y precisas para canalizaciones de aprendizaje automático que escalan fácilmente en un entorno distribuido. Spark NLP viene con más de y preentrenados en más de . También ofrece tareas como tokenización, segmentación de palabras, etiquetado de partes del discurso, incrustaciones de palabras y oraciones, reconocimiento de entidades nombradas, análisis de dependencias, revisión ortográfica, clasificación de textos, análisis de sentimientos, clasificación de tokens, traducción automática (+180 idiomas), Resumen y respuesta a preguntas, generación de texto, clasificación de imágenes (ViT) y muchas más . 7000 canalizaciones modelos 200 idiomas tareas de PNL Spark NLP es la única biblioteca NLP de código abierto en producción que ofrece transformadores de última generación como , , , , , , , , , , , , Google , , y Vision Transformer ( ) no solo para y , sino también para el ecosistema JVM ( , y ) a escala al extender Apache Spark de forma nativa. BERT CamemBERT ALBERT ELECTRA XLNet DistilBERT RoBERTa DeBERTa XLM-RoBERTa Longformer ELMO Universal Sentence Encoder T5 MarianMT GPT2 ViT Python R Java Scala Kotlin Evaluación comparativa de Spark NLP en un servidor bare metal Modelos ViT en un Dell PowerEdge C4130 Spark NLP tiene las mismas características de ViT para la de imágenes que Hugging Face que se agregaron en la versión reciente . La función se llama preentrenados para usar y un código simple para usar esta función en Spark NLP se ve así: clasificación 4.1.0 ViTForImageClassification, tiene más de 240 modelos listos , imageAssembler = ImageAssembler() \ imageClassifier = ViTForImageClassification \ pipeline = Pipeline(stages=[ imageAssembler, imageClassifier ]) from sparknlp.annotator import * from sparknlp.base import * from pyspark.ml import Pipeline .setInputCol( "image" ) \ .setOutputCol( "image_assembler" ) .pretrained( "image_classifier_vit_base_patch16_224" ) \ .setInputCols( "image_assembler" ) \ .setOutputCol( "class" ) \ .setBatchSize( 8 ) Si comparamos Spark NLP y Hugging Face uno al lado del otro para descargar y cargar un modelo ViT previamente entrenado para una predicción de clasificación de imágenes, además de cargar imágenes y usar cálculos posteriores como argmax fuera de la biblioteca Hugging Face, ambos son bastante sencillos. Además, ambos se pueden guardar y servir más tarde como canalización para reducir estas líneas a solo 1 línea de código: Carga y uso de modelos ViT para clasificación de imágenes en Spark NLP (izquierda) y Hugging Face (derecha) Dado que Apache Spark tiene un concepto llamado , no inicia la ejecución del proceso hasta que se llama a una . Las acciones en Apache Spark pueden ser .count() o .show() o .write() y muchas otras operaciones basadas en RDD que no abordaré ahora y que no necesitará conocer para este artículo. Por lo general, elijo contar () la columna de destino o escribir () los resultados en los discos para activar la ejecución de todas las filas en el DataFrame. Además, al igual que los puntos de referencia de Hugging Face, revisaré los tamaños de lote seleccionados para asegurarme de que puedo tener todos los resultados posibles sin perder el mejor resultado. Lazy Evaluation ACCIÓN Ahora, sabemos cómo cargar modelos de ViT en Spark NLP, también sabemos cómo desencadenar una acción para forzar el cálculo en todas las filas de nuestro DataFrame para comparar, y todo lo que queda por aprender es oneDNN de . Dado que el motor DL en Spark NLP es TensorFlow, también puede habilitar oneDNN para mejorar la velocidad en las CPU (como todo lo demás, debe probar esto para asegurarse de que mejora la velocidad y no al revés). También usaré esta bandera además de las CPU normales sin oneDNN habilitado oneAPI Deep Neural Biblioteca de red (oneDNN) Ahora que sabemos que todos los modelos ViT de Hugging Face también están disponibles en Spark NLP y cómo usarlos en una canalización, repetiremos nuestros puntos de referencia anteriores en el servidor de Dell completo para comparar CPU y GPU. Echemos un vistazo a los resultados de la canalización de clasificación de imágenes de Spark NLP en CPU sobre nuestro conjunto de datos ImageNet de muestra (3K): Canalización de clasificación de imágenes Spark NLP en una CPU sin oneDNN: predicción de 3544 imágenes Tomó alrededor de 2,1 minutos ( terminar de procesar alrededor de de nuestro conjunto de datos de muestra. Tener un conjunto de datos más pequeño para probar diferentes tamaños de lote es útil para elegir el tamaño de lote adecuado para su tarea, su conjunto de datos y su máquina. Aquí está claro que el es el mejor tamaño para que nuestra canalización brinde el mejor resultado. 130 segundos) 3544 imágenes tamaño de lote 16 También me gustaría habilitar para ver si en esta situación específica mejora mi punto de referencia en comparación con las CPU sin oneDNN. Puede habilitar oneDNN en Spark NLP configurando la variable de entorno de en Veamos qué sucede si habilito este indicador y vuelvo a ejecutar el punto de referencia anterior en la CPU para encontrar el mejor tamaño de lote: oneDNN TF_ENABLE_ONEDNN_OPTS 1. Canalización de clasificación de imágenes Spark NLP en una CPU con oneDNN: predicción de 3544 imágenes De acuerdo, claramente habilitar oneDNN para TensorFlow en esta situación específica mejoró nuestros resultados en al menos un 14 %. Ya que no tenemos que hacer/cambiar nada y todo lo que se necesita es exportar TF_ENABLE_ONEDNN_OPTS=1, voy a usar eso para el punto de referencia con un conjunto de datos más grande también para ver la diferencia. Aquí es unos segundos más rápido, pero el 14 % en el conjunto de datos más grande puede reducir minutos de nuestros resultados. Ahora que sé que el tamaño de lote de 16 para CPU sin oneDNN y el tamaño de lote de 2 para CPU con oneDNN habilitado tienen los mejores resultados, puedo continuar usando la misma canalización en un conjunto de datos más grande ( ): imágenes de 34K Canalización de clasificación de imágenes Spark NLP en CPU sin oneDNN: predicción de 34745 imágenes Esta vez, nuestro punto de referencia tomó alrededor de 24 minutos ( ) para terminar de predecir clases para en un dispositivo de sin oneDNN habilitado. Ahora veamos qué sucede si habilito oneDNN para TensorFlow y uso el tamaño de lote de 2 (los mejores resultados): 1423 segundos 34745 imágenes CPU Canalización de clasificación de imágenes Spark NLP en CPU con oneDNN: predicción de 34745 imágenes Esta vez tomó alrededor de 21 minutos ( ). Como se esperaba de nuestros puntos de referencia de muestra, podemos ver alrededor en los resultados que redujeron los minutos en comparación con no tener oneDNN habilitado. 1278 segundos del 11 % de mejoras Echemos un vistazo a cómo comparar la misma canalización en un dispositivo GPU. En Spark NLP, todo lo que necesita para usar GPU es iniciarlo con gpu=True cuando inicia la sesión de Spark NLP: chispa = chispanlp.start(gpu=Verdadero) # puedes configurar la memoria aquí también chispa = chispanlp.start(gpu=Verdadero, memoria="16g") ¡Eso es todo! Si tiene algo en su tubería que se puede ejecutar en GPU, lo hará automáticamente sin necesidad de hacer nada explícitamente. Echemos un vistazo a nuestra tubería de clasificación de imágenes Spark NLP en un dispositivo GPU sobre el conjunto de datos ImageNet de muestra (3K): Canalización de clasificación de imágenes NLP de Spark en una GPU: predicción de 3544 imágenes Por curiosidad para ver si mi cruzada para encontrar un buen tamaño de lote en un conjunto de datos más pequeño era correcta, ejecuté la misma canalización con GPU en un conjunto de datos más grande para ver si el tamaño de lote 32 tendría el mejor resultado: Canalización de clasificación de imágenes Spark NLP en una GPU: predicción de 34745 imágenes Afortunadamente, es el tamaño de lote 32 el que produce el mejor tiempo. Así que tomó alrededor de 4 minutos y medio ( 277 segundos). Seleccionaré los resultados de las ya que fueron más rápidos y los compararé con los resultados de la : CPU con oneDNN GPU Spark NLP (TensorFlow) es hasta 4,6 veces más rápido en GPU que en CPU (oneDNN) ¡Esto es genial! Podemos ver que Spark NLP en GPU es hasta que las CPU, incluso con oneDNN habilitado. 4,6 veces más rápido Echemos un vistazo a cómo se comparan estos resultados con los puntos de referencia de Hugging Face: Spark NLP es un 65 % más rápido que Hugging Face en CPU en la predicción de clases de imágenes para el conjunto de datos de muestra con imágenes de 3K y un 47 % en el conjunto de datos más grande con imágenes de 34K. Spark NLP también es un 79 % más rápido que Hugging Face en un solo conjunto de datos de inferencia de GPU más grande con imágenes de 34 000 y hasta un 35 % más rápido en un conjunto de datos más pequeño. Spark NLP fue más rápido que Hugging Face en una sola máquina al usar CPU o GPU: clasificación de imágenes con Vision Transformer (ViT) Spark NLP y Hugging Face en Databricks Todos sus datos, análisis e inteligencia artificial en una sola plataforma ¿Qué es un ladrillo de datos? Databricks es una plataforma basada en la nube con un conjunto de herramientas de ingeniería y ciencia de datos que muchas empresas utilizan ampliamente para procesar y transformar grandes cantidades de datos. Los usuarios usan Databricks para muchos propósitos, desde procesar y transformar grandes cantidades de datos hasta ejecutar muchas canalizaciones de ML/DL para explorar los datos. esta fue mi interpretación de Databricks, viene con muchas otras características y debería consultarlas: Descargo de responsabilidad: https://www.databricks.com/product/data-lakehouse Databricks es compatible con las nubes de AWS, Azure y GCP: https://www.databricks.com/product/data-lakehouse Abrazando la cara en un solo nodo de Databricks con CPU en AWS Databricks ofrece un tipo de clúster cuando está creando un clúster que es adecuado para aquellos que desean usar Apache Spark con solo 1 máquina o usar aplicaciones que no son Spark, especialmente bibliotecas de Python basadas en ML y DL. Hugging Face ya viene instalado cuando elige el tiempo de ejecución de Databricks 11.1 ML. Así es como se ven las configuraciones de clúster para mis Databricks de un solo nodo (solo CPU) antes de comenzar con nuestros puntos de referencia: de "nodo único" Clúster de un solo nodo de bricks: tiempo de ejecución de la CPU El resumen de este clúster que usa la instancia en es que tiene 1 controlador (solo 1 nodo), de memoria, de CPU y cuesta por hora. Puede leer sobre "DBU" en AWS aquí: m5n.8xlarge AWS 128 GB 32 núcleos 5,71 DBU https://www.databricks.com/product/aws-pricing Clúster único de Databricks: perfil de instancia de AWS Vamos a replicar nuestros puntos de referencia de la sección anterior (servidor Dell completo) aquí en nuestros Databricks de un solo nodo (solo CPU). Comenzamos con Hugging Face y nuestro conjunto de datos de tamaño de muestra de ImageNet para averiguar qué tamaño de lote es bueno para que podamos usarlo para el conjunto de datos más grande, ya que esto resultó ser una práctica comprobada en los puntos de referencia anteriores: Canalización de clasificación de imágenes Hugging Face en CPU de nodo único de Databricks: predicción de 3544 imágenes Tomó alrededor de 2 minutos y medio ( ) terminar de procesar alrededor de de nuestro conjunto de datos de muestra en un Databrick de un solo nodo que solo usa . El mejor tamaño de lote en esta máquina que usa solo CPU es , así que lo usaré para ejecutar el punto de referencia en el conjunto de datos más grande: 149 segundos 3544 imágenes CPU 8 Canalización de clasificación de imágenes de Hugging Face en CPU de nodo único de Databricks: predicción de 34745 imágenes En el conjunto de datos más grande con más de 34 000 imágenes, tomó alrededor de 20 minutos y medio ( ) terminar de predecir las clases para esas imágenes. Para nuestro próximo punto de referencia, necesitamos tener un clúster de Databricks de un solo nodo, pero esta vez necesitamos tener un tiempo de ejecución basado en GPU y elegir una instancia de AWS basada en GPU. 1233 segundos Abrazando la cara en un solo nodo de Databricks con una GPU en AWS Vamos a crear un nuevo clúster y esta vez vamos a elegir un tiempo de ejecución con GPU que en este caso se llama 11.1 ML (incluye Apache Spark 3.3.0, GPU, Scala 2.12) y viene con todo el software CUDA y NVIDIA instalado. Lo siguiente que necesitamos es seleccionar también una instancia de AWS que tenga una GPU y he elegido que tiene 1 GPU y una cantidad similar de núcleos/memoria que el otro clúster. Esta instancia de GPU viene con un y 15 GB memoria GPU utilizable). g4dn.8xlarge Tesla T4 16 GB de memoria ( Clúster de un solo nodo de bricks: tiempo de ejecución de GPU Este es el resumen de nuestro clúster de un solo nodo como el anterior y es el mismo en cuanto a la cantidad de núcleos y la cantidad de memoria, pero viene con una GPU Tesla T4: Clúster de nodo único de bricks: perfil de instancia de AWS Ahora que tenemos un clúster de un solo nodo con una GPU, podemos continuar con nuestras pruebas comparativas para ver cómo se desempeña Hugging Face en esta máquina en Databricks. Voy a ejecutar el punto de referencia en el conjunto de datos más pequeño para ver qué tamaño de lote es más adecuado para nuestra máquina basada en GPU: Canalización de clasificación de imágenes Hugging Face en CPU de nodo único de Databricks: predicción de 3544 imágenes Tomó alrededor de un minuto ( ) terminar de procesar alrededor de de nuestro conjunto de datos de muestra en nuestro clúster de Databricks de un solo nodo con un dispositivo GPU. El procesamiento por lotes mejoró la velocidad si observamos el resultado del tamaño de lote 1; sin embargo, después del tamaño de lote 8, los resultados se mantuvieron prácticamente iguales. Aunque los resultados son los mismos después del tamaño de lote 8, he elegido el tamaño de lote para mi punto de referencia más grande para utilizar también más memoria GPU. (para ser honesto, 8 y 256 se desempeñaron prácticamente de la misma manera) 64 segundos 3544 imágenes 256 Ejecutemos el punto de referencia en el conjunto de datos más grande y veamos qué sucede con el tamaño de lote 256: Canalización de clasificación de imágenes de Hugging Face en CPU de nodo único de Databricks: predicción de 34745 imágenes En un conjunto de datos más grande, tomó casi 11 minutos ( ) terminar de predecir las clases para más de 34 000 imágenes. Si comparamos los resultados de nuestros puntos de referencia en un solo nodo con CPU y un solo nodo que viene con 1 GPU, podemos ver que el nodo de GPU aquí es el ganador: 659 segundos Hugging Face (PyTorch) es hasta 2,3 veces más rápido en GPU que en CPU La es hasta más rápida en comparación con la ejecución de la misma canalización en CPU en Hugging Face en Databricks Single Node GPU ~2,3 veces Ahora vamos a ejecutar los mismos puntos de referencia utilizando Spark NLP en los mismos grupos y sobre los mismos conjuntos de datos para compararlo con Hugging Face. Evaluación comparativa de Spark NLP en un databrick de un solo nodo Primero, instalemos Spark NLP en sus CPU de Databricks de un solo nodo: En la pestaña dentro de su clúster, debe seguir estos pasos: — Instalar Nuevo -> PyPI -> -> Instalar — Instalar Nuevo -> Maven -> Coordenadas -> -> Instalar — Agregará ` ` a `Cluster->Opciones avanzadas->Spark->Variables de entorno` para habilitar oneDNN Bibliotecas spark-nlp==4.1.0 com.johnsnowlabs.nlp:spark-nlp_2.12:4.1.0 TF_ENABLE_ONEDNN_OPTS=1 Cómo instalar Spark NLP en Databricks en CPU para Python, Scala y Java Spark NLP en Databricks Single Node con CPU en AWS Ahora que tenemos Spark NLP instalado en nuestro clúster de un solo nodo de Databricks, podemos repetir los puntos de referencia para una muestra y conjuntos de datos completos en CPU y GPU. Comencemos con el punto de referencia en las CPU primero sobre el conjunto de datos de muestra: Canalización de clasificación de imágenes Spark NLP en CPU de nodo único de Databricks (oneDNN): predicción de 3544 imágenes Tomó alrededor de 2 minutos ( ) terminar de procesar y predecir sus clases en el mismo clúster de Databricks de un solo nodo con CPU que usamos para Hugging Face. Podemos ver que el tamaño de lote de 16 tiene el mejor resultado, así que lo usaré en el próximo punto de referencia en el conjunto de datos más grande: 111 segundos 3544 imágenes Canalización de clasificación de imágenes Spark NLP en CPU de nodo único de Databricks (oneDNN): predicción de 34742 imágenes En el conjunto de datos más grande con más de , tomó alrededor de 18 minutos ( ) terminar de predecir las clases para esas imágenes. A continuación, repetiré los mismos puntos de referencia en el clúster con GPU. 34 000 imágenes 1072 segundos Nodo único de Databricks con una GPU en AWS Primero, instale Spark NLP en su de Databricks de un solo nodo (la única diferencia es el uso de " de Maven): GPU spark-nlp-gpu" Instale en su — En la pestaña dentro del clúster, debe seguir estos pasos: — Instalar Nuevo -> PyPI -> -> Instalar — Instalar Nuevo -> Maven -> Coordenadas -> -> Instalar Spark NLP clúster de Databricks Bibliotecas spark-nlp==4.1.0 com.johnsnowlabs.nlp:spark-nlp-gpu_2.12:4.1.0 Cómo instalar Spark NLP en Databricks en GPU para Python, Scala y Java Voy a ejecutar el punto de referencia en el conjunto de datos más pequeño para ver qué tamaño de lote es más adecuado para nuestra máquina basada en GPU: Canalización de clasificación de imágenes Spark NLP en GPU de nodo único de Databricks: predicción de 3544 imágenes Se tardó menos de un minuto ( ) en terminar de procesar alrededor de de nuestro conjunto de datos de muestra en nuestros Databricks de un solo nodo con un dispositivo de GPU. Podemos ver que el funcionó mejor en este caso de uso específico, por lo que ejecutaré el punto de referencia en el conjunto de datos más grande: 47 segundos 3544 imágenes tamaño de lote 8 Canalización de clasificación de imágenes Spark NLP en GPU de nodo único de Databricks: predicción de 34742 imágenes En un conjunto de datos más grande, tomó casi 7 minutos y medio ( ) terminar de predecir clases para más de . Si comparamos los resultados de nuestros puntos de referencia en un solo nodo con CPU y un solo nodo que viene con 1 GPU, podemos ver que el nodo de GPU aquí es el ganador: 435 segundos 34 000 imágenes Spark NLP es hasta 2,5 veces más rápido en GPU que en CPU en Databricks Single Node ¡Esto es genial! Podemos ver que Spark NLP en GPU es hasta que en CPU, incluso con oneDNN habilitado (oneDNN mejora los resultados en CPU entre un 10 % y un 20 %). 2,5 veces más rápido Echemos un vistazo a cómo se comparan estos resultados con los puntos de referencia de Hugging Face en el mismo clúster de nodo único de Databricks: es hasta un más rápido que Hugging Face en en la predicción de clases de imágenes para el conjunto de datos de muestra con imágenes de 3K y hasta un en el conjunto de datos más grande con imágenes de 34K. también es un que Hugging Face en una sola para un conjunto de datos más grande con imágenes de 34K y hasta un en un conjunto de datos más pequeño con imágenes de 3K. Spark NLP 15 % CPU 34 % Spark NLP 51 % más rápido GPU 36 % más rápido es más rápido tanto en como en en comparación con Hugging en Databricks Single Node Spark NLP CPU GPU Face Escalando más allá de una sola máquina Hasta ahora, establecimos que en es más rápido que en en un servidor bare-metal y Databricks Single Node. Esto es lo que espera cuando compara GPU y CPU con estos nuevos modelos basados en transformadores. Hugging Face GPU Hugging Face CPU También hemos establecido que supera a para la misma canalización (modelo ViT), en los mismos conjuntos de datos, tanto en el servidor sin sistema operativo como en el clúster de un solo nodo de Databricks, y funciona mejor en dispositivos de CPU y GPU. Esto, por otro lado, no era algo que esperaba. Cuando estaba preparando este artículo, esperaba que la inferencia de TensorFlow en Spark NLP fuera un poco más lenta que la inferencia en Hugging Face usando PyTorch o al menos igualada. Estaba apuntando a esta sección, . Pero parece que Spark NLP es más rápido que Hugging Face incluso en una sola máquina, tanto en como en , en conjuntos de datos y . Spark NLP Hugging Face escalando la canalización más allá de una sola máquina CPU GPU grandes pequeños ¿Qué sucede si desea que su tubería de ViT sea aún más rápida? ¿Qué sucede si tiene conjuntos de datos aún más grandes y simplemente no puede colocarlos dentro de una máquina o simplemente toma demasiado tiempo recuperar los resultados? Pregunta: ¡Escalamiento horizontal! Esto significa que, en lugar de cambiar el tamaño de la misma máquina, agregue más máquinas a su clúster. Necesita algo para administrar todos esos trabajos/tareas/programar DAG/administrar tareas fallidas/etc. y esos tienen sus gastos generales, pero si necesita que algo sea más rápido o posible (más allá de una sola máquina), debe usar algún tipo de sistema distribuido. Respuesta: hacer que su máquina sea más grande o más rápida para que pueda manejar más carga. Ampliación = agregar más máquinas en paralelo para distribuir una carga. Escalamiento horizontal = Cara de abrazo ampliada: Mirar la página en el sitio web oficial de Hugging Face sugiere que la inferencia de escala solo es posible mediante el uso de Multi-GPU. Como describimos qué es el escalado horizontal, esto todavía está atascado en una sola máquina: https://huggingface.co/docs/transformers/performance Además, sin mencionar que la solución para en Hugging Face no existe en este momento: Multi-GPU inferencia https://huggingface.co/docs/transformers/perf_infer_gpu_many Por lo tanto, parece que no existe una forma nativa/oficial de canalizaciones de Hugging Face. Puede implementar su arquitectura que consta de algunos microservicios, como una cola de trabajos, protocolos de mensajería, backend de API RESTful y algunos otros componentes necesarios para distribuir cada solicitud en diferentes máquinas, pero esto escala las solicitudes de usuarios individuales en lugar de escalar el sistema real. sí mismo. ampliar las Además, la latencia de dichos sistemas no es comparable con los sistemas distribuidos de forma nativa, como Apache Spark (gRPC puede reducir esta latencia, pero aún así no es competitivo). Sin mencionar el problema del punto único de falla, la administración de trabajos/tareas/entradas fallidas y cientos de otras características que obtiene de Apache Spark y que ahora debe implementar/mantener usted mismo. Hay una publicación de blog en el sitio web de Hugging Face que representa la misma arquitectura al escalar los puntos finales REST para servir a más usuarios: " ". Sin embargo, creo que otras compañías están utilizando enfoques similares para escalar Hugging Face. , todos están escalando la cantidad de usuarios/solicitudes que llegan a los puntos finales REST de inferencia. Además, no puede escalar Hugging Face de esta manera en Implementación de 🤗 ViT en Kubernetes con TF Serving Databricks. Por ejemplo, la inferencia dentro de fastAPI es 10 veces más lenta que la inferencia local: https://towardsdatascience.com/hugging-face-transformer-inference-under-1-millisecond-latency-e1be0057a51c Una vez que Hugging Face ofrezca algunas soluciones nativas para escalar, volveré a ejecutar los puntos de referencia nuevamente. Hasta entonces, no hay escalamiento cuando tiene que recorrer el conjunto de datos desde una sola máquina para llegar a los puntos finales REST en un algoritmo de turno rotativo. (Piense de nuevo en la parte en la que agrupamos filas/secuencias/imágenes para alimentar la GPU de una sola vez, luego lo obtendrá) Escalamiento horizontal de Spark NLP: Spark NLP es una extensión de Spark ML, por lo tanto, se escala de forma nativa y sin problemas en todas las plataformas compatibles con Apache Spark, como (y no limitadas) Databricks, AWS EMR, Azure Insight, GCP Dataproc, Cloudera, SageMaker, Kubernetes y muchas más. ¡Se necesitan cambios de código cero! ¡Spark NLP puede escalar desde una sola máquina a un número infinito de máquinas sin cambiar nada en el código! Tampoco necesita exportar ningún modelo fuera de Spark NLP para usarlo en una biblioteca completamente diferente para acelerar o escalar la inferencia. Ecosistema Spark NLP: integraciones optimizadas, probadas y compatibles Databricks multinodo con CPU en AWS Vamos a crear un clúster y esta vez elegimos dentro del . Esto significa que podemos tener más de 1 nodo en nuestro clúster, lo que en la terminología de Apache Spark significa 1 controlador y N número de trabajadores (ejecutores). Estándar modo Clúster También necesitamos instalar Spark NLP en este nuevo clúster a través de la pestaña Bibliotecas. Puede seguir los pasos que mencioné en la sección anterior para Databricks de un solo nodo con CPU. Como puede ver, elegí la misma instancia de AWS basada en CPU que usé para comparar tanto Hugging Face como Spark NLP para que podamos ver cómo se escala cuando agregamos más nodos. Así es como se ven nuestras configuraciones de clúster: Clúster de varios nodos (estándar) de bricks con solo CPU Reutilizaré la misma canalización de Spark NLP que usé en los puntos de referencia anteriores y también solo usaré el conjunto de datos más grande con imágenes de 34K. ¡Vamos a empezar! (no es necesario cambiar ningún código) Escale Spark NLP en CPU con 2x nodos Databricks con 2x nodos: solo CPU Solo agreguemos 1 nodo más y hagamos el total de las máquinas que realizarán el procesamiento en 2 máquinas. No olvidemos la belleza de Spark NLP cuando pasa de una configuración de una sola máquina (su Colab, Kaggle, Databricks Single Node o incluso su computadora portátil Jupyter local) a una configuración de clúster de varios nodos (Databricks, EMR, GCP, Azure, Cloudera , YARN, Kubernetes, etc.), ¡se requiere un cambio de código cero! ¡Y me refiero a cero! Con eso en mente, ejecutaré el mismo punto de referencia dentro de este nuevo clúster en los conjuntos de datos más grandes con imágenes de 34K: Canalización de clasificación de imágenes Spark NLP en con CPU (oneDNN): predicción de 34742 imágenes 2x nodos Le tomó alrededor ( ) terminar de predecir clases para imágenes de 34K. Comparemos este resultado en con Spark NLP y los resultados de Hugging Face en un solo nodo de Databricks (seguiré repitiendo los resultados de Hugging Face en un solo nodo como referencia, ya que Hugging Face no se pudo escalar en varias máquinas, especialmente en Databricks) : de 9 minutos 550 segundos 2x nodos es que Hugging Face con Spark NLP un 124 % más rápido 2x nodos Anteriormente, Spark NLP venció a Hugging Face en un clúster de Databricks de un solo nodo usando solo CPU en un . 15 % Esta vez, al tener solo 2x nodos en lugar de 1 nodo, Spark NLP finalizó el proceso de más de 34 000 imágenes un 124 % más rápido que Hugging Face. Scale Spark NLP en CPU con 4x nodos Dupliquemos el tamaño de nuestro clúster como antes y pasemos de a Así es como se vería el clúster con 4x nodos: 2x Nodos 4x Nodos. Databricks con 4x nodos: solo CPU Ejecutaré el mismo punto de referencia en este nuevo clúster en los conjuntos de datos más grandes con imágenes de 34K: Canalización de clasificación de imágenes Spark NLP en con CPU (oneDNN): predicción de 34742 imágenes 4x nodos Le tomó alrededor ( ) terminar de predecir clases para imágenes de 34K. Comparemos este resultado en con Spark NLP frente a Hugging Face en CPU en Databricks: de 5 minutos 289 segundos 4x nodos es que Hugging Face con Spark NLP un 327 % más rápido 4x nodos Como puede verse, Spark NLP ahora es que Hugging Face en las CPU mientras usa solo en Databricks. un 327 % más rápido 4x nodos Escale Spark NLP en CPU con nodos 8x Ahora dupliquemos el clúster anterior agregando 4x Nodos más y hagamos un total de . Por cierto, este cambio de tamaño del clúster es bastante fácil, solo aumenta la cantidad de trabajadores en las configuraciones de su clúster: 8x Nodos Cambiar el tamaño de Spark Cluster en Databricks Ladrillos de datos con nodos 8x: solo CPU Ejecutemos el mismo punto de referencia esta vez en 8x Nodes: Canalización de clasificación de imágenes Spark NLP en con CPU (oneDNN): predicción de 34742 imágenes 8x nodos Le tomó más de 2 minutos y medio ( ) terminar de predecir clases para imágenes de 34K. Comparemos este resultado en con Spark NLP frente a Hugging Face en CPU en Databricks: 161 segundos 8x Nodes es que Hugging Face con Spark NLP un 666 % más rápido 8x nodos Como puede verse, Spark NLP ahora es que Hugging Face en las CPU mientras usa solo en Databricks. un 666 % más rápido 8x Nodes ¡Simplemente ignoremos el número de 6s aquí! (fue 665.8% si te hace sentir mejor) Escale Spark NLP en CPU con 10x nodos Para finalizar nuestras predicciones de modelos ViT de escalamiento horizontal en CPU en Databricks mediante Spark NLP, cambiaré el tamaño del clúster una vez más y lo aumentaré a 10x Nodos: Databricks con 10x nodos: solo CPU Ejecutemos el mismo punto de referencia esta vez en 10x Nodes: Canalización de clasificación de imágenes Spark NLP en con CPU (oneDNN): predicción de 34742 imágenes 10x nodos Le tomó menos de ( ) terminar de predecir clases para imágenes de 34K. Comparemos este resultado en con todos los resultados anteriores de Spark NLP vs. Hugging Face en CPU en Databricks: 2 minutos 112 segundos 10x Nodes es que Hugging Face con Spark NLP 1000% más rápido 10x Nodos ¡Y así es como se modelo Vision Transformer proveniente de Hugging Face en usando en Databricks! Nuestra canalización ahora es que Hugging Face en las CPU. escala el 10x Nodes Spark NLP 1000 % más rápida Logramos hacer que nuestra canalización de un que Hugging Face, que está atascada en 1 solo nodo, simplemente usando Spark NLP, pero solo usamos . Veamos si podemos obtener las mismas mejoras escalando nuestra canalización en un . ViT sea 1000 % más rápida CPU clúster de GPU Databricks multinodo con GPU en AWS Tener un clúster de Databricks de varios nodos basado en GPU es prácticamente lo mismo que tener un clúster de un solo nodo. La única diferencia es elegir y mantener el mismo tiempo de ejecución de ML/GPU con las mismas especificaciones de instancias de AWS que elegimos en nuestros puntos de referencia para GPU en un solo nodo. Estándar También necesitamos instalar Spark NLP en este nuevo clúster a través de la pestaña . Igual que antes, puede seguir los pasos que mencioné en Databricks de un solo nodo con una GPU. Bibliotecas Clúster de varios nodos (estándar) de bricks de datos con GPU Escale Spark NLP en GPU con 2x nodos Nuestro clúster de GPU de Databricks de varios nodos utiliza la misma instancia de GPU de AWS de que usamos anteriormente para ejecutar nuestros puntos de referencia para comparar Spark NLP con Hugging Face en un clúster de Databricks de un solo nodo. g4dn.8xlarge Este es un resumen de cómo se ve esta vez con 2 nodos: Databricks con 2x nodos: con 1 GPU por nodo Voy a ejecutar la misma canalización en este clúster de GPU con 2x nodos: Canalización de clasificación de imágenes Spark NLP en con GPU: predicción de 34742 imágenes 2x nodos Le tomó 4 minutos ( ) terminar de predecir clases para . Comparemos este resultado en con Spark NLP frente a Hugging Face en GPU en Databricks: 231 segundos imágenes de 34K 2x nodos es que Hugging Face con Spark NLP un 185 % más rápido 2x nodos Spark NLP con es casi ( ) que Hugging Face en 1 solo nodo mientras usa 2x Nodes 3x veces más rápido 185 % GPU. Escale Spark NLP en GPU con nodos 4x Redimensionemos nuestro clúster de GPU de 2x Nodos a Este es un resumen de cómo se ve esta vez con usando una GPU: 4x Nodos. 4x Nodes Databricks con 4x nodos: con 1 GPU por nodo Ejecutemos el mismo punto de referencia en 4x Nodes y veamos qué sucede: Canalización de clasificación de imágenes Spark NLP en con GPU: predicción de 34742 imágenes nodos 4x Esta vez tomó casi 2 minutos ( ) terminar de clasificar todas las en nuestro conjunto de datos. Visualicemos esto solo para tener una mejor visión de lo que esto significa en términos de Hugging Face en un solo nodo frente a Spark NLP en un clúster de varios nodos: 118 segundos imágenes de 34K es que Hugging Face con Spark NLP un 458 % más rápido 4x nodos Eso es un en comparación con Hugging Face. Acabamos de hacer que nuestra canalización mediante el uso de Spark NLP con 458 % más de rendimiento sea 5,6 veces más rápida nodos 4x. Escale Spark NLP en GPU con nodos 8x A continuación, cambiaré el tamaño del clúster para tener en mis Databricks con el siguiente resumen: 8x nodos Databricks con 8x nodos: con 1 GPU por nodo Solo como recordatorio, cada instancia de AWS ( ) tiene 1 (15 GB de memoria utilizable). Volvamos a ejecutar el punto de referencia y veamos si podemos detectar alguna mejora, ya que el escalado horizontal en cualquier sistema distribuido tiene sus gastos generales y no puede seguir agregando máquinas: g4dn.8xlarge GPU NVIDIA T4 de 16 GB Canalización de clasificación de imágenes Spark NLP en con GPU: predicción de 34742 imágenes nodos 8x Se tardó casi un minuto ( ) en terminar de clasificar de 34 000 con en nuestro clúster de Databricks. Parece que todavía logramos mejorar el rendimiento. Pongamos este resultado junto a los resultados anteriores de Hugging Face en un solo nodo frente a Spark NLP en un clúster de varios nodos: 61 segundos imágenes nodos 8x es que Hugging Face con Spark NLP 980% más rápido 8x Nodes Spark NLP con es casi que Hugging Face en GPU. 8x Nodes 11x veces más rápido (980 %) Escale Spark NLP en GPU con 10x nodos De manera similar a nuestros puntos de referencia de múltiples nodos en CPU, me gustaría cambiar el tamaño del clúster de GPU una vez más para tener y hacerlos coincidir en términos de la cantidad final de nodos. El resumen final de este clúster es el siguiente: 10x Nodos Databricks con 10x nodos: con 1 GPU por nodo Ejecutemos nuestro último punto de referencia en este clúster de GPU específico (sin cambios de código): Canalización de clasificación de imágenes Spark NLP en con GPU: predicción de 34742 imágenes 10x nodos Le tomó menos de un minuto ( ) terminar de predecir las clases para más de . Pongámoslos todos uno al lado del otro y veamos cómo progresamos escalando nuestro modelo Vision Transformer proveniente de Hugging Face en la canalización Spark NLP en Databricks: 51 segundos 34743 imágenes es que Hugging Face con Spark NLP 1200% más rápido 10x Nodos ¡Y hemos terminado! ¡Logramos nuestro modelo proveniente de Hugging Face en usando en Databricks! Nuestra canalización ahora es con comparación con Hugging Face en GPU. escalar Vision Transformer 10x Nodes Spark NLP 13 veces más rápida mejoras de rendimiento del 1200 % en Resumamos todos estos puntos de referencia comparando primero las mejoras entre las CPU y las GPU, y luego cuánto más rápido puede ser nuestra canalización al pasar de las CPU Hugging Face a 10x Nodes en Databricks usando Spark NLP en las GPU. Juntándolo todo: Ladrillos de datos: nodo único y nodos múltiples Spark NLP 🚀 en 10x Nodos con CPU es 1000% (11x veces) más rápido que Hugging Face 🤗 atascado en un solo nodo con CPU Spark NLP 🚀 en 10x Nodos con GPU es 1192 % (13x veces) más rápido que Hugging Face 🤗 atascado en un solo nodo con GPU ¿Qué pasa con las diferencias de precio entre nuestra instancia de CPU de AWS y la instancia de GPU de AWS? (Quiero decir, obtienes más si pagas más, ¿verdad?) con CPU frente a con 1 GPU y especificaciones similares AWS m5d.8xlarge AWS g4dn.8xlarge OK, ¡entonces el precio parece más o menos el mismo! Con eso en mente, ¿qué mejoras obtienes si pasas de en atascadas en una sola máquina a en con ? Hugging Face CPU Spark NLP 10x Nodes 10x GPU en GPU es que Hugging Face en CPU Spark NLP 25 veces (2366 %) más rápido Spark NLP 🚀 en 10x Nodos con GPU es 2366 % (25x veces) más rápido que Hugging Face 🤗 en un solo nodo con CPU Ultimas palabras Con el espíritu de total transparencia, todos los cuadernos con sus registros, capturas de pantalla e incluso la hoja de Excel con números se proporcionan . aquí en GitHub Escalar Spark NLP requiere cero cambios de código. Ejecutar los puntos de referencia desde un solo nodo Databricks a los 10 nodos significaba simplemente volver a ejecutar el mismo bloque de código en el mismo cuaderno. Tenga en cuenta que estas dos bibliotecas vienen con muchas mejores prácticas para optimizar su velocidad y eficiencia en diferentes entornos para diferentes casos de uso. Por ejemplo, no hablé sobre las particiones y su relación con el paralelismo y las distribuciones en Apache Spark. Hay muchas configuraciones de Spark para ajustar un clúster, especialmente equilibrando la cantidad de tareas entre CPU y GPU. Ahora la pregunta es, ¿sería posible acelerar alguno de ellos dentro de los mismos entornos que usamos para nuestros puntos de referencia? ¡La respuesta es 100%! Traté de mantener todo para ambas bibliotecas con valores predeterminados y funciones listas para usar en favor de la simplicidad para la mayoría de los usuarios. Es posible que desee envolver Hugging Face y otras bibliotecas Pythonish basadas en DL en un Spark UDF para escalarlas. Esto funciona hasta cierto punto, ya que lo he hecho yo mismo y todavía lo hago (cuando no hay una solución nativa). No entraré en los detalles del uso excesivo de la memoria, los posibles problemas de serialización, la latencia más alta y otros problemas cuando uno envuelve estos modelos basados en transformadores en una UDF. Solo diría que si está utilizando Apache Spark, use la biblioteca que amplía de forma nativa las funciones requeridas en Apache Spark. A lo largo de este artículo, hice todo lo posible para mencionar Hugging Face en PyTorch y Spark NLP en TensorFlow. Esta es una gran diferencia dado el hecho de que en cada punto de referencia realizado por Hugging Face entre PyTorch y TensorFlow, PyTorch fue y sigue siendo el ganador de la inferencia. En Hugging Face, PyTorch tiene una latencia mucho más baja y parece ser mucho más rápido que TensorFlow en Transformers. El hecho de que Spark NLP use el mismo TensorFlow y salga adelante en todos los puntos de referencia en comparación con PyTorch en Hugging Face es un gran problema. O se descuida el TensorFlow en Hugging Face, o PyTorch es simplemente más rápido en la inferencia en comparación con TensorFlow. De cualquier manera, no puedo esperar a ver qué sucede cuando Spark NLP comience a admitir TorchScript y ONNX Runtime además de TensorFlow. Los tiempos de ejecución de ML y ML GPU Databricks vienen con Hugging Face instalado, eso es bastante bueno. Pero eso no significa que Hugging Face sea fácil de usar en Databricks. La biblioteca Transformer de Hugging Face no admite DBFS (el sistema de archivos nativo distribuido de Databricks) ni Amazon S3. Como puede ver en los cuadernos, tuve que descargar una versión comprimida de los conjuntos de datos y extraerlos para usarlos. No es realmente así como hacen las cosas los usuarios de Databricks y otras plataformas en producciones. Mantenemos nuestros datos dentro de sistemas de archivos distribuidos, hay medidas de seguridad implementadas y la mayoría de ellos son lo suficientemente grandes como para que no puedan ser descargados por una computadora personal. Tuve que descargar los conjuntos de datos que ya tenía en DBFS, comprimirlos, cargarlos en S3, hacerlos públicos y volver a descargarlos en los cuadernos. Un proceso bastante tedioso que podría haberse evitado si Hugging Face fuera compatible con DBFS/S3. Referencias vit https://arxiv.org/pdf/2010.11929.pdf https://github.com/google-research/vision_transformer Transformadores de visión (ViT) en reconocimiento de imágenes: guía 2022 https://github.com/lucidrains/vit-pytorch https://medium.com/mlearning-ai/an-image-is-worth-16x16-words-transformers-for-image-recognition-at-scale-51f3561a9f96 https://medium.com/nerd-for-tech/an-image-is-worth-16x16-words-transformers-for-image-recognition-at-scale-paper-summary-3a387e71880a https://gareemadhingra11.medium.com/resumen-de-papel-una-imagen-vale-16x16-palabras-3f7f3aca941 https://medium.com/analytics-vidhya/vision-transformers-bye-bye-convolutions-e929d022e4ab https://medium.com/syncedreview/google-brain-uncovers-representation-structure-differences- between-cnns-and-vision-transformers-83b6835dbbac cara de abrazo https://huggingface.co/docs/transformers/main_classes/pipelines https://huggingface.co/blog/fine-tune-vit https://huggingface.co/blog/vision-transformers https://huggingface.co/blog/tf-serving-vision https://huggingface.co/blog/deploy-tfserving-kubernetes https://huggingface.co/google/vit-base-patch16-224 https://huggingface.co/blog/deploy-vertex-ai https://huggingface.co/models?other=vit Ladrillos de datos https://www.databricks.com/spark/getting-started-with-apache-spark https://docs.databricks.com/getting-started/index.html https://docs.databricks.com/getting-started/quick-start.html Vea lo mejor de DATA+AI SUMMIT 2022 https://www.databricks.com/blog/2020/05/15/shrink-training-time-and-cost-using-nvidia-gpu-accelerated-xgboost-and-apache-spark-on-databricks.html Chispa PNL Spark PNL GitHub Spark NLP (ejemplos de Spark NLP) Taller de Transformadores Spark NLP Centro de modelos Spark NLP Optimización de velocidad y puntos de referencia en Spark NLP 3: aprovechar al máximo el hardware moderno Aceleración de hardware en Spark NLP Sirviendo Spark NLP a través de API: Spring y LightPipelines Sirviendo Spark NLP a través de API (1/3): Synapse ML de Microsoft Sirviendo Spark NLP a través de API (2/3): FastAPI y LightPipelines Sirviendo Spark NLP a través de API (3/3): Trabajos de Databricks y API de MLFlow Serve Aproveche el aprendizaje profundo en Scala con GPU en Spark 3.0 Primeros pasos con Apache Spark 3 acelerado por GPU Ajuste del rendimiento de Apache Spark Posibles optimizaciones adicionales en las GPU: Acelerador RAPIDS para la configuración de Apache Spark