сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · LLM и RAG

Инференс и сервинг LLM

Зачем это спрашивают

Инференс LLM это деньги и латентность: вопросы «почему медленно» и «почему дорого» встают в первый же месяц любого LLM-продукта. Проверяют словарь оптимизаций и понимание, что у «скорости» два разных числа.

// TTFT и токены-в-секунду - разные метрики, ведут себя по-разному и оптимизируются разным.

Авторегрессия, TTFT и KV-cache

Генерация авторегрессивна: токен за токеном. Латентность распадается на TTFT (time to first token) - время до первого токена (фаза prefill, обработка промпта), и скорость декода (время на токен). Стриминг не ускоряет, но маскирует хвост: юзер читает, пока модель пишет.

KV-cache (key-value) хранит ключи и значения attention всех прошлых токенов - без него каждый новый токен пересчитывал бы весь контекст. Цена: память кэша растёт с длиной контекста и размером батча - длинные контексты съедают GPU быстрее весов.

// PagedAttention управляет KV-кэшем страницами, как виртуальная память: меньше фрагментации - больше конкурентных запросов на той же GPU.

TTFT
time to first token - латентность prefill-фазы
KV-cache
кэш attention прошлых токенов; память ~ контекст × батч

Throughput: батчинг и квантизация

Continuous batching (vLLM и семейство) подсаживает новые запросы в батч на лету, не дожидаясь конца длинных, кратный рост throughput против статических батчей.

Квантизация (int8/int4) режет память и ускоряет инференс при малой потере качества. Порядок действий строгий: сначала оценка качества на своих задачах, потом выкатка - усреднённые бенчмарки скрывают деградацию именно твоего кейса.

// Спекулятивное декодирование: маленькая модель-черновик предлагает несколько токенов, большая проверяет их пачкой - ускорение без потери качества, математика ответа не меняется.

continuous batching
подсадка запросов в батч на лету - кратный throughput
speculative decoding
черновик предлагает, большая модель проверяет пачкой

Экономика токенов

Цена = токены: длина промпта и ответа. Рычаги: короче системный промпт, кэширование общих префиксов (один системный промпт на тысячи запросов), лимиты на длину ответа.

Роутинг по сложности: простые запросы - на дешёвую модель, сложные - на флагман. Экономит кратно, потому что распределение запросов всегда перекошено в простые.

// Держи в голове порядок: input-токены обычно дешевле output - многословный ответ дороже длинного контекста.

Как отвечать: «LLM-сервис медленный и дорогой. Что будешь делать?»

Сначала разделю жалобу на два числа: TTFT это prefill и длина промпта, скорость печати это decode. Дальше по рычагам: continuous batching (vLLM) - обычно самый большой выигрыш throughput; квантизация int8/int4 после проверки качества на наших задачах; кэш общих префиксов, чтобы системный промпт не пережёвывался каждый раз; спекулятивное декодирование для скорости без потери качества. По деньгам - роутинг: большинство запросов простые и не заслуживают флагманской модели. И слежу за KV-кэшем: длинные контексты × батч съедают память быстрее, чем веса.

Диагностика двумя метриками и рычаги в порядке отдачи - так отвечает тот, кто реально платил за GPU.

