Revolución de la Sparsidad de Activación: Mejorando el Rendimiento del Modelo y Acelerando la Inferencia sin Reentrenamiento

Revolución de la Sparsidad de Activación: Mejorando el Rendimiento del Modelo y Acelerando la Inferencia sin Reentrenamiento

Técnicas dispersas para una aceleración 100X en la inferencia de modelos de lenguaje grandes. ¡Descubre la magia de la sparsidad de activación: sin reentrenamiento, bajo costo y alta eficiencia, lo que conduce a un aumento significativo en la velocidad de inferencia de GPU!

En la discusión anterior sobre “Cómo LLM acelera la inferencia mediante sparsidad”, exploramos la primera parte, “[Cómo podan los modelos grandes](Unveiling LLM-Pruner Techniques: Doubling Inference Speed)”. Esta vez, continuamos profundizando en la segunda parte, “Cómo acelerar la inferencia usando sparsidad de activación”, y en la próxima discusión examinaremos la tercera parte, “El impacto de los compiladores dispersos en la inferencia de LLM”.

Hemos estado explorando si existe un método que pueda cumplir varios requisitos: no requerir reentrenamiento del modelo sino solo ajuste fino (bajo costo de transferencia del modelo), mantener el rendimiento del modelo (buena efectividad), tener un alto soporte por parte del hardware moderno (GPU/CPU) y reducir significativamente el cómputo y E/S de GPU para optimizar la latencia (velocidad de inferencia rápida).

De hecho, tal método existe, y la sparsidad de activación es uno que cumple con todos estos requisitos.

Vale la pena señalar que el uso de funciones de activación ReLU en redes neuronales se sabe que induce sparsidad de activación y se ha adoptado en varios trabajos anteriores. En promedio, esta sparsidad de activación en todas las capas conduce a ahorros significativos en la transferencia de pesos (E/S) entre GPU y CPU, afectando aproximadamente al 95% de las filas de los pesos de la capa de proyección. Esta reducción se traduce directamente en ahorros computacionales, ya que los resultados de las operaciones de multiplicación de matrices para estas filas serán cero.

Además, a diferencia de la sparsidad no estructurada (por ejemplo, sparsidad de pesos no estructurada), este tipo de sparsidad es más amigable con el hardware debido a que pone a cero bloques más extensos y estructurados (como filas o columnas).

De manera similar, refiriéndonos a la figura a continuación, ilustramos brevemente la efectividad de la sparsidad de activación para acelerar la inferencia.

En el caso de la sparsidad de activación, se realiza una multiplicación de vector disperso por matriz densa durante la inferencia, mientras que durante el entrenamiento se ajusta a multiplicación de matriz dispersa por matriz densa.

  • Carga de trabajo computacional reducida: Esta sparsidad semiestructurada (a diferencia de la sparsidad no estructurada de la poda de pesos) permite omitir ciertas filas, reduciendo el cómputo. Por ejemplo, bibliotecas como cusparse ya admiten operaciones correspondientes.
  • Transferencia de E/S reducida: Durante la inferencia, la E/S de GPU es un cuello de botella (por ejemplo, de caché de GPU a caché de CPU o de DRAM de GPU a caché de GPU). Este método permite omitir filas innecesarias, reduciendo así la E/S.

Viabilidad de la sparsidad de activación

El siguiente contenido se refiere principalmente a datos de [5] para demostrar la viabilidad de aplicar la activación ReLU en LLM.

Comparación entre modelos con y sin sparsidad de activación

Mediante la medición y el análisis de la FFN (Red Feed-Forward) de tres modelos, OPT 6.7B, Llama 7B (con activación SiLU) y Falcon 7B (con activación GELU), se obtienen las siguientes tres conclusiones:

a. La comparación entre Llama 7B (con activación SiLU), Falcon 7B (con activación GELU) y OPT 6.7B (con activación ReLU) revela que ReLU induce más del 90% de sparsidad de activación, mientras que SiLU y GELU inducen menos del 10% de sparsidad de activación, demostrando que ReLU puede inducir activaciones dispersas.

b. La sparsidad de activación conduce a ahorros significativos en la transmisión de pesos (E/S), afectando aproximadamente al 95% de las filas de los pesos de la capa de proyección descendente.

c. La elección de la función de activación no afecta significativamente la precisión porque GELU, SiLU o ReLU están al mismo nivel de precisión. Sin embargo, ReLU puede ahorrar un 32% de la carga de trabajo computacional (FLOPS).

Reducción de costos de entrenamiento

