Inteligencia Artificial
SGLang: ejecución eficiente de programas modelo de lenguaje estructurado
Los modelos de lenguaje grande (LLM) se utilizan cada vez más para tareas complejas que requieren llamadas de múltiples generaciones, técnicas de indicaciones avanzadas, flujo de control y entradas/salidas estructuradas. Sin embargo, faltan sistemas eficientes para programar y ejecutar estas aplicaciones. SGLang, un sistema recientemente introducido, tiene como objetivo abordar este problema proporcionando una ejecución eficiente de programas de modelos de lenguaje complejos. SGLang comprende un lenguaje frontend y un tiempo de ejecución. La interfaz simplifica la programación con primitivas para la generación y el control del paralelismo, mientras que el tiempo de ejecución acelera la ejecución a través de optimizaciones novedosas como RadixAttention para la reutilización de caché KV y máquinas de estados finitos 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 última generación en varios modelos multimodales y de lenguaje grande, abordando tareas como control de agentes, razonamiento lógico, puntos de referencia de aprendizaje de pocas oportunidades, decodificación JSON y recuperación. -Tuberías de generación aumentadas y chat multiturno.
Los avances recientes en las capacidades de 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 planificación, razonamiento e interacción de múltiples rondas con entornos externos. Esto se facilita mediante el uso de herramientas, múltiples modalidades de entrada y diversas técnicas de estimulación, como el aprendizaje en pocas ocasiones, la autoconsistencia, el esqueleto del pensamiento y el árbol del pensamiento. Estos nuevos casos de uso requieren múltiples llamadas de generación de LLM, a menudo dependientes, lo que indica una tendencia a utilizar estructuras de múltiples llamadas para completar tareas complejas.
Este cambio marca una transición del simple chat 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 conocen como “Programas modelo de lenguaje” (Programas LM). Las técnicas de indicación avanzadas y los flujos de trabajo agentes entran dentro del alcance de los programas LM. Hay dos propiedades comunes de los programas LM: (1) Los programas LM normalmente implican múltiples llamadas LLM intercaladas con flujo de control para completar tareas complejas y mejorar la calidad general. (2) Los programas LM reciben entradas estructuradas y producen resultados estructurados, lo que permite la composición de los programas LM y la integración en los sistemas de software existentes.
En este artículo, profundizaremos en el marco SGLang, exploraremos su arquitectura, analizaremos su rendimiento y lo compararemos con marcos de última generación. Entonces empecemos.
Una introducción a SGLang
A pesar del uso generalizado de programas LM, los sistemas actuales para expresarlos y ejecutarlos siguen siendo ineficientes. SGLang identifica dos desafíos principales asociados con el uso eficiente de los programas LM:
- Complejidad de la programación: desarrollar programas LM es tedioso y difícil debido a la naturaleza no determinista de los LLM. Esto implica una amplia manipulación de cadenas, ajuste experimental de indicaciones, análisis de salida frágil, manejo de múltiples modalidades de entrada e implementación de mecanismos de paralelismo. Esta complejidad reduce significativamente la legibilidad incluso de programas simples.
- Ineficiencia de ejecución: la ejecución de programas LM es ineficiente debido al cálculo redundante y al uso de memoria. Los motores de inferencia de última generación, optimizados para reducir la latencia y mejorar el rendimiento, carecen de conocimiento directo de la carga de trabajo, lo que genera ineficiencias significativas. Un ejemplo notable es la reutilización de la caché Key-Value (KV), que consta de tensores intermedios reutilizables esenciales para la inferencia generativa. Los sistemas actuales carecen de mecanismos efectivos para facilitar la reutilización de la caché KV en múltiples LLM llamadas que comparten un prefijo común, lo que genera cálculos innecesarios y desperdicio de memoria. Además, la decodificación restringida para salidas estructuradas, como el modo JSON, no es óptima ya que los sistemas existentes solo decodifican un token a la vez.
Para abordar estos desafíos, SGLang presenta un lenguaje de generación estructurado para LLM. La idea central es explotar sistemáticamente la estructura de llamadas múltiples en los programas LM para una ejecución eficiente. Como se muestra en la siguiente figura, SGLang tiene dos partes: un lenguaje de front-end y un tiempo de ejecución de back-end.

