Modelos y plataformas de IA

SGLang: Ejecución Eficiente de Programas de Modelos de Lenguaje Estructurados

mm
Añade Unite.AI a tus fuentes preferidas en Google

Los grandes modelos de lenguaje (LLM) se utilizan cada vez más para tareas complejas que requieren múltiples llamadas de generación, técnicas de prompting avanzadas, control de flujo y entradas/salidas estructuradas. Sin embargo, los sistemas eficientes para programar y ejecutar estas aplicaciones son escasos. SGLang, un sistema recién introducido, busca abordar este problema proporcionando una ejecución eficiente de programas de modelos de lenguaje complejos. SGLang consta de un lenguaje de frontend y un tiempo de ejecución. El frontend simplifica la programación con primitivas para la generación y el control de la paralelización, mientras que el tiempo de ejecución acelera la ejecución a través de optimizaciones novedosas como RadixAttention para la reutilización de la caché KV y máquinas de estado finito comprimidas para una decodificación de salida estructurada más rápida. Los experimentos demuestran que SGLang logra un rendimiento hasta 6,4 veces mayor en comparación con los sistemas de inferencia de estado de la técnica en varios modelos de lenguaje y multimodal grandes, abordando tareas como el control de agentes, el razonamiento lógico, las pruebas de aprendizaje de pocos disparos, la decodificación de JSON, las tuberías de generación mejoradas por recuperación y el chat de varias vueltas.

Los avances recientes en las capacidades de los LLM han ampliado su utilidad, permitiéndoles manejar una gama más amplia de tareas generales y funcionar como agentes autónomos. En estas aplicaciones, los LLM participan en la planificación de varias rondas, el razonamiento y la interacción con entornos externos. Esto se facilita a través del uso de herramientas, múltiples modalidades de entrada y varias técnicas de prompting, como el aprendizaje de pocos disparos, la autoconsistencia, el esqueleto de pensamiento y el árbol de pensamiento. Estos nuevos casos de uso requieren múltiples llamadas a los LLM, a menudo dependientes, lo que indica una tendencia hacia el uso de estructuras de varias llamadas para completar tareas complejas.

Este cambio marca una transición de un uso de chat simple a un uso programático más sofisticado de los LLM, donde los programas programan y controlan los procesos de generación de los LLM. Estos programas se denominan “Programas de Modelo de Lenguaje” (LM Programs). Las técnicas de prompting avanzadas y los flujos de trabajo de agentes caen dentro del alcance de los programas LM. Hay dos propiedades comunes de los programas LM: (1) Los programas LM suelen involucrar múltiples llamadas a los LLM intercaladas con un control de flujo para completar tareas complejas y mejorar la calidad general. (2) Los programas LM reciben entradas estructuradas y producen salidas estructuradas, lo que permite la composición de programas LM y la integración en sistemas de software existentes.

En este artículo, profundizaremos en el marco de SGLang, explorando su arquitectura, analizando su rendimiento y comparándolo con los marcos de estado de la técnica. Así que comencemos.

Introducción a SGLang

A pesar del uso generalizado de los programas LM, los sistemas actuales para expresar y ejecutarlos siguen siendo ineficientes. SGLang identifica dos desafíos principales asociados con el uso eficiente de los programas LM:

  • Complejidad de programación: Desarrollar programas LM es tedioso y difícil debido a la naturaleza no determinista de los LLM. Esto implica una manipulación extensiva de cadenas, un ajuste experimental de las técnicas de prompting, un análisis de salida frágil, el manejo de múltiples modalidades de entrada y la implementación de mecanismos de paralelización. Esta complejidad reduce significativamente la legibilidad incluso de programas simples.
  • Ineficiencia de ejecución: La ejecución de los programas LM es ineficiente debido a la computación redundante y el uso de memoria. Los motores de inferencia de estado de la técnica, optimizados para reducir la latencia y mejorar el rendimiento, carecen de conocimiento directo de la carga de trabajo, lo que resulta en ineficiencias significativas. Un ejemplo notable es la reutilización de la caché KV, que consiste en tensores intermedios reutilizables esenciales para la inferencia generativa. Los sistemas actuales carecen de mecanismos efectivos para facilitar la reutilización de la caché KV a través de múltiples llamadas a los LLM que comparten un prefijo común, lo que conduce a cálculos innecesarios y memoria desperdiciada. Además, la decodificación de salida estructurada, como el modo JSON, es subóptima, ya que los sistemas existentes solo decodifican un token a la vez.

