Potenciando Llama 2 70B con NVIDIA H100

El viaje de la inferencia acelerada de LLM

The journey of accelerated LLM inference

La búsqueda de rendimiento en el motor de respuestas de Perplexity nos impulsa a adoptar la tecnología más reciente que NVIDIA y AWS ofrecen. En este blog, nos complace compartir los resultados de nuestros últimos experimentos: una comparativa de inferencia de Llama 2 70B en diversos entornos de hardware y software.

Nuestra plataforma de inferencia de LLM, pplx-api, está construida sobre una arquitectura de vanguardia impulsada por bibliotecas de código abierto. Desde que comenzó la versión beta pública de pplx-api en octubre, hemos estado abordando desafíos de escalabilidad y aprendiendo cómo optimizar nuestra configuración para lograr una escala masiva. Esto nos llevó a ejecutar experimentos con las siguientes preguntas orientativas:

¿Cuál es la ganancia de rendimiento bruto al cambiar nuestras GPU de NVIDIA A100 a NVIDIA H100, manteniendo el resto de las configuraciones iguales?

¿Cuál es la ganancia de eficiencia de la cuantización de punto flotante de 8 bits (fp8), para la cual la H100 añade soporte nativo? ¿Cuál es el costo en precisión de esta cuantización?

¿Cómo afectan el paralelismo de tensores y el tamaño de lote a la latencia y al rendimiento de tokens?

Considerando lo anterior, ¿qué configuración resulta en el equilibrio más escalable entre rendimiento y eficiencia de costos?

Configuración experimental

Ejecutamos el siguiente experimento como una serie de pruebas comparativas locales para evitar la latencia de red.

Métricas clave:

Latencia: El tiempo total que le toma al servidor de inferencia generar su respuesta completa.

Rendimiento: El número de tokens de salida, por segundo, por GPU, que el servidor de inferencia puede generar en todas las solicitudes y usuarios.

Constantes:

Los siguientes factores influirían en las métricas clave, por lo que los mantuvimos constantes en las diferentes pruebas del experimento.

Modelo de IA

El rendimiento escala con el tamaño del LLM. Más parámetros requieren más cálculos, lo que resulta en una inferencia más lenta. Por ejemplo, Llama 2 13B es más rápido que Llama 2 70B cuando otras configuraciones son iguales. Nos ceñimos a Llama 2 70B en este experimento porque queremos optimizar el servicio de los modelos de código abierto más capaces.

Conjunto de datos de tokens de entrada/salida

La cantidad de tokens de entrada y salida en cada par de solicitud/respuesta de muestra puede influir en las mediciones de rendimiento. En general, la generación de tokens de salida domina el tiempo total de respuesta. Cuando el muestreo de datos solo induce respuestas de "sí/no" del LLM, la respuesta es más rápida en comparación con las muestras que piden al LLM escribir ensayos. Nuestro conjunto de datos se compone de solicitudes sintéticas con 1024 tokens de entrada que inducen 512 tokens de salida. Esta distribución se eligió para coincidir con la distribución de tráfico observada en nuestro despliegue público de Llama2 70B.

Versión de software

NVIDIA TensorRT-LLM (versión v0.5.0) es una biblioteca de código abierto para optimizar la inferencia de LLM. Lanzada a finales de 2023, sintetiza muchas de las optimizaciones de inferencia de NVIDIA y proporciona una capa flexible de personalización para los parámetros clave de este experimento: tamaño de lote, cuantización y paralelismo de tensores.

Variables

Experimentamos a través de 4 ejes de configuración: paralelismo de tensores, arquitectura de GPU, cuantización y tamaño máximo de lote. Estos ejes están interconectados porque cada uno representa un compromiso con respecto al recurso de cuello de botella crítico: la memoria de la GPU.

Arquitectura de GPU

