Haz que el tiempo de generación de tu llamada vuele con AWS Inferentia2

Acelera el tiempo de generación de tus llamadas con AWS Inferentia2

En un artículo anterior en el blog de Hugging Face, presentamos AWS Inferentia2, el acelerador AWS Inferentia de segunda generación, y explicamos cómo podrías usar optimum-neuron para implementar rápidamente modelos de Hugging Face para tareas estándar de texto y visión en instancias de AWS Inferencia 2.

En un paso más de integración con el AWS Neuron SDK, ahora es posible usar 🤗 optimum-neuron para implementar modelos LLM para generación de texto en AWS Inferentia2.

Y qué mejor modelo podríamos elegir para esa demostración que Llama 2, uno de los modelos más populares en el Hugging Face hub.

Configurar 🤗 optimum-neuron en tu instancia de Inferentia2

Nuestra recomendación es usar el Hugging Face Neuron Deep Learning AMI (DLAMI). El DLAMI viene con todas las bibliotecas requeridas preempaquetadas para ti, incluyendo Optimum Neuron, Neuron Drivers, Transformers, Datasets y Accelerate.

Alternativamente, puedes usar el Hugging Face Neuron SDK DLC para implementar en Amazon SageMaker.

Nota: mantente atento a un próximo artículo dedicado a la implementación de SageMaker.

Finalmente, estos componentes también se pueden instalar manualmente en una instancia nueva de Inferentia2 siguiendo las instrucciones de instalación de optimum-neuron.

Exportar el modelo Llama 2 a Neuron

Como se explica en la documentación de optimum-neuron, los modelos deben ser compilados y exportados a un formato serializado antes de ejecutarlos en dispositivos Neuron.

Afortunadamente, 🤗 optimum-neuron ofrece una API muy simple para exportar modelos estándar de transformers 🤗 al formato de Neuron.

>>> from optimum.neuron import NeuronModelForCausalLM>>> compiler_args = {"num_cores": 24, "auto_cast_type": 'fp16'}>>> input_shapes = {"batch_size": 1, "sequence_length": 2048}>>> model = NeuronModelForCausalLM.from_pretrained(        "meta-llama/Llama-2-7b-hf",        export=True,        **compiler_args,        **input_shapes)

Esto merece una pequeña explicación:

  • usando compiler_args, especificamos en cuántos núcleos queremos que se implemente el modelo (cada dispositivo Neuron tiene dos núcleos) y con qué precisión (aquí float16),
  • usando input_shape, establecemos las dimensiones estáticas de entrada y salida del modelo. Todos los compiladores de modelos requieren formas estáticas y Neuron no es una excepción. Ten en cuenta que sequence_length no solo limita la longitud del contexto de entrada, sino también la longitud de la caché KV y, por lo tanto, la longitud de salida.

Dependiendo de tu elección de parámetros y del host de inferentia, esto puede llevar desde unos minutos hasta más de una hora.

Afortunadamente, solo necesitarás hacer esto una vez porque puedes guardar tu modelo y volver a cargarlo más tarde.

>>> model.save_pretrained("una_ruta_local_para_el_modelo_neuronal_compilado")

Aún mejor, puedes subirlo al Hugging Face Hub.

>>> model.push_to_hub(        "una_ruta_local_para_el_modelo_neuronal_compilado",        repository_id="aws-neuron/Llama-2-7b-hf-neuron-latency")

Generar Texto usando Llama 2 en AWS Inferentia2

Una vez que se haya exportado tu modelo, puedes generar texto usando la biblioteca transformers, como se describe en detalle en esta publicación anterior.

>>> from optimum.neuron import NeuronModelForCausalLM>>> from transformers import AutoTokenizer>>> model = NeuronModelForCausalLM.from_pretrained('aws-neuron/Llama-2-7b-hf-neuron-latency')>>> tokenizer = AutoTokenizer.from_pretrained("aws-neuron/Llama-2-7b-hf-neuron-latency")>>> inputs = tokenizer("¿Qué es el deep-learning?", return_tensors="pt")>>> outputs = model.generate(**inputs,                             max_new_tokens=128,                             do_sample=True,                             temperature=0.9,                             top_k=50,                             top_p=0.9)>>> tokenizer.batch_decode(outputs, skip_special_tokens=True)['¿Qué es el deep-learning?\n El término "deep-learning" se refiere a un tipo de aprendizaje automático que tiene como objetivo modelar abstracciones de alto nivel de los datos en forma de una jerarquía de múltiples capas de nodos de procesamiento cada vez más complejos.']

Nota: al pasar múltiples fragmentos de entrada a un modelo, las secuencias de tokens resultantes deben estar acolchadas a la izquierda con un token de fin de secuencia. Los tokenizers guardados con los modelos exportados están configurados en consecuencia.

Las siguientes estrategias de generación son compatibles:

  • búsqueda codiciosa,
  • muestreo multinomial con top-k y top-p (con temperatura).

Se admiten la mayoría de las preprocesamientos/filtros de logits (como la penalización por repetición).

Todo en uno con los tuberías de optimum-neuron

Para aquellos que les gusta mantenerlo simple, hay una forma aún más sencilla de usar un modelo LLM en AWS Inferentia 2 utilizando tuberías de optimum-neuron.

Usarlos es tan simple como:

>>> from optimum.neuron import pipeline>>> p = pipeline('text-generation', 'aws-neuron/Llama-2-7b-hf-neuron-budget')>>> p("Mi lugar favorito en la tierra es", max_new_tokens=64, do_sample=True, top_k=50)[{'generated_text': 'Mi lugar favorito en la tierra es el océano. Es donde me siento más en paz. Me encanta viajar y conocer nuevos lugares. Tengo un'}]