На чём валят

  • Оценивать «скорость модели» одним числом - TTFT и токены/сек ведут себя по-разному.
  • Игнорировать рост KV-кэша - длинные контексты × батч съедают GPU-память быстрее весов.
  • Квантовать без оценки на своих задачах - усреднённые бенчи скрывают твою деградацию.
  • Все запросы через флагман - роутинг по сложности экономит кратно.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 14, остальные разбираются в тренажёре.

  1. #inference_serving1 / 5
    Латентность и пропускная способность (throughput) в сервинге LLM — это...
    A)Одно и то же понятие, просто названное двумя разными словами для маркетинга
    B)Throughput — это время ожидания пользователем до появления первого токена ответа
    C)Латентность — это сколько запросов в секунду обслужено системой
    D)разные цели: латентность — время на один запрос, throughput — запросов/токенов в секунду; и они конфликтуют
    показать ответ и разбор
    +D)разные цели: латентность — время на один запрос, throughput — запросов/токенов в секунду; и они конфликтуют

    // разбор: Латентность — время на один запрос (важны time-to-first-token и время на токен), throughput — сколько запросов/токенов в секунду выдаёт система суммарно. Они в конфликте: большие батчи повышают throughput (GPU загружен), но каждый запрос ждёт дольше — латентность растёт. Онлайн-чат оптимизирует латентность, офлайн-обработка — throughput. Отсюда continuous batching как компромисс.

  2. #inference_serving2 / 5
    Почему continuous (in-flight) batching эффективнее статического батчинга для LLM-сервинга?
    A)Он убирает потребность в дорогих специализированных GPU-ускорителях
    B)Новые запросы входят в батч по мере освобождения слотов, не ждя конца самых длинных генераций
    C)Он обеспечивает одинаковую длину всех ответов в батче
    D)Он отключает KV-cache ради экономии памяти
    показать ответ и разбор
    +B)Новые запросы входят в батч по мере освобождения слотов, не ждя конца самых длинных генераций

    // разбор: В статическом батче запросы стартуют и финишируют вместе: короткие ответы ждут самый длинный, GPU простаивает, а новый запрос ждёт следующего батча. Continuous batching работает на уровне итераций: закончил один запрос — его слот тут же занимает новый из очереди. GPU держится загруженным, throughput и латентность под нагрузкой заметно лучше. Это ядро vLLM/TGI.

  3. #inference_serving3 / 5
    Почему удвоение длины промпта бьёт по стоимости/латентности сильнее, чем линейно?
    A)Длина входного промпта на итоговую стоимость и латентность вообще никак не влияет в этом случае
    B)Стоимость зависит от числа выходных токенов, вход бесплатен
    C)Attention квадратичен по длине, а KV-cache растёт линейно и съедает память/батч
    D)Модель при длинном промпте просто откажется отвечать
    показать ответ и разбор
    +C)Attention квадратичен по длине, а KV-cache растёт линейно и съедает память/батч

    // разбор: Стоимость определяют и входные, и выходные токены. Само внимание масштабируется квадратично по длине (каждый токен смотрит на все), так что длинный контекст дорожает быстрее линейного на этапе prefill. Плюс KV-cache растёт линейно с длиной и отъедает память, снижая максимальный батч → косвенно бьёт по throughput. Отсюда борьба за компактный контекст и эффективные attention-ядра.

  4. #inference_serving4 / 5
    Что даёт speculative decoding?
    A)Автоматически без потерь уменьшает итоговый размер основной модели вдвое при её загрузке в память
    B)Ускоряет генерацию: draft-модель предлагает токены, большая проверяет их за один проход
    C)Повышает фактическую точность ответов за счёт двух независимых проходов по данным
    D)Расширяет контекст без дополнительных затрат памяти
    показать ответ и разбор
    +B)Ускоряет генерацию: draft-модель предлагает токены, большая проверяет их за один проход

    // разбор: Декодирование по одному токену недоиспользует GPU (упор в память, не в вычисления). Speculative decoding: быстрая маленькая draft-модель угадывает сразу несколько следующих токенов, а большая модель верифицирует их одним параллельным проходом, принимая совпавший префикс. При хорошем угадывании — кратное ускорение без изменения распределения выходов (эквивалентно обычному). Качество и размер модели не меняются.

  5. #inference_serving5 / 5
    Почему prefill (обработка промпта) и decode (генерация) по-разному грузят железо?
    A)Prefill считает все входные токены параллельно (compute-bound), а decode идёт по одному токену и упирается в память/пропускную KV-cache (memory-bound)
    B)Они идентичны по профилю нагрузки на GPU
    C)Prefill медленнее decode на длине промпта
    D)Decode не использует GPU вообще
    показать ответ и разбор
    +A)Prefill считает все входные токены параллельно (compute-bound), а decode идёт по одному токену и упирается в память/пропускную KV-cache (memory-bound)

    // разбор: Prefill обрабатывает весь промпт за один проход — токены идут параллельно, GPU занят матричными умножениями (compute-bound), отсюда time-to-first-token растёт с длиной промпта. Decode генерирует по одному токену: на каждый шаг тянутся все веса и KV-cache при малом объёме вычислений — упор в пропускную способность памяти (memory-bound). Разный профиль объясняет, почему батчинг и spec-decoding бьют в decode, а длинный промпт — в prefill.

дальше

Теорию прочитали. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.