El front-end simplifica la programación de programas LM y el tiempo de ejecución acelera su ejecución. Estas piezas pueden trabajar juntas para un mejor rendimiento o funcionar de forma independiente.
SGLang es un lenguaje de dominio específico integrado en Python, que proporciona primitivas para generación (p. ej., extender, gen, select) y control de paralelismo (p. ej., fork, join). Es compatible con el flujo de control y las bibliotecas de Python, lo que permite a los usuarios desarrollar flujos de trabajo de indicaciones avanzados fácilmente con la sintaxis nativa de Python. SGLang incluye un intérprete y un compilador. El intérprete gestiona el estado del mensaje como una secuencia y envía operaciones primitivas a la secuencia para su ejecución asincrónica, lo que garantiza un control adecuado sobre la sincronización y el paralelismo 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 programas LM:
- RadixAttention: esta técnica permite la reutilización automática de la caché KV en llamadas de varias generaciones. En los motores de inferencia existentes, la caché KV de una solicitud se descarta después del procesamiento, lo que impide la reutilización en múltiples llamadas y ralentiza la ejecución. SGLang mantiene un caché LRU del caché KV dentro de un árbol de base, administra el caché KV como un caché tradicional y utiliza el árbol de base para una coincidencia, inserción y desalojo eficientes. Esto permite que el tiempo de ejecución maneje varios patrones de reutilización de manera eficiente.
- Máquina de estados finitos comprimida: esta técnica permite una decodificación restringida más rápida para salidas estructuradas. Los sistemas existentes siguen restricciones sólo 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 comprimida de estados finitos para representarlas, comprimiendo una ruta de múltiples tokens en una ruta de un solo paso siempre que sea posible, permitiendo la decodificación de múltiples tokens a la vez para una velocidad más rápida.
- Ejecución especulativa de API: para modelos solo de API como GPT-4 de OpenAI, SGLang introduce la ejecución especulativa API para optimizar programas de llamadas múltiples.
Utilizando SGLang, se implementaron varias aplicaciones LLM, incluido el control de agentes, el razonamiento lógico, los puntos de referencia de aprendizaje de pocas oportunidades, la decodificación JSON, los canales de generación de recuperación aumentada, el chat de múltiples turnos y el procesamiento de múltiples modalidades. El rendimiento se probó en modelos como Llama-7B/70B, Mistral-8x7B, LLaVA-v1.5-7B (imagen) y LLaVA-NeXT-34B (vídeo) en GPU NVIDIA 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 e inferencia existentes, incluidos Guidance, vLLM y LMQL.
SGLang: Modelo y Metodología de Programación
El modelo de programación SGLang se presenta a través de un ejemplo en ejecución, que describe las primitivas del lenguaje y los modos de ejecución, y describe las oportunidades de optimización del tiempo de ejecución. Este modelo simplifica las operaciones tediosas en flujos de trabajo de múltiples llamadas (por ejemplo, manipulación de cadenas, llamadas API, especificación de restricciones, paralelismo) al proporcionar primitivas flexibles y componibles. SGLang es un lenguaje de dominio específico integrado en Python. La siguiente figura muestra un programa que evalúa un ensayo sobre una imagen utilizando el método de solicitud de rama-resolver-fusionar.

