Инференс — применение уже обученной модели к запросам. Обучение бывает один раз, инференс — на каждое обращение, и именно он определяет операционные расходы.
Две фазы и почему это важно
Обработка входа. Модель разом читает переданный текст. Считается параллельно, крупными матричными умножениями, с высокой загрузкой вычислительных ядер — упирается в вычислительную мощность. Этап называют префиллом.
Генерация. Ответ строится по одному токену: каждый следующий зависит от предыдущего, распараллелить нельзя. На каждом шаге ради одного токена приходится перекачивать из памяти все веса модели, а вычислений при этом выполняется немного — узкое место не счёт, а пропускная способность памяти. Говорят, что декодирование ограничено памятью.
Отсюда наблюдение, которое объясняет многое: длинный вход обрабатывается быстро, длинный выход — медленно. Просьба «отвечай кратко» ускоряет ответ сильнее, чем сокращение переданных документов.
Батчинг при генерации почти бесплатен. Пока узкое место — чтение весов, к одному чтению можно подключить несколько запросов: скорость каждого из них почти не падает, а общий поток растёт. Это работает до насыщения памяти под кэш и вычислительных пределов — за ними деградация наступает резко.
KV-кэш и память
Кэш хранит контекст, а не ответ. Чтобы построить очередной токен, модель использует промежуточные результаты внимания ко всем предыдущим токенам — KV-кэш. Он живёт всё время запроса, и его объём пропорционален длине контекста и размеру модели.
Параллелизм упирается в память, а не в вычисления. На длинных контекстах кэш на один запрос занимает объём, сопоставимый с весами небольшой модели, и именно он определяет, сколько запросов сервер держит одновременно. Совпадающие префиксы — общий системный промпт, общие документы — из кэша переиспользуются.
Управление кэшем — главная забота сервера инференса. Как выделяются блоки и переиспользуются префиксы — в статье про vLLM; принципы общие для серверов, работающих под нагрузкой.
Показатели, которые меряют
Время до первого токена — определяет ощущение отзывчивости. Растёт вместе с объёмом входа.
Скорость генерации — токенов в секунду. Для интерактивной работы комфортным считается темп, превышающий скорость чтения.
Пропускная способность — сколько запросов система обслуживает в единицу времени. Для сервиса важнее скорости одного ответа.
Эти показатели конфликтуют: объединение запросов в пакеты повышает пропускную способность и ухудшает время отклика отдельного пользователя.
Диагностика по двум точкам. Долгий первый токен при бодрой генерации — узкое место во входе: режьте контекст и переносите загрузку документов из запроса. Нормальный первый токен и медленный неровный стриминг — перегружен этап генерации: меньше запросов на инстанс, больше инстансов. Растущая очередь при нормальных обоих — не хватает пропускной способности в целом.
Латентность или пропускная способность
Одно железо — два режима. Интерактивный сервис хочет малых пакетов и свободных мощностей: важен первый токен и ровный стриминг. Пакетная обработка документов допускает крупные пакеты и очередь: стоимость одного запроса падает в разы, латентность никого не волнует.
Смешивать режимы в одном инстансе — терять оба. Фоновая партия отнимает память и полосу у интерактива, а интерактивные приоритеты не дают пакету набрать размер. Разнесите по отдельным инстансам или хотя бы по временным окнам.
Профиль задачи определяет железо. Входо-тяжёлые задачи — поиск по документам с большим контекстом — нагружают вычисления. Длинная генерация и большие контексты — пропускную способность памяти и её объём под кэш.
Что ускоряет
Кэш ключей и значений. Промежуточные вычисления переиспользуются между шагами генерации. Занимает память, и на длинном контексте — много.
Объединение в пакеты на лету. Новые запросы подключаются к уже идущим, а не ждут очереди. Основной вклад в пропускную способность.
Квантизация. Меньше данных перекачивается из памяти — а именно перекачка и есть узкое место генерации.
Кэш ответов. Если запросы повторяются, самый дешёвый ответ — тот, который не считали.
Своё или облако
Вопрос упирается в загрузку. Облачная модель тарифицируется по обращениям и не требует вложений; своя требует ускорителя, который стоит одинаково и при полной загрузке, и при простое.
Своя инфраструктура окупается при устойчивом потоке и становится обязательной, если данные нельзя выпускать за периметр. При редких обращениях она почти всегда дороже.
Тарификация отражает фазы. Облачные провайдеры считают входные и выходные токены по разным ценам, и выходные обычно дороже в несколько раз: генерация последовательна и занимает слот на всё время ответа. Стоимость обращения складывается из обоих слагаемых — как это считать на практике, в статье про токены.
Пакетные тарифы. Многие провайдеры дают скидку на отложенную пакетную обработку — те же модели без гарантий немедленного ответа: провайдер сам собирает запросы в удобные пакеты. Для ночных загрузок без дедлайна это самый дешёвый путь.
Типичные ошибки при оценке
Замер на первом запросе. Модель загружается в память, кэши пусты — первая цифра всегда хуже установившейся.
Оценка по одному пользователю с выводом о пропускной способности. Эти показатели связаны нелинейно, и экстраполяция даёт завышенный результат.
Сравнение решений на разных длинах контекста. Разница объясняется длиной, а не решением.
Закупка ускорителей по пиковой вычислительной мощности под сервис с длинными ответами. Если доминирует генерация, узким местом будет пропускная способность памяти и объём под кэш, а не пиковые вычисления.
Расчёт стоимости по цене входных токенов. Выходные дороже, и на задачах с развёрнутыми ответами именно они определяют счёт.
Частые вопросы
Почему ответ генерируется медленно, а вход читается быстро?
Вход обрабатывается параллельно, а ответ строится по одному токену: каждый следующий зависит от предыдущего. Поэтому длина ответа влияет на время сильнее, чем длина запроса, и просьба отвечать кратко ускоряет заметнее, чем сокращение переданных документов.
Что важнее — скорость ответа или пропускная способность?
Зависит от сценария, и они конфликтуют. Для интерактивного помощника важно время до первого токена. Для фоновой обработки документов — сколько задач система закрывает в час, и там объединение запросов в крупные пакеты выгодно, хотя каждый отдельный ответ приходит позже.
Когда своя инфраструктура дешевле облака?
При устойчивой загрузке. Ускоритель стоит одинаково и при полной работе, и при простое, поэтому редкие обращения почти всегда дешевле обслуживать облачной моделью. Отдельный случай — запрет на вынос данных: тогда вопрос стоимости вторичен.
Какие характеристики ускорителя важнее — вычисления или память?
Зависит от профиля: короткие ответы при длинных входах нагружают вычисления, длинные ответы и большие контексты — пропускную способность памяти и её объём. Для интерактивного сервиса обычно важны обе, и решение проверяют замером на своём профиле нагрузки, а не по пиковым числам спецификации.
Почему при росте числа пользователей время ответа резко деградирует в какой-то момент?
Пока есть запас памяти под кэш и вычислений, пакеты растут почти без потери скорости — система «впитывает» нагрузку. При насыщении включаются ожидание в очереди и пересчёты вытесненного кэша, и деградация наступает ступенью, а не плавно. Точку насыщения находят нагрузочным тестом, до внедрения.
Почему одинаковые запросы отвечают с разной скоростью?
Скорость зависит от соседей по пакету и загрузки инстанса: один и тот же запрос в пустом и в полном пакете проходит за разное время. Корректное сравнение вариантов делают на фиксированной нагрузке и по средним за период, а не по единичным прогонам.