Soy uno de los colaboradores del proyecto de código abierto Spark NLP y, recientemente, esta biblioteca comenzó a admitir modelos Vision Transformers (ViT) 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 Hugging Face y 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 25 veces (2300 %) mediante el uso de Databricks, Nvidia y Spark NLP.
En este artículo voy a:
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 .
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 " Cómo funcionan los transformadores " que recomiendo leer si está interesado.
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 "Transformador de visión" (ViT) en junio de 2021 en un artículo titulado: " 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 de Noisy Student (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 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 fracturas de fémur , enfisema , cáncer de mama , COVID-19 y 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
Modelo Vision Transformer (ViT) ( vit-base-patch16–224 ) 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:
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:
La imagen se tomó de: https://www.akc.org/expert-advice/lifestyle/do-you-live-in-dog-state-or-cat-state/ — Modelo ViT : https://huggingface.co /julien-c/hotdog-no-hotdog
¿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.
Algunos detalles sobre nuestros puntos de referencia:
1- Conjunto de datos: ImageNet mini: muestra (>3K) — completo (>34K)
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 34K imágenes y lo llamé imagenet-mini 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é imagenet-mini-sample, que tiene 3544 imágenes para mis puntos de referencia más pequeños y también para ajustar los parámetros correctos, como el tamaño del lote.
2- Modelo: El “ vit-base-patch16–224 ” de Google
Usaremos este modelo de Google alojado en Hugging Face: https://huggingface.co/google/vit-base-patch16-224
3- Bibliotecas: Transformers 🤗 & Spark NLP 🚀
Modelo ViT en un Dell PowerEdge C4130
¿Qué es un servidor bare-metal? Un servidor bare - metal 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.
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 transformers import ViTFeatureExtractor, ViTForImageClassification from PIL import Image import requests 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 Pipelines . 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.
Una tubería simple para la clasificación de imágenes se verá así:
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 google/vit-base-patch16–224 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:
> dispositivo : 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í).
> tamaño_lote: cuando la canalización usará DataLoader (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.
> 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 batch_size no aumente en absoluto el rendimiento de su canalización. Puede ralentizar su canalización:
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 ( 188 segundos) terminar de procesar alrededor de 3544 imágenes 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 ( imágenes de 34K ) con este tamaño de lote:
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 ( 1879 segundos ) terminar de predecir clases para 34745 imágenes en CPU.
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 GPU . Como se mencionó anteriormente, necesitamos cambiar el dispositivo a una identificación de dispositivo CUDA como 0 (la primera GPU):
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' ) model = model.to(device) 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 50 segundos terminar de procesar alrededor de 3544 imágenes de nuestro conjunto de datos de minimuestra de imagenet en un dispositivo GPU . 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 256 para mi punto de referencia más grande para utilizar suficiente memoria GPU también.
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 ( 497 segundos ) para terminar de predecir clases para 34745 imágenes en un dispositivo GPU . Si comparamos los resultados de nuestros puntos de referencia en CPU y un dispositivo GPU, podemos ver que la GPU aquí es la ganadora:
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 GPU es hasta ~3,9 veces más rápida en comparación con la ejecución de las mismas canalizaciones en las CPU.
Hemos mejorado nuestra canalización de ViT para realizar la clasificación de imágenes mediante el uso de un dispositivo de GPU en lugar de CPU, pero ¿podemos mejorar aún más nuestra canalización tanto en CPU como en GPU en una sola máquina antes de escalarla a varias máquinas? Echemos un vistazo a la biblioteca Spark NLP.
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 7000 canalizaciones y modelos preentrenados en más de 200 idiomas . 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 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 BERT , CamemBERT , ALBERT , ELECTRA , XLNet , DistilBERT , RoBERTa , DeBERTa , XLM-RoBERTa , Longformer , ELMO , Universal Sentence Encoder , Google T5 , MarianMT , GPT2 y Vision Transformer ( ViT ) no solo para Python y R , sino también para el ecosistema JVM ( Java , Scala y Kotlin ) a escala al extender Apache Spark de forma nativa.
Modelos ViT en un Dell PowerEdge C4130
Spark NLP tiene las mismas características de ViT para la clasificación de imágenes que Hugging Face que se agregaron en la versión reciente 4.1.0 . La función se llama ViTForImageClassification, tiene más de 240 modelos preentrenados listos para usar , y un código simple para usar esta función en Spark NLP se ve así:
from sparknlp.annotator import * from sparknlp.base import * from pyspark.ml import Pipeline imageAssembler = ImageAssembler() \ .setInputCol( "image" ) \ .setOutputCol( "image_assembler" ) imageClassifier = ViTForImageClassification \ .pretrained( "image_classifier_vit_base_patch16_224" ) \ .setInputCols( "image_assembler" ) \ .setOutputCol( "class" ) \ .setBatchSize( 8 ) pipeline = Pipeline(stages=[ imageAssembler, imageClassifier ])
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 Lazy Evaluation , no inicia la ejecución del proceso hasta que se llama a una ACCIÓN . 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.
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 oneAPI Deep Neural Biblioteca de red (oneDNN) . 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
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 ( 130 segundos) terminar de procesar alrededor de 3544 imágenes 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 tamaño de lote 16 es el mejor tamaño para que nuestra canalización brinde el mejor resultado.
También me gustaría habilitar oneDNN 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 TF_ENABLE_ONEDNN_OPTS en 1. 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:
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 ( 1423 segundos ) para terminar de predecir clases para 34745 imágenes en un dispositivo de CPU sin oneDNN habilitado. Ahora veamos qué sucede si habilito oneDNN para TensorFlow y uso el tamaño de lote de 2 (los mejores resultados):
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 ( 1278 segundos ). Como se esperaba de nuestros puntos de referencia de muestra, podemos ver alrededor del 11 % de mejoras en los resultados que redujeron los minutos en comparación con no tener oneDNN habilitado.
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 CPU con oneDNN ya que fueron más rápidos y los compararé con los resultados de la 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 4,6 veces más rápido que las CPU, incluso con oneDNN habilitado.
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)
¿Qué es un ladrillo de datos? Todos sus datos, análisis e inteligencia artificial en una sola plataforma
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.
Descargo de responsabilidad: esta fue mi interpretación de Databricks, viene con muchas otras características y debería consultarlas: 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 de "nodo único" 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:
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 m5n.8xlarge en AWS es que tiene 1 controlador (solo 1 nodo), 128 GB de memoria, 32 núcleos de CPU y cuesta 5,71 DBU por hora. Puede leer sobre "DBU" en AWS aquí: 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 ( 149 segundos ) terminar de procesar alrededor de 3544 imágenes de nuestro conjunto de datos de muestra en un Databrick de un solo nodo que solo usa CPU . El mejor tamaño de lote en esta máquina que usa solo CPU es 8 , así que lo usaré para ejecutar el punto de referencia en el conjunto de datos más grande:
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 ( 1233 segundos ) 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.
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 g4dn.8xlarge que tiene 1 GPU y una cantidad similar de núcleos/memoria que el otro clúster. Esta instancia de GPU viene con un Tesla T4 y 16 GB de memoria ( 15 GB memoria GPU utilizable).
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 ( 64 segundos ) terminar de procesar alrededor de 3544 imágenes 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 256 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)
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 ( 659 segundos ) 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:
Hugging Face (PyTorch) es hasta 2,3 veces más rápido en GPU que en CPU
La GPU es hasta ~2,3 veces 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
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.
Primero, instalemos Spark NLP en sus CPU de Databricks de un solo nodo:
En la pestaña Bibliotecas dentro de su clúster, debe seguir estos pasos:
— Instalar Nuevo -> PyPI -> spark-nlp==4.1.0 -> Instalar
— Instalar Nuevo -> Maven -> Coordenadas -> com.johnsnowlabs.nlp:spark-nlp_2.12:4.1.0 -> Instalar
— Agregará ` TF_ENABLE_ONEDNN_OPTS=1 ` a `Cluster->Opciones avanzadas->Spark->Variables de entorno` para habilitar oneDNN
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 ( 111 segundos ) terminar de procesar 3544 imágenes 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:
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 34 000 imágenes , tomó alrededor de 18 minutos ( 1072 segundos ) terminar de predecir las clases para esas imágenes. A continuación, repetiré los mismos puntos de referencia en el clúster con GPU.
Nodo único de Databricks con una GPU en AWS
Primero, instale Spark NLP en su GPU de Databricks de un solo nodo (la única diferencia es el uso de " spark-nlp-gpu" de Maven):
Instale Spark NLP en su clúster de Databricks
— En la pestaña Bibliotecas dentro del clúster, debe seguir estos pasos:
— Instalar Nuevo -> PyPI -> spark-nlp==4.1.0 -> Instalar
— Instalar Nuevo -> Maven -> Coordenadas -> com.johnsnowlabs.nlp:spark-nlp-gpu_2.12:4.1.0 -> Instalar
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 ( 47 segundos ) en terminar de procesar alrededor de 3544 imágenes de nuestro conjunto de datos de muestra en nuestros Databricks de un solo nodo con un dispositivo de GPU. Podemos ver que el tamaño de lote 8 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:
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 ( 435 segundos ) terminar de predecir 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:
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 2,5 veces más rápido que en CPU, incluso con oneDNN habilitado (oneDNN mejora los resultados en CPU entre un 10 % y un 20 %).
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:
Spark NLP es hasta un 15 % 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 hasta un 34 % en el conjunto de datos más grande con imágenes de 34K. Spark NLP también es un 51 % más rápido que Hugging Face en una sola GPU para un conjunto de datos más grande con imágenes de 34K y hasta un 36 % más rápido en un conjunto de datos más pequeño con imágenes de 3K.
Spark NLP es más rápido tanto en CPU como en GPU en comparación con Hugging Face en Databricks Single Node
Hasta ahora, establecimos que Hugging Face en GPU es más rápido que Hugging Face en CPU 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.
También hemos establecido que Spark NLP supera a Hugging Face 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, escalando la canalización más allá de una sola máquina . Pero parece que Spark NLP es más rápido que Hugging Face incluso en una sola máquina, tanto en CPU como en GPU , en conjuntos de datos grandes y pequeños .
Pregunta: ¿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?
Respuesta: ¡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.
Ampliación = hacer que su máquina sea más grande o más rápida para que pueda manejar más carga.
Escalamiento horizontal = agregar más máquinas en paralelo para distribuir una carga.
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 Multi-GPU para inferencia en Hugging Face no existe en este momento:
https://huggingface.co/docs/transformers/perf_infer_gpu_many
Por lo tanto, parece que no existe una forma nativa/oficial de ampliar las 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.
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: " Implementación de 🤗 ViT en Kubernetes con TF Serving ". 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 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á)
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
Vamos a crear un clúster y esta vez elegimos Estándar dentro del modo Clúster . 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).
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 (no es necesario cambiar ningún código) y también solo usaré el conjunto de datos más grande con imágenes de 34K. ¡Vamos a empezar!
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 2x nodos con CPU (oneDNN): predicción de 34742 imágenes
Le tomó alrededor de 9 minutos ( 550 segundos ) terminar de predecir clases para imágenes de 34K. Comparemos este resultado en 2x nodos 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) :
Spark NLP es un 124 % más rápido que Hugging Face con 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 2x Nodos a 4x Nodos. Así es como se vería el clúster con 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 4x nodos con CPU (oneDNN): predicción de 34742 imágenes
Le tomó alrededor de 5 minutos ( 289 segundos ) terminar de predecir clases para imágenes de 34K. Comparemos este resultado en 4x nodos con Spark NLP frente a Hugging Face en CPU en Databricks:
Spark NLP es un 327 % más rápido que Hugging Face con 4x nodos
Como puede verse, Spark NLP ahora es un 327 % más rápido que Hugging Face en las CPU mientras usa solo 4x nodos en Databricks.
Ahora dupliquemos el clúster anterior agregando 4x Nodos más y hagamos un total de 8x Nodos . 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:
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 8x nodos con CPU (oneDNN): predicción de 34742 imágenes
Le tomó más de 2 minutos y medio ( 161 segundos ) terminar de predecir clases para imágenes de 34K. Comparemos este resultado en 8x Nodes con Spark NLP frente a Hugging Face en CPU en Databricks:
Spark NLP es un 666 % más rápido que Hugging Face con 8x nodos
Como puede verse, Spark NLP ahora es un 666 % más rápido que Hugging Face en las CPU mientras usa solo 8x Nodes en Databricks.
¡Simplemente ignoremos el número de 6s aquí! (fue 665.8% si te hace sentir mejor)
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 10x nodos con CPU (oneDNN): predicción de 34742 imágenes
Le tomó menos de 2 minutos ( 112 segundos ) terminar de predecir clases para imágenes de 34K. Comparemos este resultado en 10x Nodes con todos los resultados anteriores de Spark NLP vs. Hugging Face en CPU en Databricks:
Spark NLP es 1000% más rápido que Hugging Face con 10x Nodos
¡Y así es como se escala el modelo Vision Transformer proveniente de Hugging Face en 10x Nodes usando Spark NLP en Databricks! Nuestra canalización ahora es 1000 % más rápida que Hugging Face en las CPU.
Logramos hacer que nuestra canalización de ViT sea un 1000 % más rápida que Hugging Face, que está atascada en 1 solo nodo, simplemente usando Spark NLP, pero solo usamos CPU . Veamos si podemos obtener las mismas mejoras escalando nuestra canalización en un clúster de GPU .
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 Estándar 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.
También necesitamos instalar Spark NLP en este nuevo clúster a través de la pestaña Bibliotecas . Igual que antes, puede seguir los pasos que mencioné en Databricks de un solo nodo con una GPU.
Clúster de varios nodos (estándar) de bricks de datos con GPU
Nuestro clúster de GPU de Databricks de varios nodos utiliza la misma instancia de GPU de AWS de g4dn.8xlarge 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.
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 2x nodos con GPU: predicción de 34742 imágenes
Le tomó 4 minutos ( 231 segundos ) terminar de predecir clases para imágenes de 34K . Comparemos este resultado en 2x nodos con Spark NLP frente a Hugging Face en GPU en Databricks:
Spark NLP es un 185 % más rápido que Hugging Face con 2x nodos
Spark NLP con 2x Nodes es casi 3x veces más rápido ( 185 % ) que Hugging Face en 1 solo nodo mientras usa GPU.
Redimensionemos nuestro clúster de GPU de 2x Nodos a 4x Nodos. Este es un resumen de cómo se ve esta vez con 4x Nodes usando una GPU:
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 nodos 4x con GPU: predicción de 34742 imágenes
Esta vez tomó casi 2 minutos ( 118 segundos ) terminar de clasificar todas las imágenes de 34K 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:
Spark NLP es un 458 % más rápido que Hugging Face con 4x nodos
Eso es un 458 % más de rendimiento en comparación con Hugging Face. Acabamos de hacer que nuestra canalización sea 5,6 veces más rápida mediante el uso de Spark NLP con nodos 4x.
A continuación, cambiaré el tamaño del clúster para tener 8x nodos en mis Databricks con el siguiente resumen:
Databricks con 8x nodos: con 1 GPU por nodo
Solo como recordatorio, cada instancia de AWS ( g4dn.8xlarge ) tiene 1 GPU NVIDIA T4 de 16 GB (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:
Canalización de clasificación de imágenes Spark NLP en nodos 8x con GPU: predicción de 34742 imágenes
Se tardó casi un minuto ( 61 segundos ) en terminar de clasificar imágenes de 34 000 con nodos 8x 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:
Spark NLP es 980% más rápido que Hugging Face con 8x Nodes
Spark NLP con 8x Nodes es casi 11x veces más rápido (980 %) que Hugging Face en GPU.
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 10x Nodos y hacerlos coincidir en términos de la cantidad final de nodos. El resumen final de este clúster es el siguiente:
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 10x nodos con GPU: predicción de 34742 imágenes
Le tomó menos de un minuto ( 51 segundos ) terminar de predecir las clases para más de 34743 imágenes . 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:
Spark NLP es 1200% más rápido que Hugging Face con 10x Nodos
¡Y hemos terminado!
¡Logramos escalar nuestro modelo Vision Transformer proveniente de Hugging Face en 10x Nodes usando Spark NLP en Databricks! Nuestra canalización ahora es 13 veces más rápida con mejoras de rendimiento del 1200 % en comparación con Hugging Face en GPU.
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.
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?)
AWS m5d.8xlarge con CPU frente a AWS g4dn.8xlarge con 1 GPU y especificaciones similares
OK, ¡entonces el precio parece más o menos el mismo! Con eso en mente, ¿qué mejoras obtienes si pasas de Hugging Face en CPU atascadas en una sola máquina a Spark NLP en 10x Nodes con 10x GPU ?
Spark NLP en GPU es 25 veces (2366 %) más rápido que Hugging Face en CPU
Spark NLP 🚀 en 10x Nodos con GPU es 2366 % (25x veces) más rápido que Hugging Face 🤗 en un solo nodo con CPU
vit
cara de abrazo
Ladrillos de datos
Chispa PNL