Muchos LLM modernos (como Llama y Falcon) han sido entrenados usando activaciones que no son ReLU. Entrenar desde cero no es rentable; por lo tanto, es necesario considerar implementar la activación ReLU mediante ajuste fino. El modelo se ajusta finamente a través de las siguientes dos fases:

  • En la primera fase, se retienen las activaciones ReLU existentes (en el caso de OPT) o se reemplaza la función de activación entre las capas de up-projection y down-projection con ReLU (en el caso de Falcon y Llama, donde se usan GELU y SiLU).
  • En la segunda fase, se insertan nuevas activaciones ReLU después de las capas de normalización.

Primera Fase — Reemplazo de activaciones no ReLU

Reemplazar las activaciones no ReLU con ReLU en las capas FFN. Para los modelos Falcon y Llama, esto implica reemplazar GELU y SiLU, respectivamente. Se observa que, dado que el modelo OPT ya utiliza activaciones ReLU, no se realizan cambios. Después del ajuste fino en 30B tokens de RefinedWeb, el modelo muestra una sparsidad significativa en las activaciones.

Segunda Fase — Inserción de nuevas ReLU

En la fase anterior, reemplazamos las activaciones no ReLU para obtener más sparsidad. Esto resultó en entradas dispersas para la capa de down-projection, que representa aproximadamente el 30% del costo computacional total. Sin embargo, además de la down-projection, hay otras multiplicaciones matriz-vector en las capas de decodificación del transformer, como la up-projection en la capa FFN y la proyección QKV en la capa de atención. En conjunto, estas multiplicaciones matriz-vector consumen alrededor del 55% del costo computacional total.

En las capas Transformer modernas, las entradas a las capas de atención y FFN provienen de capas de normalización, como LayerNorm o RMSNorm. Estas capas pueden verse como una forma específica de un MLP donde no aplican parámetros aprendibles arbitrarios sino que aprenden a escalar la entrada. Por lo tanto, aplicamos ReLU para obtener activaciones dispersas después de las capas de normalización, logrando el objetivo de la segunda fase.

Resultados de la medición

Costo del ajuste fino: El ajuste fino se completó con 30B y 50B tokens en las fases uno y dos, respectivamente. En comparación con el costo de entrenamiento de 1T tokens para Llama, el costo fue solo de aproximadamente el 3-5%.

Efectividad: Comparando la latencia de inferencia después del ajuste fino para Llama y Falcon, no hubo una disminución perceptible en el rendimiento del modelo. Sin embargo, hubo una mejora significativa de más del 30% en la velocidad de inferencia.

En general, los resultados confirman que lograr sparsidad de activación mediante ajuste fino puede reducir los FLOPS de inferencia en varias etapas y tasas, manteniendo un rendimiento comparable en diferentes tareas. Los modelos de activación dispersa correspondientes se pueden encontrar en el proyecto: https://huggingface.co/SparseLLM.

Cómo acelerar la inferencia

La predicción de sparsidad de contexto de DejaVu, como se describe en el artículo de referencia [1], es un excelente enfoque.

Cómo utilizar completamente la sparsidad estructurada para acelerar

La sparsidad de contexto asume que los modelos preentrenados exhiben sparsidad de contexto, lo que significa que los cálculos de sparsificación para Atención y MLP logran el mismo efecto que los cálculos completos. Con esta premisa, una sparsidad de contexto promedio del 85% en modelos dispersos estructurados puede resultar en una reducción de siete veces en los parámetros para cada entrada específica, manteniendo la precisión, mejorando así significativamente el rendimiento de la inferencia.

Como se muestra en la figura anterior, se diseña un predictor disperso asíncrono basado en la sparsidad de contexto, prediciendo la sparsidad de la Atención y MLP de la siguiente capa con anticipación. Este enfoque no solo asegura la eficiencia de la inferencia, sino que también reduce en gran medida la sobrecarga computacional y de E/S.

Validación de la existencia de sparsidad de contexto

Se realizaron pruebas en los modelos OPT-175B, 66B y 30B con varios conjuntos de datos downstream como OpenBookQA y Wiki-Text. El método implicó dos pases hacia adelante del modelo para identificar la sparsidad de contexto para cada ejemplo de entrada. En el primer pase, se registró un subconjunto de parámetros, particularmente aquellos asociados con cabezas de Atención y neuronas MLP que generan grandes normas de salida para las entradas. En el segundo pase, cada ejemplo de entrada se calculó utilizando solo el subconjunto de parámetros registrado. Sorprendentemente, ambos pases hacia adelante produjeron predicciones o rendimiento similares en todas las tareas de aprendizaje contextual y modelado de lenguaje.

