Как измерить задержку LLM: разложите время ответа на этапы

Разбираем, как измерить задержку LLM отдельно для установления соединения, ожидания первого токена и генерации ответа — и сравнить модели на своих запросах.

Схема измерения задержки LLM: от отправки запроса до первого и последнего токена
Схема измерения задержки LLM: от отправки запроса до первого и последнего токена
The token — a Christmas and New Year's present (1830) (14776624204).jpg | by Internet Archive Book Images | wikimedia_commons | No restrictions

Как измерить задержку LLM в своём приложении

Пользователь нажимает «Отправить», но ответ появляется не сразу. Чтобы понять, виновата ли модель, сеть или ваш код, недостаточно замерить общее время HTTP-запроса. Измерьте задержку LLM по этапам: от отправки запроса до первого токена, затем — время генерации оставшейся части ответа.

Такой тест помогает сравнивать конфигурации на собственных промптах и выбирать, что оптимизировать: потоковую выдачу, размер ответа, модель или сетевой путь. Он не заменяет независимый бенчмарк: результаты зависят от провайдера, региона, нагрузки и параметров запроса.

Какие интервалы времени измерять

У потокового ответа есть несколько полезных метрик:

  • TTFT (time to first token) — время от начала запроса до первого полученного фрагмента текста. Для пользователя это приблизительная оценка, когда интерфейс сможет начать показывать ответ.
  • Время ответа целиком — промежуток от отправки запроса до получения последнего события потока.
  • Скорость генерации — число выходных токенов, делённое на время между первым и последним токеном. Единицы измерения — токены в секунду.
  • Время до завершения запроса — интервал, включающий обработку ответа приложением и закрытие соединения.

Не смешивайте TTFT с задержкой отображения. Если приложение буферизует события, обновляет интерфейс редко или ждёт завершения разбора JSON, первый токен может прийти быстро, но появиться на экране позже.

Как измерить задержку LLM через поток событий

Сначала выберите один неизменный сценарий: одинаковые инструкции, пользовательский запрос, модель, параметры генерации и лимит ответа. Включите потоковую выдачу, если она доступна. OpenAI описывает потоковые ответы через события, а Anthropic — через события Messages API; конкретные названия и структура событий зависят от API.

Пример ниже для Python использует OpenAI Responses API и `time.perf_counter()`, подходящий для измерения коротких интервалов. Секрет хранится в переменной окружения, а не в исходном коде:

python
import os
import time
from openai import OpenAI

client = OpenAI(api_key=os.environ[«OPENAI_API_KEY»])

started = time.perf_counter()
first_text_at = None
finished = None
text_parts = []

stream = client.responses.create(
model=os.environ[«MODEL»],
input=»В двух абзацах объясни, зачем измерять TTFT.»,
stream=True,
max_output_tokens=180,
)

for event in stream:
now = time.perf_counter()

if event.type == «response.output_text.delta»:
if first_text_at is None:
first_text_at = now
text_parts.append(event.delta)

elif event.type == «response.completed»:
finished = now

ended = finished or time.perf_counter()
answer = «».join(text_parts)

print({
«ttft_seconds»: (
round(first_text_at — started, 3)
if first_text_at is not None else None
),
«total_seconds»: round(ended — started, 3),
«characters»: len(answer),
})

Установите актуальный официальный SDK и проверьте его документацию: интерфейсы библиотек меняются. Для чистого HTTP-клиента используйте события, описанные провайдером, а не предполагайте, что все API посылают одинаковый формат.

Этот пример фиксирует получение первого текстового фрагмента, а не обязательно первого байта сети или внутреннего токена модели. Если провайдер сначала отправляет служебные события, отдельно записывайте время первого события и время первого текста.

Как посчитать скорость генерации и не перепутать её с TTFT

Скорость генерации можно оценить так:

text
скорость, токенов/с =
число выходных токенов / (время завершения − время первого текста)

