Искусственный интеллект
SGLang: Эффективное выполнение структурированных языковых моделей программ
Большие языковые модели (LLM) все чаще используются для сложных задач, требующих нескольких генерационных вызовов, продвинутых методов подсказки, управления потоком и структурированных входных/выходных данных. Однако эффективные системы для программирования и выполнения этих приложений отсутствуют. SGLang, недавно представленная система, призвана решить эту проблему, обеспечивая эффективное выполнение сложных языковых моделей программ. SGLang состоит из языка frontend и runtime. Frontend упрощает программирование с помощью примитивов для генерации и контроля параллелизма, а runtime ускоряет выполнение за счет новых оптимизаций, таких как RadixAttention для повторного использования кэша KV и сжатые конечные автоматы для более быстрого декодирования структурированных выходных данных. Эксперименты показывают, что SGLang достигает до 6,4-кратного увеличения пропускной способности по сравнению с системами вывода на основе состояния искусства на различных больших языковых и многомодальных моделях, решая задачи, такие как контроль агента, логическое рассуждение, оценки обучения с несколькими примерами, декодирование JSON, пайплайны генерации с повышенной выдачей и многоповоротный чат.
Недавние достижения в возможностях LLM расширили их полезность, позволяя им обрабатывать более широкий спектр общих задач и функционировать как автономные агенты. В этих приложениях LLM участвуют в многократном планировании, рассуждении и взаимодействии с внешними средами. Это обеспечивается с помощью инструментов, нескольких входных модальностей и различных методов подсказки, таких как обучение с несколькими примерами, самоусиление, скелет мысли и дерево мысли. Эти новые случаи использования требуют нескольких, часто зависимых, вызовов LLM, указывая на тенденцию использовать многоуровневые структуры для выполнения сложных задач.
Этот сдвиг отмечает переход от простого общения к более сложному программному использованию LLM, где программы планируют и контролируют процессы генерации LLM. Эти программы называются “языковыми моделями программ” (LM-программы). Продвинутые методы подсказки и агентские рабочие процессы входят в сферу LM-программ. Существует два общих свойства LM-программ: (1) LM-программы обычно включают несколько вызовов LLM, чередующихся с управлением потоком для выполнения сложных задач и повышения общего качества. (2) LM-программы получают структурированные входные данные и производят структурированные выходные данные, что позволяет составлять LM-программы и интегрировать их в существующие программные системы.
В этой статье мы более подробно рассмотрим фреймворк SGLang, изучим его архитектуру, проанализируем его производительность и сравним его с фреймворками на основе состояния искусства. Итак, начнем.
Введение в SGLang
Несмотря на широкое использование LM-программ, текущие системы для выражения и выполнения их остаются неэффективными. SGLang выявляет две основные проблемы, связанные с эффективным использованием LM-программ:
- Сложность программирования: разработка LM-программ является утомительной и трудной из-за неопределенной природы LLM. Это включает в себя обширную манипуляцию строками, экспериментальное настройка подсказок, хрупкое парсинг выходных данных, обработку нескольких входных модальностей и реализацию механизмов параллелизма. Эта сложность значительно снижает читаемость даже простых программ.
- Неэффективность выполнения: выполнение LM-программ является неэффективным из-за избыточных вычислений и использования памяти. Системы вывода на основе состояния искусства, оптимизированные для снижения задержки и повышения пропускной способности, не имеют прямого знания рабочей нагрузки, что приводит к значительным неэффективностям. Примером этого является повторное использование кэша KV, который состоит из повторно используемых промежуточных тензоров, необходимых для вывода. Текущие системы не имеют эффективных механизмов для облегчения повторного использования кэша KV между несколькими вызовами LLM, что приводит к ненужным вычислениям и расточительному использованию памяти. Кроме того, ограниченное декодирование для структурированных выходных данных, таких как режим JSON, является неоптимальным, поскольку существующие системы могут декодировать только один токен за раз.
Для решения этих проблем SGLang вводит структурированный язык генерации для LLM. Основная идея заключается в систематическом использовании многоуровневой структуры в LM-программах для эффективного выполнения. Как показано на следующей схеме, SGLang имеет две части: язык frontend и runtime.