Para abordar estos desafíos, SGLang introduce un Lenguaje de Generación Estructurado para los LLM. La idea central es explotar sistemáticamente la estructura de varias llamadas en los programas LM para una ejecución eficiente. Como se muestra en la siguiente figura, SGLang tiene dos partes: un lenguaje de frontend y un tiempo de ejecución de backend.

El frontend simplifica la programación de los programas LM, y el tiempo de ejecución acelera su ejecución. Estas partes pueden trabajar juntas para un mejor rendimiento o funcionar de forma independiente.

SGLang es un lenguaje específico de dominio incrustado en Python, que proporciona primitivas para la generación (por ejemplo, extender, gen, seleccionar) y el control de la paralelización (por ejemplo, bifurcar, unir). Es compatible con el control de flujo de Python y las bibliotecas, lo que permite a los usuarios desarrollar flujos de trabajo de prompting avanzados con facilidad utilizando la sintaxis nativa de Python. SGLang incluye un intérprete y un compilador. El intérprete gestiona el estado del prompt como un flujo y envía operaciones primitivas al flujo para la ejecución asíncrona, garantizando un control adecuado sobre la sincronización y la paralelización dentro del programa. Además, los programas SGLang se pueden rastrear y compilar para optimizaciones adicionales. El tiempo de ejecución de SGLang propone varias optimizaciones novedosas para acelerar la ejecución de los programas LM:

  • RadixAttention: Esta técnica permite la reutilización automática de la caché KV a través de múltiples llamadas de generación. En los motores de inferencia existentes, la caché KV de una solicitud se descarta después del procesamiento, lo que impide la reutilización a través de múltiples llamadas y ralentiza la ejecución. SGLang mantiene una caché LRU de la caché KV dentro de un árbol radix, gestionando la caché KV como una caché tradicional y utilizando el árbol radix para el emparejamiento, la inserción y la expulsión eficientes. Esto permite al tiempo de ejecución manejar varios patrones de reutilización de forma eficiente.
  • Máquina de Estado Finito Comprimida: Esta técnica permite una decodificación de salida estructurada más rápida. Los sistemas existentes siguen las restricciones solo para el siguiente token, lo que les permite decodificar un token a la vez. En cambio, SGLang analiza las restricciones y construye una máquina de estado finito comprimida para representarlas, comprimiendo un camino de varios tokens en un paso único siempre que sea posible, lo que permite la decodificación de múltiples tokens a la vez para una mayor velocidad.
  • Ejecución Especulativa de API: Para modelos de API como OpenAI, SGLang introduce la ejecución especulativa de API para optimizar programas de varias llamadas.

Utilizando SGLang, se implementaron varias aplicaciones de LLM, incluyendo el control de agentes, el razonamiento lógico, las pruebas de aprendizaje de pocos disparos, la decodificación de JSON, las tuberías de generación mejoradas por recuperación, el chat de varias vueltas y el procesamiento de multimodalidad. El rendimiento se probó en modelos que incluyen Llama-7B/70B, Mistral-8x7B, LLaVA-v1.5-7B (imagen) y LLaVA-NeXT-34B (video) en GPU NVIDIA (NVDA ) A10G y A100. Los resultados experimentales muestran que SGLang logra un rendimiento hasta 6,4 veces mayor en una amplia gama de cargas de trabajo, modelos y configuraciones de hardware, en comparación con los sistemas de programación y inferencia existentes, incluyendo Guidance, vLLM y LMQL.

SGLang: Modelo de Programación y Metodología

El modelo de programación de SGLang se introduce a través de un ejemplo en ejecución, describiendo sus primitivas de lenguaje y modos de ejecución, y esbozando oportunidades de optimización en tiempo de ejecución. Este modelo simplifica las operaciones tediosas en flujos de trabajo de varias llamadas (por ejemplo, manipulación de cadenas, llamadas a API, especificación de restricciones, paralelización) al proporcionar primitivas flexibles y componibles. SGLang es un lenguaje específico de dominio incrustado en Python. La siguiente figura muestra un programa que evalúa un ensayo sobre una imagen utilizando el método de prompting de rama-resolver-combinar.

