SGLang: как структура программы ускорила LLM-инференс (Рубрика #AI)
Продолжая тему vLLM и PagedAttention (что я разбирал раньше), решил продолжить статье «SGLang: Efficient Execution of Structured Language Model Programs». У vLLM вопрос был: как эффективнее размещать KV cache в памяти. SGLang делает следующий ход: как не вычислять заново точные префиксы, уже обработанные в предыдущих обращениях к модели.
Команда Stanford, UC Berkeley, Shanghai Jiao Tong и Texas A&M смотрела не на отдельный запрос, а на целую LLM-программу: несколько вызовов модели, ветвление, параллельные генерации, общий контекст и структурированный ответ. Главная идея работы, опубликованной на NeurIPS 2024: если движок видит эту структуру, он может оптимизировать всю рабочую нагрузку.
Базовые инженерные идеи здесь такие
1️⃣ Переиспользование — RadixAttention KV cache зависит от точной последовательности предыдущих токенов. SGLang хранит ссылки на него в radix tree — сжатом префиксном дереве — и находит самый длинный уже вычисленный префикс. GPU считает только хвост. Эффект: меньше повторной обработки промпта (prefill) и дубликатов в памяти, ниже задержка до первого токена, выше пропускная способность. Лучше всего это работает с длинными общими system prompts, few-shot примерами, повторяющимся RAG-контекстом и ветвями рассуждения.
2️⃣ Планирование вокруг дорогого состояния Сохранить кэш мало: им нужно воспользоваться до вытеснения. Поэтому планировщик предпочитает запросы с длинным совпадением, а LRU-механизм удаляет давно не использовавшиеся листья, на которые не ссылаются активные запросы. Эффект: больше попаданий в кэш и полезнее батч. Учёт на CPU невелик, но есть риск несправедливости: запрос без выгодного совпадения может ждать дольше.
3️⃣ Использование детерминизма Если на некотором участке грамматика JSON допускает только одно продолжение, сжатый конечный автомат (compressed FSM) склеивает этот участок и обрабатывает его за один проход вместо нескольких шагов. Для закрытых API авторы ещё предложили заранее генерировать текст после stop-маркера: если хвост совпадёт со следующей операцией программы, его можно переиспользовать. Интересно, но именно RadixAttention оказался фундаментом системы.
В экспериментах авторов на их задачах SGLang давал до 6,4 раза большую пропускную способность, чем тогдашние Guidance, vLLM и LMQL. Это общий максимум от нескольких оптимизаций, а не множитель одного RadixAttention. Эффект кэша падает, если префиксы не повторяются или основное время уходит на длинную генерацию.
Сегодня SGLang — уже не столько язык для LLM-программ, сколько полноценная система инференса. RadixAttention остался в ядре; поверх него появился многоуровневый HiCache: GPU → RAM → внешнее хранилище. Вокруг выросли непрерывное формирование батчей, страничное хранение KV cache, спекулятивное декодирование, разнесение обработки промпта и генерации, распределённый запуск, квантизация и OpenAI-совместимый API. Идея управляемого структурированного вывода тоже осталась, но исходный jump-forward на compressed FSM в 2025 году убрали ради упрощения кода. Теперь JSON Schema, regex и EBNF обслуживают отдельные грамматические движки: XGrammar по умолчанию, Outlines и llguidance.
В общем, для меня эта статья продолжает историю vLLM. Производительность часто растёт не от более быстрых вычислений, а от правильно выбранной системной абстракции. vLLM навёл порядок в размещении KV cache и разделении общих блоков. SGLang автоматизировал поиск и повторное использование произвольных точных префиксов между вызовами и связал это с планированием. Оптимизировали не модель, а работу вокруг неё.
#AI #Research #Software #Architecture #Engineering #DistributedSystems #Performance #SystemDesign
Публичные источники
- arXiv: SGLang — Efficient Execution of Structured Language Model Programs
- arXiv: Efficient Memory Management for Large Language Model Serving with PagedAttention
- Книжный куб: разбор vLLM и PagedAttention
- NeurIPS 2024: ссылка из опубликованного Telegram-поста
- NeurIPS 2024: рабочая страница публикации SGLang
- Официальный репозиторий SGLang
- Документация SGLang: structured outputs
- Документация SGLang: многоуровневый KV cache HiCache
- SGLang PR #4032: удаление jump-forward decoding