Стек инференса LLM (LLM Inference Stack): из чего он состоит и как уложиться в SLA и бюджет

Стек инференса LLM — это производственная «машина», которая превращает запрос пользователя в поток токенов ответа, соблюдая SLA по задержкам, бюджет стоимости и правила безопасности. В отличие от обучения, где основная задача — адаптировать параметры, здесь важно эффективно исполнять уже обученную модель: быстро считать матричные операции, грамотно использовать память/кэш, выбирать режимы декодирования и маршрутизировать запросы между профилями моделей.

Стек инференса LLM (LLM Inference Stack): из чего он состоит и как уложиться в SLA и бюджет

Практически любой продукт на базе LLM опирается на соседние слои AI-системы: индексы знаний, retrieval и валидацию. Связанные материалы: базовые понятия см. в LLM, экономика и путь запроса — в Инференсе, принципы сжатия и ускорения — в Квантовании, обзор верхнего уровня — в AI-стеке. В этой статье мы спускаемся ниже — к слоям исполнения, планировщикам и кёрнелам, от которых зависит токенов/сек, TTFT и цена/1k токенов.

Стек инференса LLM (LLM Inference Stack) - Картина целиком: слои стека инференса

Ниже — минимальная, но достаточная декомпозиция. Логика идёт снизу вверх: от «железа» к API приложения.

  • Железо и драйверы. GPU/CPU/ускорители, память (HBM/DDR), межсоединения (NVLink/PCIe), драйверы (CUDA/ROCm), планировщик ОС.
  • Кёрнелы и библиотеки. Оптимизированные ядра матричных операций, внимания (flash-attention), квантизованные операторы, BLAS, профили для int8/int4.
  • Компиляторы/рантаймы. Графовые оптимизации, фьюзинг операторов, планирование на устройство, prepacking весов, JIT/AOT.
  • Модельный слой. Хранение весов, раскладка тензоров, KV-кэш, политика загрузки/выгрузки, потоковая декодировка.
  • Планирование/батчинг. Очереди запросов, микробатчи, смешивание потоков, приоритеты классов задач.
  • Маршрутизация моделей. Выбор маршрута (компактная/тяжёлая, квантизованная/точная), спекулятивная декодировка, fallback.
  • API/стриминг. Протоколы (gRPC/HTTP), time-to-first-token (TTFT), backpressure, лимиты.
  • Наблюдаемость и биллинг. Метрики P50/P95, токены/сек, цена/эпизод, трассировки, журналы версий.
  • Безопасность и политика. Ограничения подсказки, фильтры, контроль инструментов, SSO/ACL.

Каждый слой должен быть заменяемым и наблюдаемым, иначе локальная оптимизация «съедается» соседними узкими местами.

Железо: что действительно важно

Главные бюджеты инференса — память и полоса памяти, затем уже FLOPs. Из этого следуют практические правила:

  • Память и раскладки. Большие контексты «едят» VRAM за счёт KV-кэша; экономия на битности (int8/int4) и компактной раскладке кэша критична.
  • Полоса доступа. Flash-attention и «плиточные» кёрнелы уменьшает трафик между HBM и ALU.
  • Межсоединения. При мульти-GPU внимательно к sharding/pipeline параллелизму: коммуникации часто дороже вычислений.
  • CPU и диски. Для компактных моделей и офлайн-режимов CPU эффективен; для холодных весов важна скорость дисков/кэшей.

Железо — только фундамент; без грамотных кёрнелов и планировщика выигрыш мал.

Кёрнелы и библиотеки: где рождаются токены/сек

Кёрнелы реализуют «горячие» операции: матричные умножения, внимание, нелинейности и нормализации. Ключевые приёмы:

  • Flash-attention/GQA/MQA. Снижает использование памяти внимания и повышает пропускную способность.
  • Fused-операторы. Объединяют несколько шагов в один проход по памяти.
  • INT8/INT4 кёрнелы. Специализированные ядра для квантизованных весов и/или активаций.
  • Prepacking/лейаут. Раскладка весов под «родную» память устройства, чтобы реже трогать HBM.

Именно здесь решается, будет ли ваша система считать 100 или 400 токенов/сек на узел.

Компиляторы и рантаймы: как «сплющить» граф модели

Рантайм превращает высокоуровневый граф модели в последовательность операторов для устройства:

  • Фьюзинг графа. Удаление лишних копий, объединение последовательностей в один кёрнел.
  • Квантизованные пути. Подмена операторов на INT8/INT4 при сохранении точности (см. квантование).
  • JIT/AOT. Сборка графа заранее под конкретную архитектуру снижает холодный старт.
  • Static-shape/Static-batch. Там, где это возможно, фиксируйте формы тензоров для предкомпилированных путей.

Цель — меньше «лейтенси на оператор» и меньше «бередить» память.

Модельный слой: веса, KV-кэш, декодирование

Веса. Держите их в формате, совместимом с кёрнелами и планируемой битностью. Популярная практика — весовое INT4/INT8 для линейных слоёв и FP16/BF16 для «хрупких» узлов.

