Использование машинного обучения: метрики быстродействия облачных и локальных моделей
Пользователь отправляет запрос AI-ассистенту, но вместо ответа несколько секунд видит пустой экран. Для инженера эта пауза не одно число, а цепочка вычислений, сетевых переходов и ожидания в очереди. Каждое звено можно измерить, а иногда и ускорить.

Поэтому быстродействие генеративной модели давно стало частью пользовательского опыта: от него зависит, насколько отзывчивым будет сервис и какие архитектурные решения окажутся оправданными.
«Скорость модели» складывается из нескольких фаз. Сравнивать локальный запуск с облачным API по одному показателю рискованно: одна система может быстрее начать ответ, другая — ровнее передавать токены или лучше держать параллельную нагрузку. Разберём, что именно измерять и как читать эти метрики.
От запроса к первому токену: что скрывается за TTFT
TTFT (Time to First Token) — время от отправки запроса до появления первого сгенерированного токена. Токеном может быть слово, его часть или знак препинания. Для пользователя это пауза перед началом ответа: если она заметна, ощущение отзывчивости не спасёт даже высокая скорость последующей генерации.
В интерфейсной разработке часто ориентируются на порог около 500 мс, но воспринимаемая скорость зависит от контекста. Короткая пауза в голосовом помощнике может раздражать сильнее, чем такая же пауза при формировании длинного отчёта. Поэтому значение TTFT полезно рассматривать вместе со сценарием, а не как универсальную оценку качества.
На TTFT влияют несколько факторов:
1. Сеть. В облачном сценарии запрос проходит от клиента к серверу, а первый фрагмент ответа возвращается обратно. Время зависит от маршрута, расстояния до дата-центра, сетевой нагрузки и устройства API. При локальном запуске обращение к удалённому сервису не требуется, хотя задержки внутри приложения и компьютера всё равно остаются.
2. Очередь. Если вычислительные ресурсы заняты другими запросами, новый запрос может ждать начала обработки. В облаке это зависит от нагрузки и организации сервиса. Локальная модель тоже не свободна от очередей: они появляются, если к ней одновременно обращаются несколько процессов или если устройство занято другими задачами.
3. Префилл. На этой фазе модель обрабатывает входной текст и подготавливает состояние для дальнейшей генерации. В трансформере внимание к предыдущим токенам требует вычислений по контексту, поэтому длинный запрос обычно требует больше работы до первого ответа, чем короткий. На префилл влияют архитектура модели, размер контекста, реализация движка и доступная память.
В декодировании часто используется KV-кэш, где сохраняются ключи и значения внимания, рассчитанные для предыдущих токенов. Он избавляет модель от необходимости повторно выполнять часть вычислений на каждом шаге и обычно ускоряет генерацию. Однако это оптимизация, а не обязательное условие: без кэша модель тоже может декодировать, повторно вычисляя нужные состояния. Цена такого подхода обычно выражается в дополнительных вычислениях и более медленном выводе.
Локальная компактная модель на подходящем оборудовании может быстро начать ответ, особенно на коротком запросе. Но из этого не следует, что облако обязательно медленнее. Более мощный серверный ускоритель способен компенсировать сетевую задержку, а очередь или высокая нагрузка, наоборот, способны ухудшить облачный TTFT. Итог зависит от модели, оборудования, сети, размера запроса и текущей загрузки.
Фаза декодирования: плавность генерации и метрики ITL, TPOT
После первого токена модель продолжает генерировать ответ по одному токену за раз. Для этой фазы полезны две метрики:
- ITL (Inter-Token Latency) показывает время между соседними токенами. Если часть текста приходит быстро, а затем возникает длинная пауза, среднее значение может этого не показать. ITL помогает заметить такие провалы.
- TPOT (Time per Output Token) показывает среднее время генерации одного выходного токена. Это удобная метрика для сравнения скорости декодирования, но само усреднение может скрыть отдельные задержки.
В режиме стриминга, когда сервис отправляет текст частями по мере генерации, важны обе метрики. TPOT описывает средний темп, а ITL помогает понять, насколько ровно этот темп поддерживается. Поток может выглядеть быстрым в целом, но восприниматься рваным, если между отдельными фрагментами возникают длинные паузы.
Для оценки полной задержки ответа используют приближённое разложение:
E2E ≈ TTFT + (N − 1) × TPOT
Здесь N — число выходных токенов. Формула предполагает, что после первого токена генерация идёт с примерно постоянным средним темпом. На практике реальное время меняется из-за колебаний ITL, сетевой передачи и обработки ответа приложением.
Для короткого ответа заметную часть времени может составлять ожидание первого токена. В длинной генерации сильнее сказывается скорость декодирования: небольшая разница в среднем времени на токен накапливается по мере роста ответа. Поэтому при настройке чат-бота с короткими репликами стоит отдельно смотреть на TTFT, а для генерации больших документов — ещё и на TPOT, ITL и общую длительность выдачи.
Среднее значение не рассказывает всей истории. Полезно смотреть на распределение задержек, в том числе на P95 и P99: эти процентили показывают, насколько долго ждут запросы в более медленной части выборки. Если средний TTFT выглядит приемлемо, но P99 резко растёт, часть пользователей всё равно будет регулярно сталкиваться с долгими паузами.
Локальный запуск против облачного API: где выигрывает каждый вариант
Вопрос «что быстрее» имеет смысл только с уточнением условий. Локальная система избавляет от обращения к удалённому API, но ограничена ресурсами конкретного устройства. Облачная система добавляет сетевой путь, зато может использовать мощное оборудование и распределять запросы между ресурсами. Сравнивать варианты стоит на одинаковых запросах, с сопоставимыми настройками генерации и в условиях, близких к реальной нагрузке.
| Параметр | Локальный запуск | Облачный API |
|---|---|---|
| Сетевой вклад в TTFT | Нет обращения к удалённому API; остаются задержки внутри устройства и приложения | Зависит от сети, маршрута и расстояния до сервера |
| Ожидание в очереди | Зависит от занятости устройства и конкурирующих локальных задач | Зависит от загрузки сервиса и политики обработки запросов |
| Время до первого токена | Зависит от модели, оборудования, длины контекста и настроек | Зависит от тех же вычислительных факторов, а также сети и нагрузки |
| Размер доступного контекста | Ограничен возможностями модели и доступной памятью устройства | Также ограничен моделью и условиями API |
| Параллельная обработка | Ограничена ресурсами локальной системы | Может распределяться между ресурсами сервиса, но фактические возможности зависят от API |
| Квантование | Пользователь может выбирать поддерживаемые форматы и настройки движка | Детали реализации часто определяет провайдер |
| Контроль конфигурации | Обычно больше контроля над моделью и параметрами запуска | Доступны только настройки, предусмотренные API |
Ограничения контекста есть в обоих вариантах. Локальная доступная память влияет на то, насколько удобно запускать конкретную модель и обрабатывать длинные запросы, но сама по себе не задаёт универсальный предел. В облаке предел определяется выбранной моделью и условиями API. Поэтому формулировка «облако не ограничено» неверна: лимит может быть выше или ниже, но его нужно проверять для конкретного сервиса.
Квантование позволяет уменьшить требования модели к памяти и в некоторых конфигурациях ускорить вычисления. Результат зависит от формата, модели и оборудования; снижение точности может повлиять на качество вывода. Сравнивать локальный INT4 с облачным API, настройки которого неизвестны, трудно: это неравные условия, даже если пользователь отправляет одинаковый текст.
Одинаковый средний TTFT ещё не означает одинакового опыта. Смотрите на процентили и на то, где именно возникает задержка: до первого токена, между токенами или при обработке пикового потока запросов.
Локальный запуск может оказаться удобнее при требованиях к контролю над данными, предсказуемой доступности модели или работе без постоянного обращения к облаку. Облачный API может быть практичнее, если приложению нужно обслуживать переменную нагрузку или использовать модель, для которой у команды нет подходящего оборудования. Но ни один из этих признаков не гарантирует лучшую скорость: её определяют конкретная конфигурация и условия работы.
Непрерывный батчинг: пропускная способность и цена конкуренции
При нескольких одновременных запросах серверному движку нужно распределить вычисления между ними. Непрерывный батчинг (continuous batching) позволяет добавлять новые запросы в обработку по мере освобождения ресурсов, не дожидаясь завершения всего набора. Такой подход используется в движках вывода, включая vLLM и TensorRT-LLM, и помогает эффективнее загружать ускорители.
Здесь важно различать скорость одного потока и общую пропускную способность сервера:
- Single-stream TPS показывает, сколько токенов в секунду получает один запрос в конкретных условиях.
- Aggregate TPS показывает суммарное число токенов в секунду по нескольким одновременно обслуживаемым запросам.
Высокая aggregate TPS полезна сервису, который обрабатывает много пользователей. Но сама по себе она не гарантирует высокой скорости для каждого отдельного пользователя. При росте конкуренции время до начала ответа или интервалы между токенами могут увеличиваться. Точная картина зависит от размера батча, политики планировщика, длины входов и ответов, возможностей ускорителей и настроек движка.
Батчинг не обязательно означает выбор между производительностью сервера и скоростью отдельного запроса. Он меняет распределение ресурсов, а результат нужно оценивать на реальной нагрузке. Например, короткие запросы и длинные генерации по-разному занимают вычислительные ресурсы. Если смешать их в одном тесте, среднее значение может скрыть, что одни запросы обслуживаются быстро, а другие заметно дольше.
На локальном устройстве картина тоже зависит от сценария. Один запрос может получать значительную долю ресурсов GPU, пока устройство свободно. Если одновременно работают другие задачи или модель обслуживает несколько пользователей, преимущество исчезает. Поэтому вывод, что локальная компактная модель всегда отзывчивее облачной большой, слишком широк: конкретное сравнение зависит от оборудования, нагрузки и сетевого пути.
Практический тест должен включать не только одиночный запрос, но и несколько уровней конкуренции. Отдельно фиксируют TTFT, распределение ITL или TPOT и число обработанных токенов. Так видно, растёт ли пропускная способность вместе с нагрузкой и как при этом меняется ожидание для отдельного пользователя.
Стандартизация телеметрии: OpenTelemetry и задержки генеративного софта
Когда генеративная модель встроена в приложение, задержка складывается не только из работы самой модели. Запрос проходит через клиент, API-шлюз, оркестратор, движок вывода и иногда дополнительные инструменты. Если измерять только общий ответ приложения, становится трудно понять, где возникла пауза.
OpenTelemetry предоставляет общий подход к сбору телеметрии распределённых систем. Для генеративных операций в его семантических конвенциях предусмотрены названия метрик, связанные со временем до первого токена и временем на выходной токен, например gen_ai.server.time_to_first_token и gen_ai.server.time_per_output_token. Набор конвенций и поддержка конкретных инструментов могут различаться, поэтому перед внедрением стоит свериться с используемой версией спецификации и реализацией.
Даже если команда пока не отправляет телеметрию в единый наблюдательный контур, полезно разложить запрос на отдельные интервалы: время на клиенте, ожидание до начала обработки, префилл, декодирование и передача токенов. Связанные трассы помогают увидеть последовательность этапов, а метрики по распределению — найти медленные хвосты. Без такого разделения можно ошибочно оптимизировать модель, хотя задержка возникла в сети или очереди.
Стандартизация особенно полезна при сравнении окружений. Если локальный движок и облачный API измеряются разными способами, их цифры нельзя напрямую сопоставить. Единые определения TTFT и времени генерации токена позволяют понять, действительно ли изменилась производительность при миграции или команда просто поменяла способ измерения.
Эта же дисциплина помогает применять алгоритмы машинного обучения в софте за пределами генерации текста. Инструменты предиктивной аналитики на практике дают полезные результаты лишь тогда, когда качество и скорость оцениваются на понятных данных и едиными метриками. Даже сравнение фреймворков для обработки данных мало что говорит без одинакового сценария нагрузки и чёткого понимания, какой этап измеряется. Аудит алгоритмического стека помогает отделить системные узкие места от случайных; например, подход к аудиту алгоритмов поискового продвижения иллюстрирует тот же принцип на другом уровне цифрового продукта.
Архитектура зависит от запроса, а не от ярлыка
Локальные и облачные модели решают разные задачи, но граница между ними не определяется одной цифрой в таблице. Компактная модель может быть удобна для частых коротких запросов и требований к контролю над средой. Облачный API может дать доступ к другим моделям и ресурсам для параллельной обработки. При этом облако способно показать такой же или меньший TTFT, чем локальный запуск, если вычислительная система работает быстрее, сеть достаточно стабильна, а сервис не перегружен. В иных условиях локальный вариант окажется отзывчивее.
Для команды, которая выбирает архитектуру использования машинного обучения в продукте, важны три практических ориентира:
1. Разделяйте метрики. Измеряйте TTFT, ITL или TPOT и полное время ответа отдельно. Так будет понятно, стоит ли оптимизировать сеть, обработку входа, декодирование или передачу результата.
2. Проверяйте распределение задержек. Среднее значение полезно для общей картины, но P95 и P99 показывают, что происходит с запросами в медленной части выборки и при росте нагрузки.
3. Тестируйте в условиях своего приложения. Используйте характерные для него длины запросов и ответов, учитывайте параллельные обращения и проверяйте несколько уровней нагрузки. Результат одиночного теста не предсказывает поведение сервиса в пиковый период.
Быстродействие генеративной модели не сводится к вопросу, где находится GPU. На восприятие ответа влияют путь запроса, ожидание, префилл и темп декодирования. Когда эти этапы измеряются отдельно, выбор между локальным запуском и облачным API становится инженерным решением, привязанным к конкретной нагрузке, а не спором о том, какой вариант быстрее вообще.