К основному содержимому
к странице архива
#AI

SGLang: как структура программы ускорила LLM-инференс (Рубрика #AI)

#AI #Research #Software #Architecture #Engineering #DistributedSystems #Performance #SystemDesign
ПодписатьсяПост в Telegram

Продолжая тему 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

Публичные источники