La función multi_dimensional_judge toma tres argumentos: `s`, `path` y `essay`. `s` gestiona el estado del prompt, `path` es la ruta del archivo de imagen y `essay` es el texto del ensayo. Nuevas cadenas y primitivas SGLang se pueden agregar al estado `s` para la ejecución utilizando el operador +=. Primero, la función agrega la imagen y el ensayo al prompt. Luego, verifica si el ensayo está relacionado con la imagen utilizando la función `seleccionar`, almacenando el resultado en s[“related”]. Si están relacionados, el prompt se bifurca en tres copias para la evaluación paralela desde diferentes dimensiones, utilizando `gen` para almacenar los resultados en f[“judgment”]. A continuación, combina los juicios, genera un resumen y asigna una calificación de letra. Finalmente, devuelve los resultados en formato JSON, siguiendo un esquema definido por una restricción de expresión regular regex. SGLang simplifica enormemente este programa, ya que un programa equivalente utilizando una interfaz similar a la de OpenAI requeriría 2,1 veces más líneas de código debido a la manipulación manual de cadenas y el control de la paralelización.

SGLang proporciona primitivas para controlar el estado del prompt, la generación y la paralelización, que se pueden utilizar con la sintaxis y las bibliotecas de Python. A continuación, se presentan las primitivas:

gen: Llama a un modelo para generar y almacena los resultados en una variable con el nombre especificado en su primer argumento. Admite un argumento `regex` para restringir la salida a seguir una gramática definida por una expresión regular (por ejemplo, un esquema JSON).

  • seleccionar: Llama a un modelo para elegir la opción con mayor probabilidad de una lista.
  • += o extender: Agrega una cadena al prompt.
  • [nombre_de_variable]: Recupera los resultados de una generación.
  • bifurcar: Crea bifurcaciones paralelas del estado del prompt.
  • unir: Reune el estado del prompt.
  • imagen y video: Admiten entradas de imagen y video.

La forma más sencilla de ejecutar un programa SGLang es a través de un intérprete, donde un prompt se trata como un flujo asíncrono. Las primitivas como `extender`, `gen` y `seleccionar` se envían al flujo para la ejecución asíncrona. Estas llamadas no bloqueantes permiten que el código de Python continúe ejecutándose sin esperar a que la generación termine, similar a lanzar kernels de CUDA de forma asíncrona. Cada prompt es gestionado por un ejecutor de flujo en un hilo de fondo, lo que permite la paralelización dentro del programa. La recuperación de los resultados de la generación bloqueará hasta que estén listos, garantizando la sincronización correcta. Alternativamente, los programas SGLang se pueden compilar como gráficos computacionales y ejecutar con un ejecutor de gráficos, lo que permite más optimizaciones. Este artículo utiliza el modo intérprete por defecto y discute los resultados del modo compilador en el Apéndice D. SGLang admite modelos de peso abierto con su propio tiempo de ejecución SGLang (SRT), así como modelos de API como OpenAI y Anthropic.

Los sistemas de programación para LLM se pueden clasificar en de alto nivel (por ejemplo, LangChain, DSPy) y de bajo nivel (por ejemplo, LMQL, Guidance, SGLang). Los sistemas de alto nivel proporcionan prompts predefinidos o generados automáticamente, como el optimizador de prompts de DSPy. Los sistemas de bajo nivel no alteran los prompts, pero permiten la manipulación directa de los prompts y las primitivas. SGLang es un sistema de bajo nivel similar a LMQL y Guidance. La siguiente tabla compara sus características.

SGLang se centra más en la eficiencia en tiempo de ejecución y viene con su propio tiempo de ejecución codiseñado, lo que permite optimizaciones novedosas. Los lenguajes de alto nivel (por ejemplo, DSPy) se pueden compilar a lenguajes de bajo nivel (por ejemplo, SGLang). La integración de SGLang como backend en DSPy para una mejor eficiencia en tiempo de ejecución se demuestra más adelante.

El ejemplo anterior ilustra las operaciones de RadixAttention con una política de expulsión LRU en nueve puntos de tiempo, mostrando la evolución dinámica del árbol radix en respuesta a diferentes solicitudes. Estas solicitudes incluyen dos sesiones de chat, un lote de consultas de aprendizaje de pocos disparos y muestreo de autoconsistencia. Cada arista del árbol lleva una etiqueta que denota una subcadena o una secuencia de tokens. Los nodos están codificados por colores para reflejar diferentes estados: verde para nodos agregados recientemente, azul para nodos en caché accedidos durante el punto de tiempo y rojo para nodos expulsados.