KV-кэш. В авто-регрессии хранит ключи/значения внимания для уже сгенерированных токенов. Это главный потребитель VRAM при длинных контекстах:

  • INT8/INT4 кэш — кратно экономит память, иногда «бесплатно» по качеству на ваших задачах.
  • Группировка/страйдинг — храните кэш так, чтобы декодер читал его последовательно.
  • Политики очистки — ограничивайте длину диалога, используйте «свертки» истории.

Декодирование. Greedy/beam/top-p/top-k управляют качеством/скоростью. Для фактов — консервативные режимы; для креатива — nucleus sampling. Общее — экономить шаги внимания.

Планирование и батчинг: как повысить токенов/сек без взрыва P95

  • Микробатчинг. Сшивайте однородные запросы в мини-партии; выравнивайте длины шагов.
  • Смешивание потоков. Параллельно обслуживайте несколько сессий; приоритизируйте короткие запросы.
  • Адаптивный батчинг. Размер партии меняется от очереди и класса задачи.
  • Контроль P95. Большие батчи — это эффективно, но могут «размазать» хвост задержек; держите лимиты класса.

Правильный планировщик даёт ×1.5–×3 прироста по токенам/сек при той же архитектуре.

Маршрутизация и спекулятивная декодировка

  • Маршрутизация по сложности. Компактная модель «по умолчанию», тяжёлая — по сигналам (длина, домен, требуемая точность).
  • Спекулятивная декодировка. Лёгкий «спекулянт» предлагает несколько токенов, базовая модель быстро подтверждает/отбрасывает. Это снижает число «дорогих» итераций.
  • Fallback/деградация. При перегрузе — сжимать контекст, упрощать режимы декодера, предлагать краткие «заглушки» с ссылкой на доотправку.

Маршрутизация — один из самых экономичных рычагов, когда у вас не один сценарий.

API и стриминг: как это видит пользователь

  • TTFT — время до первого токена — ключевая метрика UX. Снижайте prefill и стартовую «подготовку»; включайте KV-кэш.
  • Потоки. Стриминг отдаёт токены по мере готовности; бэкпрешер и «сердцебиение» соединения важны для стабильности.
  • Квоты и лимиты. Ограничения токенов/сек, длина контекста/ответа, контроль шаблонов (JSON/таблицы).

Внешний протокол прост, но внутри он «держится» на планировщике и кэше.

Наблюдаемость, трассировка и стоимость

  • Метрики по шагам. TTFT, токенов/сек, P50/P95 по префиллу/декодированию/постобработке.
  • Стоимость. Цена/1k токенов ввода/вывода и «скрытые» расходы (retrieval/сжатие).
  • Трассировки. Сквозные trace-id, версия модели, параметры декодера, кёрнелы и режим квантования.
  • Алерты. Рост P95, падение токенов/сек, промахи кэша, перегрев.

Без этого управлять стеком невозможно: регрессии часто приходят «сверху» (сценарии, контент), а видны «снизу» (кёрнелы, сеть).

Интеграция с retrieval и знанием

В сквозной архитектуре LLM работает не в вакууме: часто он завернут в RAG. Важные связи:

  • Меньше «мусора» в контексте — быстрее префилл и дешевле эпизод.
  • Хороший rerank даёт цитируемые выдержки и экономит токены.
  • Чёткий контракт подсказки (формат/ограничения) снижает «флэппинг» декодера.

Фундамент по retrieval см. в RAG-pipeline, а про индексы — в обзоре векторных БД и терминале про эмбеддинги.

Таблица: эффекты оптимизаций стека

Оптимизация TTFT Токенов/сек Стоимость Комментарии
KV-кэш ↓ заметно Максимальный эффект на длинных контекстах
Батчинг/микробатч ↑ P95 / ≈ P50 ↑↑ Требует выравнивания длин
Спекулятивная декодировка Зависит от качества «спекулянта»
Квантование весов ≈/↓ INT8 почти «бесплатно», INT4 осторожно
Квантованный KV-кэш ↓ VRAM ↑ при длинных Проверять качество на ваших задачах
Flash-attention/GQA Сильнее на больших последовательностях
Сжатие контекста ↑ косвенно ↓↓ Ключ к экономике RAG
Маршрутизация моделей ↑ среднее Компактная модель «по умолчанию»

Таблица: профили инференса и приоритеты

Профиль Пример Главные KPI Рецепты
Интерактивный чат Поддержка/ассистент TTFT, P95 Стриминг, KV-кэш, conservative decode
Генерация кода IDE-помощник Pass@k, строгий формат Ограничивающие подсказки, JSON-контракты
Массовая суммаризация Отчёты/корпус Цена/объект Пакеты, квантование, компактные модели
Поиск с RAG Внутренний поиск Faithfulness, цитаты Гибридный поиск, rerank, сжатие

Планирование ёмкости: как прикинуть мощность

