Инференс и сервинг 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, остальные разбираются в тренажёре.
- Латентность и пропускная способность (throughput) в сервинге LLM — это...A)Одно и то же понятие, просто названное двумя разными словами для маркетингаB)Throughput — это время ожидания пользователем до появления первого токена ответаC)Латентность — это сколько запросов в секунду обслужено системойD)разные цели: латентность — время на один запрос, throughput — запросов/токенов в секунду; и они конфликтуют
показать ответ и разбор
+D)разные цели: латентность — время на один запрос, throughput — запросов/токенов в секунду; и они конфликтуют// разбор: Латентность — время на один запрос (важны time-to-first-token и время на токен), throughput — сколько запросов/токенов в секунду выдаёт система суммарно. Они в конфликте: большие батчи повышают throughput (GPU загружен), но каждый запрос ждёт дольше — латентность растёт. Онлайн-чат оптимизирует латентность, офлайн-обработка — throughput. Отсюда continuous batching как компромисс.
- Почему continuous (in-flight) batching эффективнее статического батчинга для LLM-сервинга?A)Он убирает потребность в дорогих специализированных GPU-ускорителяхB)Новые запросы входят в батч по мере освобождения слотов, не ждя конца самых длинных генерацийC)Он обеспечивает одинаковую длину всех ответов в батчеD)Он отключает KV-cache ради экономии памяти
показать ответ и разбор
+B)Новые запросы входят в батч по мере освобождения слотов, не ждя конца самых длинных генераций// разбор: В статическом батче запросы стартуют и финишируют вместе: короткие ответы ждут самый длинный, GPU простаивает, а новый запрос ждёт следующего батча. Continuous batching работает на уровне итераций: закончил один запрос — его слот тут же занимает новый из очереди. GPU держится загруженным, throughput и латентность под нагрузкой заметно лучше. Это ядро vLLM/TGI.
- Почему удвоение длины промпта бьёт по стоимости/латентности сильнее, чем линейно?A)Длина входного промпта на итоговую стоимость и латентность вообще никак не влияет в этом случаеB)Стоимость зависит от числа выходных токенов, вход бесплатенC)Attention квадратичен по длине, а KV-cache растёт линейно и съедает память/батчD)Модель при длинном промпте просто откажется отвечать
показать ответ и разбор
+C)Attention квадратичен по длине, а KV-cache растёт линейно и съедает память/батч// разбор: Стоимость определяют и входные, и выходные токены. Само внимание масштабируется квадратично по длине (каждый токен смотрит на все), так что длинный контекст дорожает быстрее линейного на этапе prefill. Плюс KV-cache растёт линейно с длиной и отъедает память, снижая максимальный батч → косвенно бьёт по throughput. Отсюда борьба за компактный контекст и эффективные attention-ядра.
- Что даёт speculative decoding?A)Автоматически без потерь уменьшает итоговый размер основной модели вдвое при её загрузке в памятьB)Ускоряет генерацию: draft-модель предлагает токены, большая проверяет их за один проходC)Повышает фактическую точность ответов за счёт двух независимых проходов по даннымD)Расширяет контекст без дополнительных затрат памяти
показать ответ и разбор
+B)Ускоряет генерацию: draft-модель предлагает токены, большая проверяет их за один проход// разбор: Декодирование по одному токену недоиспользует GPU (упор в память, не в вычисления). Speculative decoding: быстрая маленькая draft-модель угадывает сразу несколько следующих токенов, а большая модель верифицирует их одним параллельным проходом, принимая совпавший префикс. При хорошем угадывании — кратное ускорение без изменения распределения выходов (эквивалентно обычному). Качество и размер модели не меняются.
- Почему prefill (обработка промпта) и decode (генерация) по-разному грузят железо?A)Prefill считает все входные токены параллельно (compute-bound), а decode идёт по одному токену и упирается в память/пропускную KV-cache (memory-bound)B)Они идентичны по профилю нагрузки на GPUC)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.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.