Resultados de observación: En promedio, las cabezas de Atención pueden imponer sparsidad de hasta el 80%, mientras que las neuronas MLP pueden lograr sparsidad de hasta el 95%, resultando en una sparsidad general de aproximadamente el 85%, lo que puede llevar a una aceleración de siete veces. Para datos de referencia específicos, consulte la figura a continuación.

Impacto en la ingeniería

Efecto de aceleración: Dado que las GPU son dispositivos orientados a bloques, el tiempo requerido para cargar un solo byte de memoria es el mismo que cargar el bloque de memoria alrededor de la misma dirección. El tamaño de bloque de las GPU NVIDIA suele ser de 128 bytes. Por lo tanto, se realizaron optimizaciones como fusión de memoria y fusión de operadores. Bajo la premisa de batch_size=1, en comparación con FasterTransformer, la aceleración alcanzó un efecto de duplicación, logrando una mejora de 2x en velocidad.

Impacto en el rendimiento: Dado que las activaciones son funciones de cada token, la sparsidad efectiva también se distribuye aleatoriamente entre los tokens. Por lo tanto, la efectividad de la optimización dispersa decae exponencialmente al aumentar el tamaño del lote. Esto se puede consultar en los experimentos de ablación realizados en el artículo.

Reducción del umbral de inferencia

Organizando los métodos actuales de descarga parcial y el método DejaVu, como se muestra en la tabla a continuación:

¿Se pueden combinar la sparsidad de activación y los métodos de descarga para diseñar un motor de inferencia híbrido GPU-CPU: donde las neuronas de activación caliente se precargan en la GPU para acceso rápido, mientras que las neuronas de activación fría se calculan en la CPU, reduciendo significativamente los requisitos de memoria de GPU y la transferencia de datos CPU-GPU?

La respuesta es, naturalmente, ‘SÍ’.

Una de esas soluciones es PowerInfer[10], que puede ejecutar OPT-175B en una sola NVIDIA RTX 4090, logrando velocidades de generación de tokens solo un 18% inferiores a los servidores GPU A100 de primer nivel. Además de la descarga y la sparsidad de activación, otros aspectos como Brainstorm[9], SparTA[15] y Flash-llm[16] también tienen valor de referencia.

Resumen:

PowerInfer precarga los pesos en la GPU para las neuronas frecuentemente activadas, mientras que los pesos de las neuronas menos activas se retienen en la CPU.

Para reducir la latencia de inferencia, el motor de inferencia solo calcula las neuronas que el predictor en línea predice que estarán activas, omitiendo la mayoría de las neuronas inactivas. Además, la estrategia de precarga permite a PowerInfer asignar una porción significativa de las tareas de inferencia a la GPU, ya que las neuronas de activación caliente cargadas en la GPU constituyen la mayoría de las activaciones. Para las neuronas de activación fría que no están en la memoria de la GPU, PowerInfer realiza los cálculos en la CPU, eliminando la necesidad de transferir los pesos a la GPU.

La visión general de la arquitectura y el flujo de trabajo de inferencia de PowerInfer

PowerInfer comprende componentes fuera de línea y en línea. Debido a las variaciones en las propiedades de localidad entre diferentes LLM, el componente fuera de línea analiza la sparsidad de activación del LLM, distinguiendo entre neuronas calientes y frías. En la fase en línea, el motor de inferencia carga ambos tipos de neuronas en la GPU y la CPU y atiende solicitudes de LLM con baja latencia en tiempo de ejecución. Antes de procesar las solicitudes de los usuarios, el motor en línea asigna los dos tipos de neuronas a sus respectivas unidades de procesamiento según la salida del solucionador fuera de línea. En tiempo de ejecución, el motor crea ejecutores de GPU y CPU, que son hilos que se ejecutan en el lado de la CPU, para gestionar los cálculos concurrentes CPU-GPU. El motor también predice las activaciones de las neuronas y omite las neuronas inactivas. Las neuronas activadas se precargan en la memoria de la GPU para su procesamiento, mientras que la CPU calcula los resultados para sus neuronas y los transfiere a la GPU para su integración. El motor utiliza operadores conscientes de neuronas dispersas tanto en CPU como en GPU, centrándose en filas/columnas individuales de neuronas dentro de las matrices.

Enlace del proyecto: https://github.com/SJTU-IPADS/PowerInfer

Optimización del cálculo de una sola capa

Un ejemplo ilustrativo muestra cómo PowerInfer calcula diferentes neuronas para una capa de LLM