Puntos de referencia

Pero, ¿qué tan eficiente es la generación de texto en Inferentia2? ¡Descubrámoslo!

Hemos subido al hub versiones precompiladas de los modelos LLama 2 7B y 13B con diferentes configuraciones:

Nota: todos los modelos están compilados con una longitud máxima de secuencia de 2048.

El modelo llama2 7B “budget” está destinado a ser implementado en la instancia inf2.xlarge que tiene solo un dispositivo de neurona y suficiente memoria cpu para cargar el modelo.

Todos los demás modelos se compilan para utilizar toda la capacidad de los núcleos disponibles en la instancia inf2.48xlarge.

Nota: por favor, consulta la página de productos inferentia2 para obtener detalles sobre las instancias disponibles.

Hemos creado dos configuraciones orientadas a “latencia” para los modelos llama2 7B y llama2 13B que pueden atender solo una solicitud a la vez, pero a máxima velocidad.

También hemos creado dos configuraciones orientadas a “rendimiento” para atender hasta cuatro solicitudes en paralelo.

Para evaluar los modelos, generamos tokens hasta una longitud total de secuencia de 1024, comenzando desde 256 tokens de entrada (es decir, generamos 256, 512 y 768 tokens).

Nota: los números de modelo “budget” se informan pero no se incluyen en los gráficos para una mejor legibilidad.

Tiempo de codificación

El tiempo de codificación es el tiempo requerido para procesar los tokens de entrada y generar el primer token de salida. Es una métrica muy importante, ya que corresponde a la latencia percibida directamente por el usuario al transmitir tokens generados.

Probamos el tiempo de codificación para tamaños de contexto crecientes, 256 tokens de entrada corresponden aproximadamente a un uso típico de preguntas y respuestas, mientras que 768 es más típico de un caso de uso de Generación con Recuperación Mejorada (RAG).

El modelo “budget” (Llama2 7B-B) se implementa en una instancia inf2.xlarge, mientras que otros modelos se implementan en una instancia inf2.48xlarge.

El tiempo de codificación se expresa en segundos.

Tiempo de codificación de Llama2 inferentia2

Podemos ver que todos los modelos implementados muestran excelentes tiempos de respuesta, incluso para contextos largos.

Latencia de extremo a extremo

La latencia de extremo a extremo corresponde al tiempo total para alcanzar una longitud de secuencia de 1024 tokens.

Por lo tanto, incluye el tiempo de codificación y generación.

El modelo “budget” (Llama2 7B-B) se implementa en una instancia inf2.xlarge, mientras que otros modelos se implementan en una instancia inf2.48xlarge.

La latencia se expresa en segundos.

Latencia de extremo a extremo de Llama2 inferentia2

Todos los modelos implementados en la instancia de alto rendimiento muestran una buena latencia, incluso aquellos configurados para optimizar el rendimiento.

La latencia del modelo implementado “budget” es significativamente más alta, pero aún aceptable.

Rendimiento

Adoptamos la misma convención que otros referenciales para evaluar el rendimiento, dividiendo la latencia de extremo a extremo por la suma de los tokens de entrada y salida. En otras palabras, dividimos la latencia de extremo a extremo por tamaño_del_lote * longitud_de_secuencia para obtener el número de tokens generados por segundo.

El modelo “budget” (Llama2 7B-B) se implementa en una instancia inf2.xlarge, mientras que otros modelos se implementan en una instancia inf2.48xlarge.

El rendimiento se expresa en tokens/segundo.

Rendimiento de Llama2 inferentia2

Nuevamente, los modelos implementados en la instancia de alto rendimiento tienen un muy buen rendimiento, incluso aquellos optimizados para latencia.

El modelo “budget” tiene un rendimiento mucho más bajo, pero aún aceptable para un caso de uso de transmisión, considerando que un lector promedio lee alrededor de 5 palabras por segundo.

Conclusión

Hemos ilustrado lo fácil que es implementar modelos llama2 desde el centro de recursos de Hugging Face en AWS Inferentia2 utilizando 🤗 optimum-neuron.

Los modelos implementados demuestran un rendimiento muy bueno en términos de tiempo de codificación, latencia y rendimiento.

Es interesante notar que la latencia de los modelos implementados no es demasiado sensible al tamaño del lote, lo que abre el camino para su implementación en puntos finales de inferencia que atienden múltiples solicitudes en paralelo.

Aún hay mucho margen de mejora:

  • en la implementación actual, la única forma de aumentar el rendimiento es aumentar el tamaño del lote, pero actualmente está limitado por la memoria del dispositivo. Se están integrando alternativas como la segmentación en línea,
  • la longitud estática de la secuencia limita la capacidad del modelo para codificar contextos largos. Sería interesante ver si los sumideros de atención podrían ser una opción válida para solucionar esto.

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

Combatir la suplantación de identidad por la IA

Encontrar formas de determinar si un mensaje de voz es real o generado por una inteligencia artificial.

Inteligencia Artificial

Cómo los científicos están descifrando códigos históricos para revelar secretos perdidos

El proyecto DECRYPT, una colaboración entre lingüistas y científicos de la computación, tiene como objetivo automatiz...

Inteligencia Artificial

Diferenciación automática con Python y C++ para el aprendizaje profundo

Esta historia explora la diferenciación automática, una característica de los marcos de trabajo modernos de Deep Lear...

Inteligencia Artificial

Hacia la IA General el papel de LLMs y Modelos Fundamentales en la Revolución del Aprendizaje de por Vida

En la última década y especialmente con el éxito del aprendizaje profundo, se ha formado una discusión continua en to...