La arquitectura de GPU Hopper de novena generación (H100-HBM3-80GB / p5.48xlarge) incluye una enorme lista de características sobre su predecesora, Ampere (A100-SXM4-80GB / p4de.24xlarge), que incluye tasas de computación de 2x-6x y casi 2x de ancho de banda de memoria de GPU. El ancho de banda de memoria de la GPU es una métrica crítica para la inferencia porque un cuello de botella de latencia principal de las multiplicaciones de matrices de la inferencia proviene de la carga de gigabytes de datos del modelo desde la memoria de la GPU a los registros de cómputo. Basándonos en estas estadísticas, planteamos la hipótesis de que una comparación equitativa entre NVIDIA H100 y A100 mostrará una mejora de 2x tanto en latencia como en rendimiento.

Otra diferencia clave entre NVIDIA H100 y A100 es que el núcleo tensorial de H100 añade soporte de forma nativa para instrucciones de punto flotante de 8 bits (fp8), lo que abre la puerta a más optimizaciones detalladas a continuación. Es por esto que usamos fp8 y fp16 específicamente para la H100.

Para mantener la memoria por GPU constante en este experimento, nos ceñimos a nodos con 8x80GB de memoria de GPU tanto para nuestras NVIDIA A100 como H100. Además de permitir tamaños de lote más altos, la memoria de la GPU es importante porque los parámetros del modelo se cargan en la memoria de la GPU durante el inicio del servidor para un acceso rápido. Por ejemplo, si cada uno de los 70 mil millones de parámetros de nuestro modelo es un número de punto flotante de 16 bits, entonces el modelo tiene un tamaño de aproximadamente 140 GB, lo que no cabe en una sola GPU. De ahí la necesidad de paralelismo de tensores, que explicamos a continuación.

Paralelismo de tensores

El paralelismo de tensores se refiere al número de dispositivos GPU consumidos para ejecutar el servidor de inferencia. Cuando asignamos un número de GPU, TensorRT-LLM agrupa sus recursos para ayudarnos a alcanzar el presupuesto de memoria mínimo requerido para ejecutar Llama2 70B. Nuestra hipótesis es que un menor paralelismo de tensores resultará en una mayor latencia (debido a que se consumen menos recursos para satisfacer cada lote) pero un mayor rendimiento por GPU (debido a una mejor utilización) en comparación con un paralelismo de tensores más alto.

Cuantización

La cuantización es la reducción de la precisión en los pesos y activaciones utilizados por las redes neuronales. Usamos esta técnica para reducir a la mitad el consumo de memoria de la GPU cuando cambiamos de fp16 a fp8. Esto hace posible ejecutar el mismo modelo con un menor uso total de memoria de GPU, permitiendo un paralelismo de tensores menor, lo que aumenta el rendimiento.

Las implementaciones de cuantización tienen el potencial de degradar la precisión. Por lo tanto, evaluamos la precisión para diferentes precisiones comparando su estadística de perplejidad, una medida de qué tan bien predice el LLM cada siguiente token en una oración, en el corpus WikiText. Para el punto flotante de 8 bits y el peso de 8 bits con activación de 8 bits y SmoothQuant (w8a8 SQ), no hubo un cambio significativo en la perplejidad (< 1%) en comparación con fp16 en WikiText, por lo que nos sentimos seguros de continuar. Sin embargo, w4a16 mostró un cambio sustancial del 7% en la perplejidad, potencialmente atribuible a la precisión aún menor y las conversiones dinámicas necesarias entre int4 y fp16.

Tamaño de lote

El paralelismo a través de lotes es una estrategia clásica para obtener rendimiento de un sistema con recursos limitados. Al procesar múltiples solicitudes en cada pasada hacia adelante a través de la red neuronal, se sabe que el procesamiento por lotes aumenta el rendimiento a costa de algo de latencia. El procesamiento por lotes también incurre en un mayor consumo de memoria de GPU porque el tamaño de la memoria caché KV que gestiona el mecanismo de atención crece linealmente con el tamaño del lote.

En el caso de Llama 2 70B (que tiene 80 capas), fp16 con un tamaño de lote de 32 para un tamaño de contexto de 4096, el tamaño de la caché KV resulta en unos sustanciales 40 GB. Esto termina evitando que Llama 2 70B fp16, cuyos pesos por sí solos ocupan 140GB, quepa cómodamente en los 160GB de memoria de GPU disponibles con paralelismo de tensores 2 (TP-2).

Resultados