PowerInfer coordina la GPU y la CPU para manejar las neuronas en una capa clasificando las neuronas según datos fuera de línea, asignando neuronas calientes (por ejemplo, índice 3, 5, 7) a la memoria de la GPU y asignando otras neuronas a la memoria de la CPU.

Al recibir la entrada, el predictor identifica qué neuronas en la capa actual es probable que se activen. Por ejemplo, predice la activación de las neuronas 3, 4 y 5. Vale la pena señalar que las neuronas calientes identificadas mediante análisis estadístico fuera de línea pueden no alinearse siempre con el comportamiento de activación en tiempo de ejecución. Por ejemplo, la neurona 7, aunque marcada como caliente, puede estar inactiva en un escenario dado.

Posteriormente, tanto la CPU como la GPU procesan las neuronas activas predichas, ignorando las inactivas. La GPU calcula las neuronas 3 y 5, mientras que la CPU maneja la neurona 4. Una vez que se completa el cálculo de la neurona 4, su salida se envía a la GPU para la integración de resultados.

Inferencia en línea (motor de inferencia consciente de neuronas)

  • Predictor disperso adaptativo

El motor de inferencia en línea en PowerInfer reduce la carga computacional al procesar solo las neuronas que se predice que se activarán. Este enfoque también se utiliza en DejaVu, que aboga por entrenar un conjunto de tamaño fijo de predictores MLP. En cada capa del Transformer, DejaVu aprovecha dos predictores independientes para pronosticar la activación de las neuronas en los bloques de autoatención y MLP.

Sin embargo, diseñar predictores efectivos para implementación local con recursos limitados plantea desafíos, lo que requiere un equilibrio entre la precisión de la predicción y el tamaño del modelo.

PowerInfer emplea un método de entrenamiento iterativo para predictores de tamaño no fijo para cada capa del Transformer. Este proceso primero establece un tamaño de modelo base basado en el perfil de sparsidad de la capa. Posteriormente, considerando la asimetría de activación interna, el tamaño del modelo se ajusta iterativamente para mantener la precisión. Los predictores MLP generalmente comprenden capas de entrada, oculta y salida. Dado que los tamaños de las capas de entrada y salida están determinados por la estructura de la capa del Transformer, las modificaciones se dirigen principalmente a la capa oculta. Durante el proceso de ajuste iterativo, el tamaño de la capa oculta se modifica en función de la asimetría observada. Para las capas que exhiben una asimetría significativa, el tamaño de la capa oculta disminuye gradualmente hasta que la precisión cae por debajo del 95%. Por el contrario, para capas con asimetría mínima, las dimensiones se aumentan para mejorar la precisión. A través de este enfoque, PowerInfer confina efectivamente los parámetros del predictor al 10% de los parámetros totales del LLM.

  • Ejecución híbrida GPU-CPU

Antes de la inferencia, PowerInfer construye un gráfico acíclico dirigido (DAG) computacional donde cada nodo representa un operador de inferencia de LLM y lo almacena en una cola global en la memoria de la CPU. Cada operador en la cola está etiquetado con los operadores que requiere. Durante la inferencia, dos tipos de ejecutores (creados por el sistema operativo host pthread) gestionan los cálculos en CPU y GPU. Extraen operadores de la cola global, verifican las dependencias y los asignan a las unidades de procesamiento adecuadas. La GPU y la CPU utilizan sus operadores conscientes de neuronas, donde el ejecutor de GPU lanza operadores de GPU mediante API como cudaLaunchKernel, mientras que el ejecutor de CPU coordina los núcleos de CPU no utilizados para el cálculo.

Conclusión experimental

Comparación de rendimiento

Aceleración de varios modelos en el formato FP16 en PC-High. El eje X representa la longitud de salida, mientras que el eje Y indica la relación de aceleración en comparación con llama.cpp. El número sobre cada barra representa la velocidad de generación de extremo a extremo (tokens/s). La longitud de entrada configurada para la primera fila en el gráfico es de aproximadamente 64, mientras que para la segunda fila es de aproximadamente 128.

En un PC-High equipado con NVIDIA RTX 4090, varios modelos y configuraciones de entrada-salida exhiben diferentes velocidades de generación. En promedio, PowerInfer logra una velocidad de generación de 8.32 tokens/s, con un pico de 16.0 tokens/s, que es significativamente superior a llama.cpp, con una aceleración promedio de 7.23 veces, mientras que Falcon-40B alcanza hasta 11.69 veces. A medida que aumenta el número de tokens de salida, la ventaja de rendimiento de PowerInfer se vuelve más pronunciada, ya que la fase de generación juega un papel más importante en el tiempo total de inferencia. Durante esta etapa, se activa un pequeño número de neuronas tanto en CPU como en GPU, reduciendo los cálculos innecesarios en comparación con llama.cpp. Por ejemplo, en el caso de OPT-30B, solo se activa aproximadamente el 20% de las neuronas por token generado, y la mayoría se procesa en la GPU, mostrando la ventaja del motor de inferencia consciente de neuronas de PowerInfer.