Упрощённая оценка (ориентиры):

  • Prefill: ~O(L контекста) токенов; Декод: ~O(L ответа).
  • Токены/сек на поток: зависит от битности, кёрнелов и режима внимания; измеряйте на реалистичных подсказках.
  • Параллелизм: микробатчинг × количество потоков × устройства.

Примерный бюджет узла: «N токенов/сек при средних L_in/L_out» → рассчитать максимальный QPS с учётом P95 и доли «длинных» запросов.

Безопасность и политика

  • Разделяйте инструкции и данные. Документы/подсказки не должны исполнять команды; фильтруйте prompt-injection.
  • Контракты форматов. JSON-схемы и валидаторы — must-have для инструментов.
  • Секреты. Ключи — вне подсказок, доступ к инструментам — через сервисные аккаунты.
  • Пути деградации. При перегрузе — «облегчённый режим» с короткими ответами и строгими лимитами.

Чек-лист внедрения стека инференса

  • Определите SLA: TTFT, P95, цена/1k токенов, доля ошибок.
  • Выберите модельные профили: компактная/средняя/тяжёлая, их битности и кёрнелы.
  • Настройте KV-кэш и его квантование; зафиксируйте лимиты контекста.
  • Включите батчинг и классы задач; задайте приоритеты.
  • Введите спекулятивную декодировку и маршрутизацию по сложности.
  • Наладьте наблюдаемость и трейсы: версии моделей/индексов/кёрнелов, стоимость.
  • Пропишите fallback/деградацию и «красные кнопки» отката конфигов.
  • Проведите стресс-тесты (шторм запросов, длинные контексты, отказ индекса).
  • Запустите A/B и регресс-наборы; замерьте реальные кривые качества/стоимости.
  • Документируйте операционные процедуры: кто дежурит, как эскалировать.

Частые анти-паттерны

  • «Одна большая модель на всё». Стоимость растёт быстрее качества. Лечение — маршрутизация и профили моделей.
  • Бесконтрольный контекст. Длинные подсказки «убивают» TTFT/P95. Лечение — сжатие и лимиты.
  • Нет кэшей. Отсутствие KV-кэша/кэша ответов на шаблонные запросы — лишние миллисекунды и доллары.
  • Только офлайн-бенчмарки. Без A/B легко «перетюнить» кёрнелы и режимы декодирования.
  • Смешение ролей безопасности. Инструменты без контрактов и мок-режима ведут к инцидентам.

FAQ

Почему TTFT иногда важнее общей задержки? Потому что влияет на «ощущение скорости» в стриминге. Ранний вывод первых токенов повышает терпимость к общей длительности.

INT8 всегда безопаснее INT4? В целом да: INT8 ближе к FP16 по качеству и широко поддержан. INT4 даёт ×4 экономию памяти, но требует калибровки и смешанных схем — см. квантование.

Батчинг ухудшает P95 — что делать? Вводите классы задач (короткие/длинные), ограничивайте размер партии и используйте адаптивное смешивание.

Зачем спекулятивная декодировка, если есть быстрая модель? Она экономит итерации «дорогой» модели и снижает TTFT; при хорошей калибровке даёт 10–40% выигрыша.

Нужен ли всегда RAG? Не всегда. Но для фактов и обновляемых знаний RAG повышает верность и объяснимость. См. RAG-pipeline.

Где чаще всего «течёт» VRAM? В KV-кэше на длинных контекстах. Помогает квантование кэша, лимиты истории и свёртка диалогов.

Что важнее: FLOPs или память? В инференсе LLM чаще упираются в полосу памяти, поэтому кёрнелы и раскладки важнее «теоретических FLOPs».

Почему падает скорость после обновления модели? Сменился граф, формы тензоров или битности; нужен новый фьюзинг, перепаковка весов и перестройка кэшей.

Как считать цену эпизода честно? Суммируйте токены ввода/вывода, стоимость retrieval/сжатия и накладные расходы. Отчёты должны хранить версию модели/кёрнелов.

Какая «золотая пятёрка» метрик ежедневного контроля? TTFT, токенов/сек, P95, цена/1k токенов, доля успехов/ошибок по классам задач.

Словарь терминов

  • TTFT (time-to-first-token) — время до первого токена в потоке ответа.
  • KV-кэш — буфер ключей/значений внимания для ускорения авто-регрессии.
  • Батчинг/микробатчинг — совместное исполнение нескольких запросов.
  • Спекулятивная декодировка — ускорение генерации с «предсказателем».
  • Кёрнел — низкоуровневое ядро операции (матр. умножение, внимание).
  • Фьюзинг — объединение операторов для уменьшения проходов по памяти.
  • Flash-attention — кёрнел внимания с оптимизированным доступом к памяти.
  • Маршрутизация моделей — выбор профиля исполнения по признакам запроса.
  • INT8/INT4 — квантизованные форматы весов/активаций.
  • P50/P95 — медиана и 95-й перцентиль задержки.

См. также

Task Runner