Frontend упрощает программирование LM-программ, а runtime ускоряет их выполнение. Эти части могут работать вместе для лучшей производительности или функционировать независимо.
SGLang является языком, встроенным в Python, который предоставляет примитивы для генерации (например, extend, gen, select) и контроля параллелизма (например, fork, join). Он совместим с контролем потока Python и библиотеками, что позволяет пользователям легко разрабатывать продвинутые рабочие процессы подсказки с помощью родного синтаксиса Python. SGLang включает в себя интерпретатор и компилятор. Интерпретатор управляет состоянием подсказки как потоком и отправляет примитивные операции в поток для асинхронного выполнения, обеспечивая правильный контроль над синхронизацией и параллелизмом внутри программы. Кроме того, программы SGLang можно отслеживать и компилировать для дальнейших оптимизаций. Runtime SGLang предлагает несколько новых оптимизаций для ускорения выполнения LM-программ:
- RadixAttention: эта техника позволяет автоматически повторно использовать кэш KV между несколькими вызовами генерации. В существующих системах вывода кэш KV запроса отбрасывается после обработки, что предотвращает повторное использование между несколькими вызовами и замедляет выполнение. SGLang поддерживает кэш LRU кэша KV внутри radix-дерева, управляя кэшем KV как традиционным кэшем и используя radix-дерево для эффективного сопоставления, вставки и удаления. Это позволяет runtime эффективно обрабатывать различные модели повторного использования.
- Сжатый конечный автомат: эта техника позволяет более быстро декодировать структурированные выходные данные. Существующие системы следуют ограничениям только для следующего токена, что позволяет им декодировать только один токен за раз. Вместо этого SGLang анализирует ограничения и строит сжатый конечный автомат для представления их, сжимая много-токенный путь в один шаг, когда это возможно, что позволяет декодировать несколько токенов одновременно для более быстрой скорости.
- API Speculative Execution: для API-моделей, таких как OpenAI, SGLang вводит API-спекулятивное выполнение для оптимизации многоуровневых программ.
Используя SGLang, были реализованы различные приложения LLM, включая контроль агента, логическое рассуждение, оценки обучения с несколькими примерами, декодирование JSON, пайплайны генерации с повышенной выдачей и многоповоротный чат. Производительность была протестирована на моделях, включая Llama-7B/70B, Mistral-8x7B, LLaVA-v1.5-7B (изображение) и LLaVA-NeXT-34B (видео) на NVIDIA A10G и A100 GPU. Экспериментальные результаты показывают, что SGLang достигает до 6,4-кратного увеличения пропускной способности на широком спектре рабочих нагрузок, моделей и конфигураций оборудования по сравнению с существующими системами программирования и вывода, включая Guidance, vLLM и LMQL.
SGLang: Модель программирования и методология
Модель программирования SGLang представлена через запущенный пример, описывающий его языковые примитивы и режимы выполнения, и очерчивающий возможности оптимизации runtime. Эта модель упрощает утомительные операции в многоуровневых рабочих процессах (например, манипуляцию строками, вызов API, спецификацию ограничений, параллелизм) путем предоставления гибких и составных примитивов. SGLang является языком, встроенным в Python. Следующая схема показывает программу, которая оценивает эссе об изображении с помощью метода branch-solve-merge.

Функция multi_dimensional_judge принимает три аргумента: `s`, `path` и `essay`. s управляет состоянием подсказки, path — это путь к изображению, а essay — это текст эссе. Новые строки и примитивы SGLang можно добавить к состоянию s для выполнения с помощью оператора +=. Сначала функция добавляет изображение и эссе к подсказке. Затем она проверяет, связано ли эссе с изображением с помощью select, сохраняя результат в s[“related”]. Если связано, подсказка разветвляется на три копии для параллельной оценки из разных измерений, используя gen для хранения результатов в f[“judgment”]. Далее она объединяет оценки, генерирует резюме и присваивает буквенную оценку. Наконец, она возвращает результаты в формате JSON, следующем схеме, определенной регулярным выражением regex. SGLang значительно упрощает эту программу, поскольку эквивалентная программа, использующая интерфейс, подобный OpenAI, потребует в 2,1 раза больше строк кода из-за ручной манипуляции строками и контроля параллелизма.
SGLang предоставляет примитивы для управления состоянием подсказки, генерации и параллелизма, которые можно использовать с синтаксисом Python и библиотеками. Вот эти примитивы:
gen: вызывает модель для генерации и хранит результаты в переменной с именем, указанным в первом аргументе. Он поддерживает аргумент `regex` для ограничения выходных данных, чтобы они следовали грамматике, определенной регулярным выражением (например, схеме JSON).
- select: вызывает модель для выбора наиболее вероятного варианта из списка.
- += или extend: добавляет строку к подсказке.
- [variable_name]: извлекает результаты генерации.
- fork: создает параллельные ветви состояния подсказки.
- join: воссоединяет состояние подсказки.
- image и video: принимают изображения и видео в качестве входных данных.
Самый простой способ выполнить программу SGLang — через интерпретатор, где подсказка рассматривается как асинхронный поток. Примитивы, такие как extend, gen и select, отправляются в поток для асинхронного выполнения. Эти неблокирующие вызовы позволяют коду Python продолжать выполняться без ожидания завершения генерации, подобно запуску CUDA-ядер асинхронно. Каждая подсказка управляется исполняющим потоком в фоновом потоке, что позволяет параллелизму внутри программы. Получение результатов генерации будет блокироваться до тех пор, пока они не будут готовы, обеспечивая правильную синхронизацию. Альтернативно, программы SGLang можно скомпилировать в вычислительные графы и выполнить с помощью графического исполнителя, что позволяет выполнять дополнительные оптимизации. Эта статья использует режим интерпретатора по умолчанию и обсуждает результаты компилятора в приложении D. SGLang поддерживает открытые модели с помощью собственного runtime SGLang (SRT), а также API-модели, такие как OpenAI и Anthropic.
Системы программирования для LLM можно классифицировать как высокоуровневые (например, LangChain, DSPy) и низкоуровневые (например, LMQL, Guidance, SGLang). Высокоуровневые системы предоставляют предопределенные или автоматически сгенерированные подсказки, такие как оптимизатор подсказок DSPy. Низкоуровневые системы обычно не изменяют подсказки, но позволяют直接 манипулировать подсказками и примитивами. SGLang является низкоуровневой системой, подобной LMQL и Guidance. Следующая таблица сравнивает их функции.