Este ejemplo demuestra cómo RadixAttention maneja la asignación dinámica y la expulsión de nodos en respuesta a diferentes tipos de solicitudes, garantizando la reutilización eficiente de la caché KV y la gestión de memoria.

SGLang: Evaluación y Resultados

Resultados en Modelos de Peso Abierto

Los resultados de latencia y rendimiento se muestran en las siguientes figuras. SGLang mejora el rendimiento hasta 6,4 veces y reduce la latencia hasta 3,7 veces. Estas mejoras se deben a la reutilización de la caché KV, la explotación de la paralelización dentro de un solo programa y la decodificación de salida estructurada más rápida.

En estas pruebas, la tasa de aciertos de caché oscila entre el 50% y el 99%. La Figura 13 (Apéndice) enumera las tasas de acierto de caché logradas y óptimas para todos ellos, mostrando que la programación consciente de la caché de SGLang se acerca al 96% de la tasa de acierto óptima en promedio.

Resultados en Modelos Más Grandes con Paralelismo de Tensor

Se probaron modelos más grandes, Mixtral-8x7B y Llama-70B, con paralelismo de tensor en el mismo conjunto de pruebas, y los resultados se informan en la siguiente figura. La aceleración en modelos más grandes muestra una tendencia similar a la observada en modelos más pequeños, lo que indica que la optimización de SGLang se generaliza bien a modelos más grandes. Se omitieron Guidance y LMQL debido a la falta de implementaciones eficientes de paralelismo de tensor.

Resultados en Modelos Multimodales

SGLang tiene soporte nativo para modelos multimodales con las primitivas de imagen y video. Las optimizaciones de este artículo son compatibles con modelos multimodales. Para RadixAttention, se calcula el hash de la entrada de imagen y se utiliza como clave en el árbol radix, lo que permite la reutilización de la caché KV de los tokens de imagen de la misma imagen. LLaVA-v1.5-7B (imagen) se ejecutó en llava-bench-in-the-wild y LLaVA-NeXT-34B (video) en ActivityNet. Dado que estos modelos no están bien soportados por otros sistemas de referencia, se utilizó la implementación original de los autores del modelo en Hugging Face Transformers como sistema de referencia. Como se muestra en la siguiente tabla, SGLang proporciona un rendimiento hasta 6 veces mayor en estas pruebas. En llava-bench-in-the-wild, se manejaron varias preguntas sobre la misma imagen, y el tiempo de ejecución de SGLang reutilizó la caché KV en este caso.

Despliegue de Producción

SGLang se ha desplegado en Chatbot Arena para servir modelos de peso abierto. Debido al bajo tráfico para algunos modelos, solo un trabajador SGLang sirve a cada uno. Después de un mes, se observó una tasa de acierto de caché de RadixAttention del 52,4% para LLaVA-Next-34B y del 74,1% para Vicuna-33B. Los aciertos de caché provinieron de mensajes del sistema comunes, imágenes de ejemplo reutilizadas con frecuencia y historias de chat de varias vueltas. Esto redujo la latencia del primer token en un promedio de 1,7 veces para Vicuna-33B.

Pensamientos Finales

En este artículo, hemos hablado sobre SGLang, un sistema recién introducido que busca abordar este problema proporcionando una ejecución eficiente de programas de modelos de lenguaje complejos. SGLang consta de un lenguaje de frontend y un tiempo de ejecución de backend. El frontend simplifica la programación con primitivas para la generación y el control de la paralelización, mientras que el tiempo de ejecución acelera la ejecución a través de optimizaciones novedosas como RadixAttention para la reutilización de la caché KV y máquinas de estado finito comprimidas para una decodificación de salida estructurada más rápida. Los experimentos demuestran que SGLang logra un rendimiento hasta 6,4 veces mayor en comparación con los sistemas de inferencia de estado de la técnica en varios modelos de lenguaje y multimodal grandes, abordando tareas como el control de agentes, el razonamiento lógico, las pruebas de aprendizaje de pocos disparos, la decodificación de JSON, las tuberías de generación mejoradas por recuperación y el chat de varias vueltas.

Un ingeniero por profesión, un escritor por corazón. Kunal es un escritor técnico con un profundo amor y comprensión de la IA y el ML, dedicado a simplificar conceptos complejos en estos campos a través de su documentación atractiva e informativa.