La función juez_multidimensional toma tres argumentos: `s`, `ruta` y `ensayo`. s administra el estado del mensaje, la ruta es la ruta del archivo de imagen y el ensayo es el texto del ensayo. Se pueden agregar nuevas cadenas y primitivas SGLang al estado s para su ejecución usando el += operador. Primero, la función agrega la imagen y el ensayo al mensaje. Luego verifica si el ensayo está relacionado con la imagen usando select, almacenando el resultado en s[“relacionado”]. Si está relacionado, el mensaje se bifurca en tres copias para una evaluación paralela desde diferentes dimensiones, usando gen para almacenar los resultados en f[“juicio”]. A continuación, fusiona los juicios, genera un resumen y asigna una calificación con letras. Finalmente, devuelve los resultados en formato JSON, siguiendo un esquema definido por una restricción de expresión regular. expresiones regulares. SGLang simplifica enormemente este programa, ya que un programa equivalente que utilice una interfaz similar a la API 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 paralelismo.
SGLang proporciona primitivas para controlar el estado, la generación y el paralelismo de los mensajes, que se pueden usar con la sintaxis y las bibliotecas de Python. Aquí están las primitivas:
género: 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 para que siga una gramática definida por una expresión regular (por ejemplo, un esquema JSON).
- seleccionar: llama a un modelo para elegir la opción de mayor probabilidad de una lista.
- += o extender: agrega una cadena al mensaje.
- [nombre_variable]: Obtiene los resultados de una generación.
- fork: crea bifurcaciones paralelas del estado del mensaje.
- unirse: vuelve a unirse al estado de aviso.
- Imagen y video: tome 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 mensaje se trata como una secuencia asincrónica. Primitivos como extender, generar y seleccionar se envían a la secuencia para su ejecución asincrónica. Estas llamadas sin bloqueo permiten que el código Python continúe ejecutándose sin esperar a que finalice la generación, similar al lanzamiento de kernels CUDA de forma asincrónica. Cada mensaje es administrado por un ejecutor de flujo en un subproceso en segundo plano, lo que permite el paralelismo dentro del programa. La obtención de resultados de generación se bloqueará hasta que estén listos, lo que garantiza una sincronización correcta. Alternativamente, los programas SGLang pueden compilarse como gráficos computacionales y ejecutarse con un ejecutor de gráficos, lo que permite más optimizaciones. Este artículo utiliza el modo intérprete de forma predeterminada y analiza los resultados del modo compilador en el Apéndice D. SGLang admite modelos de peso abierto con su propio SGLang Runtime (SRT), así como modelos API como OpenAI y modelos antrópicos.
Los sistemas de programación para LLM se pueden clasificar en de alto nivel (p. ej., LangChain, DSPy) y de bajo nivel (p. ej., LMQL, Guidance, SGLang). Los sistemas de alto nivel proporcionan mensajes predefinidos o generados automáticamente, como el optimizador de mensajes de DSPy. Los sistemas de bajo nivel normalmente no modifican las indicaciones, pero permiten la manipulación directa de indicaciones y 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 del 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 en lenguajes de bajo nivel (por ejemplo, SGLang). La integración de SGLang como backend en DSPy para una mejor eficiencia del tiempo de ejecución se demuestra más adelante.

El ejemplo anterior ilustra las operaciones de RadixAttention con una política de desalojo de LRU en nueve puntos temporales, mostrando la evolución dinámica del árbol radix en respuesta a varias solicitudes. Estas solicitudes incluyen dos sesiones de chat, un lote de consultas de aprendizaje breves y muestreo de autoconsistencia. Cada borde del árbol lleva una etiqueta que indica una subcadena o una secuencia de tokens. Los nodos están codificados por colores para reflejar diferentes estados: verde para los nodos recién agregados, azul para los nodos en caché a los que se accedió durante el momento y rojo para los nodos que han sido desalojados.
Paso 1: El árbol de base está inicialmente vacío.
Paso 2: El servidor procesa un mensaje de usuario entrante "Hola" y responde con la salida LLM "Hola". El mensaje del sistema "Eres un asistente útil", el mensaje del usuario "¡Hola!" y el LLM responde "¡Hola!" se consolidan en el árbol como un único borde vinculado a un nuevo nodo.
Paso 3: Llega un nuevo mensaje y el servidor encuentra el prefijo del mensaje (es decir, el primer turno de la conversación) en el árbol de base y reutiliza su caché KV. El nuevo turno se añade al árbol como un nuevo nodo.
Paso 4: Comienza una nueva sesión de chat. El nodo del Paso 3 se divide en dos nodos para permitir que las dos sesiones de chat compartan el mensaje del sistema.
Paso 5: La segunda sesión de chat continúa. Sin embargo, debido a límites de memoria, se debe desalojar un nodo del Paso 4. El nuevo turno se agrega después del nodo restante del Paso 4.
Paso 6: El servidor recibe una consulta de aprendizaje breve, la procesa y la inserta en el árbol. El nodo raíz está dividido porque la nueva consulta no comparte ningún prefijo con los nodos existentes.
Paso 7: El servidor recibe un lote de consultas de aprendizaje adicionales de pocas oportunidades. Estas consultas comparten el mismo conjunto de ejemplos de pocas tomas, por lo que un nodo del Paso 6 se divide para permitir el uso compartido.
Paso 8: El servidor recibe un nuevo mensaje de la primera sesión de chat. Expulsa todos los nodos de la segunda sesión de chat porque se han utilizado menos recientemente.
Paso 9: El servidor recibe una solicitud para probar más respuestas a las preguntas en un nodo del Paso 8, probablemente para solicitar coherencia. Para dejar espacio para estas solicitudes, se desalojan varios nodos.
Este ejemplo demuestra cómo RadixAttention maneja la asignación dinámica y el desalojo de nodos en respuesta a diferentes tipos de solicitudes, lo que garantiza una reutilización eficiente de la caché KV y una gestión de la 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 son el resultado de la reutilización de la caché KV, la explotación del paralelismo dentro de un único programa y una decodificación restringida más rápida.

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