Impacto del tamaño del lote:

Cuando el tamaño del lote es menor a 32, PowerInfer demuestra una ventaja significativa, con una mejora promedio de 6.08 veces en comparación con llama.cpp. A medida que aumenta el tamaño del lote, la relación de aceleración proporcionada por PowerInfer disminuye. Esta reducción se atribuye a la disminución de la sparsidad de las activaciones conjuntas en el modelo. Sin embargo, incluso con un tamaño de lote configurado en 32, PowerInfer aún mantiene una relación de aceleración considerable, alcanzando una mejora de 4.38 veces.

Aceleración de inferencia por lotes de Falcon-40B en PC-High. El eje X indica el tamaño del lote de solicitudes, el eje Y representa la velocidad de generación de tokens de extremo a extremo (tokens/s). El número sobre cada barra muestra la aceleración en comparación con llama.cpp.

Comparación de carga

Distribución de la carga de neuronas en CPU y GPU durante la inferencia. El bloque amarillo se refiere a llama.cpp, y el bloque azul a PowerInfer.

Se compara la distribución de la carga de neuronas entre CPU y GPU en PowerInfer y llama.cpp. La carga de neuronas se refiere a la proporción de cálculos de neuronas activadas realizados por cada unidad de procesamiento. Vale la pena señalar que en un sistema PC-High, PowerInfer aumenta significativamente la proporción de carga de neuronas en la GPU, pasando de un promedio del 20% al 70%. Esto indica que la GPU maneja el 70% de las neuronas activadas. Sin embargo, cuando los requisitos de memoria del modelo superan con creces la capacidad de la GPU, como ejecutar un modelo de 60GB en una GPU 2080Ti de 11GB, la carga de neuronas en la GPU disminuye al 42%. Esta disminución se debe a la memoria limitada de la GPU, que es insuficiente para acomodar todas las neuronas de activación caliente, lo que requiere que la CPU calcule una parte de estas neuronas.

En escenarios que involucran indicaciones de entrada más largas y longitudes de salida relativamente más cortas, PowerInfer solo muestra mejoras de rendimiento limitadas. En tales casos, la etapa de procesar una gran cantidad de tokens de manera concurrente se convierte en un factor clave para determinar la velocidad de inferencia. Esto resulta en que cada token active un conjunto único de neuronas, reduciendo significativamente la sparsidad de activación. Como resultado, la CPU se convierte en el principal cuello de botella en el proceso de inferencia, encargada de procesar una gran cantidad de neuronas de activación fría pero limitada por la capacidad computacional.

Conclusión

La tecnología de sparsidad de activación ha traído avances revolucionarios a los modelos de lenguaje a gran escala. Al esparcir las activaciones de las redes neuronales para acelerar el proceso de inferencia mientras se reducen las cargas computacionales y de E/S de la GPU, se mejora la velocidad y el rendimiento de la inferencia. Este enfoque no requiere reentrenamiento y logra sparsidad de activación solo mediante ajuste fino, reduciendo significativamente los costos mientras mantiene el rendimiento del modelo. Las perspectivas de aplicación de la tecnología de sparsidad de activación son emocionantes, trayendo más posibilidades al campo del aprendizaje profundo. Esperamos un mayor desarrollo y una amplia aplicación de esta tecnología.

Artículos de referencia

[5]ReLU Strikes Back:Exploiting Activation Sparsity in Large Language Models

[7]Inducing and exploiting activation sparsity for fast inference on deep neural networks

[8]Sparse is enough in scaling transformers

novita.ai proporciona la API de Stable Diffusion y cientos de APIs de generación de imágenes por IA rápidas y económicas para 10,000 modelos.🎯 Generación más rápida en solo 2s, pago por uso, desde $0.0015 por imagen estándar, puedes agregar tus propios modelos y evitar el mantenimiento de GPU. Comparte extensiones de código abierto de forma gratuita.

Lectura recomendada

  1. Métodos de cuantificación para una aceleración 100X en la inferencia de modelos de lenguaje grandes
  2. Revelando técnicas de poda de LLM: duplicando la velocidad de inferencia