SGLang фокусируется на эффективности runtime и поставляется с собственным runtime, что позволяет выполнять новые оптимизации. Высокоуровневые языки (например, DSPy) можно скомпилировать в низкоуровневые языки (например, SGLang). Интеграция SGLang в качестве бэкенда в DSPy для лучшей эффективности runtime продемонстрирована позже.

Вышеуказанный пример иллюстрирует операции RadixAttention с политикой удаления LRU на девяти временных точках, демонстрируя динамическое распределение и удаление узлов в ответ на различные запросы, обеспечивая эффективное повторное использование кэша KV и управление памятью.
Этот пример демонстрирует, как RadixAttention обрабатывает динамическое распределение и удаление узлов в ответ на различные запросы, обеспечивая эффективное повторное использование кэша KV и управление памятью.
SGLang: Оценка и результаты
Результаты на открытых моделях
Результаты задержки и пропускной способности показаны на следующих схемах. SGLang улучшает пропускную способность до 6,4 раза и снижает задержку до 3,7 раза. Эти улучшения являются результатом повторного использования кэша KV, использования параллелизма внутри одной программы и более быстрого ограниченного декодирования.

На этих бенчмарках коэффициент попадания в кэш варьируется от 50% до 99%. Фигура 13 (приложение) перечисляет достигнутые и оптимальные коэффициенты попадания в кэш для всех из них, показывая, что подход к планированию, осведомленному о кэше, SGLang достигает 96% оптимального коэффициента попадания в кэш в среднем.

Результаты на более крупных моделях с тензорным параллелизмом
Более крупные модели, Mixtral-8x7B и Llama-70B, были протестированы с тензорным параллелизмом на том же наборе бенчмарков, и результаты представлены на следующей схеме. Ускорение на более крупных моделях показывает тенденцию, подобную той, которая наблюдается на меньших моделях, что указывает на то, что оптимизация SGLang хорошо обобщается на более крупные модели. Guidance и LMQL были опущены из-за отсутствия эффективных реализаций тензорного параллелизма.

Результаты на многомодальных моделях
SGLang имеет родную поддержку многомодальных моделей с помощью примитивов image и video. Оптимизации в этой статье совместимы с многомодальными моделями. Для RadixAttention вычисляется хэш входных изображений и используется в качестве ключа в radix-дереве, что позволяет повторно использовать кэш KV токенов изображений из одного и того же изображения. LLaVA-v1.5-7B (изображение) была запущена на llava-bench-in-the-wild, а LLaVA-NeXT-34B (видео) — на ActivityNet. Поскольку эти модели не хорошо поддерживаются другими базовыми системами, была использована исходная реализация авторов моделей в Hugging Face Transformers в качестве базовой системы. Как показано в следующей таблице, SGLang обеспечивает пропускную способность до 6 раз выше на этих бенчмарках. В llava-bench-in-the-wild обрабатывались несколько вопросов об одном и том же изображении, и runtime SGLang повторно использовал кэш KV в этом случае.

Развертывание в производстве
SGLang была развернута в Chatbot Arena для обслуживания открытых моделей. Из-за низкого трафика для некоторых моделей только один рабочий SGLang обслуживает каждую модель. После одного месяца был наблюдаем коэффициент попадания в кэш RadixAttention 52,4% для LLaVA-Next-34B и 74,1% для Vicuna-33B. Попадания в кэш были получены из общих системных сообщений, часто повторно используемых примеров изображений и многоповоротных историй чата. Это снизило задержку первого токена в среднем на 1,7 раза для Vicuna-33B.

Окончательные мысли
В этой статье мы говорили о SGLang, недавно представленной системе, которая призвана решить эту проблему, обеспечивая эффективное выполнение сложных языковых моделей программ. SGLang состоит из языка frontend и runtime. Frontend упрощает программирование с помощью примитивов для генерации и контроля параллелизма, а runtime ускоряет выполнение за счет новых оптимизаций, таких как RadixAttention для повторного использования кэша KV и сжатые конечные автоматы для более быстрого декодирования структурированных выходных данных. Эксперименты показывают, что SGLang достигает до 6,4-кратного увеличения пропускной способности по сравнению с системами вывода на основе состояния искусства на различных больших языковых и многомодальных моделях, решая задачи, такие как контроль агента, логическое рассуждение, оценки обучения с несколькими примерами, декодирование JSON, пайплайны генерации с повышенной выдачей и многоповоротный чат.