Revisamos combinaciones compatibles de las 4 variables del experimento y presentamos las tendencias más reveladoras a continuación.

Figura 1 - La latencia de las solicitudes con diferentes tamaños de lote en cinco configuraciones diferentes, todas con paralelismo de tensores 8, lo que produce la mejor latencia con 8 GPU disponibles. Dentro de cada configuración, la latencia generalmente se duplica al aumentar el tamaño del lote de 1 → 32, y se duplica nuevamente de 32 → 128. En tamaños de lote suficientemente grandes, H100 reduce aproximadamente a la mitad la latencia en comparación con A100. A100 utiliza precisión mixta porque la arquitectura carece de soporte nativo para fp8. w8a8 con SmoothQuant (SQ) pretende parecerse a fp8.

La mejora de la latencia de la cuantización está en el orden del 10% cuando se compara H100 fp16 → fp8 y A100 fp16 → w8a8 con SmoothQuant. Sin embargo, la precisión mixta w4a16 en realidad funciona mejor en tamaños de lote pequeños y peor en tamaños de lote más grandes en comparación con fp16. Esto puede deberse a una serie de factores, incluidos núcleos de cómputo menos optimizados, tiempo de conversión entre int4 y fp16, y el hecho de que w4a16 todavía utiliza puntos flotantes de 16 bits para las activaciones, lo que no resulta en ahorros en las dimensiones de la caché KV. Debido a que w4a16 también demostró una menor precisión, concluimos que deberíamos ceñirnos a w8a8 SQ para A100 y fp8 para H100.

Figura 2 - El rendimiento a través de configuraciones TP-8 con diferente arquitectura, cuantización y tamaño de lote. Para cada arquitectura y cuantización, se eligió el tamaño de lote más grande que cumpliera con un requisito de latencia de 25600ms (20 tokens por segundo para 512 tokens), de modo que comparemos configuraciones que tengan una latencia similar. Bajo este requisito, H100 con BS-128 alcanza un rendimiento del 228% en comparación con A100 BS-64 usando la misma cuantización (fp16) e incluso tiene una latencia de respuesta más baja a pesar del tamaño de lote duplicado. La cuantización con fp8 mejora este factor al 251%.

En nuestras dos primeras figuras, solo presentamos configuraciones de TP-8. H100 logra un 54% de latencia y un 184% de rendimiento en comparación con A100 cuando ambos usan fp16 / BS-128 / TP-8, lo cual mejora a un 49% de latencia y un 202% de rendimiento cuando se usa fp8 en H100. Esta mejora en el rendimiento se puede atribuir a los aumentos en la potencia de cálculo y el ancho de banda de memoria entre H100 y A100. Cabe destacar que la diferencia es menos pronunciada con tamaños de lote más bajos, donde la utilización puede ser menor.

A medida que construimos nuestra plataforma, queremos cumplir con ciertos requisitos de latencia para nuestros usuarios mientras maximizamos el rendimiento. Por lo tanto, en lugar de comparar A100 frente a H100 al mismo tamaño de lote, en realidad tiene más sentido comparar su rendimiento solo bajo configuraciones en las que satisfacen un requisito de latencia. Establecimos un límite de latencia de 25600ms para completar los 512 tokens de salida y descubrimos que H100 / TP-8 / fp8 / BS-128 produce un 251% de rendimiento en comparación con A100 / TP-8 / fp16 / BS-64, ya que es capaz de procesar el doble del tamaño de lote a una latencia menor. Dado que la cuantización proporciona ahorros de memoria de GPU, ahora necesitamos evaluar cómo el paralelismo de tensores puede añadir una siguiente capa de optimización.

Figura 3 - La latencia a través de diferentes tamaños de lote y paralelismo de tensores para H100 fp8. La latencia generalmente se duplica al aumentar el tamaño del lote de 1 → 32, y se duplica nuevamente de 32 → 128. TP-2 es consistentemente alrededor de dos veces más lento que TP-8 cuando los tamaños de lote son iguales. Duplicar el paralelismo de tensores mientras se duplica el tamaño del lote mantiene la latencia relativamente estable, ya que el número de lotes procesados por GPU sigue siendo igual.