Resultados en modelos más grandes con paralelismo tensorial
Los modelos más grandes, Mixtral-8x7B y Llama-70B, se probaron con paralelismo tensorial en el mismo conjunto de puntos de referencia, y los resultados se presentan en la siguiente figura. La aceleración en los modelos más grandes muestra una tendencia similar a la observada en los modelos más pequeños, lo que indica que la optimización de SGLang se generaliza correctamente a modelos más grandes. Se omitieron la guía y LMQL debido a la falta de implementaciones eficientes del paralelismo tensorial.

Resultados en modelos multimodales
SGLang ofrece compatibilidad nativa con modelos multimodales con las primitivas de imagen y vídeo. Las optimizaciones de este artículo son compatibles con estos modelos. Para RadixAttention, el hash de las imágenes de entrada se calcula y se utiliza como clave en el árbol radix, lo que permite reutilizar 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 (vídeo) en ActivityNet. Dado que estos modelos no son compatibles con otros sistemas de referencia, se utilizó como base la implementación original de los autores del modelo en Hugging Face Transformers. Como se muestra en la siguiente tabla, SGLang ofrece un rendimiento hasta seis veces superior en estos puntos de referencia. En llava-bench-in-the-wild, se gestionaron múltiples preguntas sobre la misma imagen, y en este caso, el tiempo de ejecución de SGLang reutilizó la caché KV.

Despliegue de producción
SGLang se ha implementado en Chatbot Arena para ofrecer modelos de peso abierto. Debido al poco tráfico de algunos modelos, solo un trabajador de SGLang atiende cada uno. Después de un mes, se observó una tasa de aciertos de caché RadixAttention del 52.4 % para LLaVA-Next-34B y del 74.1 % para Vicuña-33B. Los accesos a la caché provinieron de mensajes comunes del sistema, imágenes de ejemplo reutilizadas con frecuencia e historiales de chat de varios turnos. Esto redujo la latencia del primer token en un promedio de 1.7 veces para Vicuña-33B.

Conclusión
En este artículo, hemos hablado de SGLang, un sistema recientemente introducido que tiene como objetivo abordar esto proporcionando una ejecución eficiente de programas de modelos de lenguaje complejos. SGLang comprende un lenguaje frontend y un tiempo de ejecución. La interfaz simplifica la programación con primitivas para la generación y el control del paralelismo, mientras que el tiempo de ejecución acelera la ejecución a través de optimizaciones novedosas como RadixAttention para la reutilización de caché KV y máquinas de estados finitos 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 última generación en varios modelos multimodales y de lenguaje grande, abordando tareas como control de agentes, razonamiento lógico, puntos de referencia de aprendizaje de pocas oportunidades, decodificación JSON y recuperación. -Tuberías de generación aumentadas y chat multiturno.