Для точного числа токенов используйте счётчик, соответствующий конкретной модели и токенизатору. Если API возвращает usage в финальном событии, сохраняйте его; иначе локальная оценка может отличаться от серверной. Не делите токены на полное время запроса: тогда ожидание до первого токена искусственно занизит скорость самой генерации.

При очень коротком ответе знаменатель мал, поэтому единичная задержка события заметно меняет результат. Для сопоставимых измерений используйте достаточно длинный, но одинаково ограниченный ответ и сообщайте отдельно TTFT, полное время и скорость выдачи.

Как провести воспроизводимое сравнение моделей

Один запрос — не бенчмарк. Зафиксируйте набор из нескольких реальных задач, например извлечение полей, краткий ответ и генерацию кода. Для каждого варианта сохраняйте:

точное имя модели и, если доступно, версию;

текст запроса и параметры генерации;
3. регион, SDK, сетевое окружение и время теста;
4. TTFT, длительность потока, число выходных токенов и ошибки;
5. сведения об очередях или повторных попытках, если клиент их выполняет.

Сделайте несколько повторов каждого запроса. Не запускайте все варианты строго по очереди в течение одного короткого промежутка: нагрузка у сервиса может измениться. Перемешайте порядок конфигураций и повторите тест в разные периоды. Для сводки показывайте медиану и диапазон или перцентили, а не только лучший результат.

Важно сохранять одинаковый объём входа и сопоставимый объём выхода. Модель, которой разрешено ответить вдвое короче, может выглядеть быстрее, хотя решает задачу иначе. Если тестируете именно производительность, проверяйте также качество результата: скорость некорректного ответа не является выигрышем.

Как отделить задержку модели от сети и приложения

Замер вокруг вызова SDK включает не только генерацию: туда могут попасть DNS, установка соединения, TLS, передача запроса, прокси и обработка событий клиентом. Поэтому сравнение через разные регионы или разные библиотеки не позволяет приписать разницу одной модели.

Добавьте в лог отдельные отметки времени: начало запроса, получение первого сетевого события, получение первого текстового фрагмента и завершение потока. Если перед приложением стоит ваш сервер, измеряйте время на обеих сторонах. Стандарт `Server-Timing` позволяет передавать диагностические временные метрики в HTTP-заголовках, но сам по себе не раскрывает внутреннее время вычислений провайдера.

Для проверки клиентского вклада выполните контрольный тест из одной и той же машины и сети, не меняя SDK и способ чтения потока. Повторите его без дополнительного прокси, если это допускает ваша инфраструктура. Не публикуйте API-ключи и не сохраняйте пользовательские данные в диагностических логах без необходимости.

Почему первый токен иногда приходит заметно позже

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

Потоковая передача делает задержку заметнее, но не обязательно сокращает вычисления: интерфейс получает части ответа по мере их готовности. Если приложение ждёт полный объект, буферизует события или преобразует весь результат перед отображением, преимущества потока теряются.

Проверьте, не выполняет ли клиент автоматические повторы после тайм-аута. Повтор может увеличить измеренную длительность и создать видимость нестабильной генерации. Для каждого запроса записывайте число попыток и отличайте ошибку соединения от успешно завершённого ответа.

Как превратить замеры в решение

Если TTFT высок, а поток после первого фрагмента идёт быстро, исследуйте входной объём, регион и время установления соединения. Если первый фрагмент приходит быстро, но весь ответ формируется долго, посмотрите на длину результата и скорость генерации. Если серверные отметки выглядят приемлемо, а интерфейс медленный, измерьте буферизацию и отрисовку на клиенте.

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

Следующий практический шаг — добавить TTFT, время завершения, число выходных токенов и число попыток в тестовый лог, затем прогнать один и тот же набор запросов несколько раз. Такой журнал покажет, где именно возникает задержка, не выдавая клиентское измерение за опубликованный провайдером бенчмарк.

Источники