Cuando se trata de cuantización y arquitectura, hay claros ganadores: H100 domina a A100 y la cuantización de menor precisión mejora la utilización de la memoria, la latencia y el rendimiento. Sin embargo, el tamaño del lote y el paralelismo de tensores presentan un compromiso en nuestras métricas clave. Un tamaño de lote mayor optimiza el rendimiento a costa de un aumento en la latencia y el consumo de memoria. Por otro lado, un mayor paralelismo de tensores aumenta el conjunto general de memoria disponible y optimiza la latencia, pero se compensa con el rendimiento debido a los costos de sincronización de la multiplicación de matrices distribuida y al bloquear más recursos de GPU.

Figura 4 - El rendimiento a través de diferentes tamaños de lote y paralelismo de tensores para H100 fp8. El rendimiento más alto proviene de TP-2 BS-128, con un 460% en comparación con la base de referencia de A100/TP-8/fp16/BS-64. Sin embargo, TP-2 BS-128 es también el resultado más lento en la Figura 3.

La configuración de maximización del rendimiento de nuestro experimento es H100 / fp8 / TP-2 / BS-128, a 767 tokens de salida por segundo por GPU. Esto es una mejora del 460% sobre A100 / fp16 / TP-8 / BS-64. Sin embargo, esto tiene el costo de una latencia duplicada - más cercana a los 42000ms para 512 tokens de salida -, por lo que puede ser inadecuado como configuración de producción. Los resultados de TP-4 BS-128 (626 tok/seg/gpu a 26188ms de tiempo de respuesta) y TP-2 BS-32 (435 tok/seg/gpu a 18821ms de tiempo de respuesta) pueden representar mejores compromisos en nuestras métricas clave.

Conclusión

Nuestros resultados demuestran que:

Alcanzamos un 54% de latencia y un 184% de rendimiento usando H100 en comparación con A100 dada la misma configuración, lo cual mejora al 49% y 202% respectivamente cuando H100 aprovecha su soporte nativo para fp8.

Al maximizar el rendimiento sujeto a una restricción de latencia, H100 / fp8 / TP-8 / BS-128 produce un 251% de rendimiento en comparación con A100 / fp16 / TP-8 / BS-64, ya que puede procesar el doble del lote a una velocidad más rápida.

Aprovechando H100 con TP-2 con fp8, podemos lograr el 373% del rendimiento de A100 / fp16 / TP-8 / BS-128, con menos de un 10% de aumento en la latencia.

El tamaño del lote y el paralelismo de tensores presentan un compromiso entre el rendimiento y la latencia para el operador de un sistema de inferencia de LLM.

Estos resultados nos hacen sentir seguros acerca de una transición completa a las GPU H100 en nuestra pila de hardware anteriormente impulsada por A100. Estamos emocionados de poder confirmar las ganancias de rendimiento anunciadas por NVIDIA y esperamos sus próximos avances en hardware acelerado.

¿Qué sigue?

Nuestra próxima frontera para la optimización es examinar la precisión y el impacto en el rendimiento de la dispersión estructurada y la precisión int4, lo que podría reducir significativamente la huella de memoria de GPU de Llama 2 70B y generar mejoras de hasta 2x en la latencia. Estamos entusiasmados de continuar el viaje de una inferencia increíblemente rápida y esperamos capacitar a nuestros usuarios para construir aplicaciones potentes sobre nuestra plataforma.

A corto plazo, pplx-api eliminará los límites de tasa y ofrecerá más LLM de Perplexity personalizados, incluyendo un LLM impulsado por Internet con conexión a hechos.

Regístrese en Perplexity Pro en perplexity.ai/pro. Obtenga acceso a nuestra pplx-api de vanguardia y aproveche estas capacidades avanzadas en sus proyectos. Descubra más sobre pplx-api en nuestro blog.

¿Interesado en dar forma al futuro de la IA? ¡Estamos contratando! Sea parte de un equipo que impulsa una infraestructura de LLM generativa a escala masiva. Explore las oportunidades en Perplexity Careers.

Autores:

Aarash Heydari, Grigorii Alekseev, Kevin Hu, Denis Yarats