Ваш дашборд показывает задержку P95 в 4.2 секунды. Сайт с бенчмарками говорит, что ваша модель выдаёт 800 токенов в секунду — «быстро» — а пользователи всё равно закрывают вкладку до того, как придёт первый токен.
Этот разрыв и есть вся история задержек LLM: число, которое все меряют по бенчмаркам, и число, которое пользователи реально ощущают, — разные числа, и большинство команд оптимизирует не то.
Задержка — самый насыщенный данными и почти лишённый рекомендаций угол LLM-стека: сайты с бенчмарками публикуют сотни таблиц с TTFT и токенами в секунду — страницы провайдеров на Artificial Analysis и живой рейтинг скорости AI API Cost как эталонные точки отсчёта — и почти ни один из них не говорит, что делать с вашим числом. Документация вендоров объясняет их собственный стек, а не ваш. А любимая метрика индустрии — токены в секунду — регулярно ошибочно принимается за то, что пользователи реально ощущают.
Этот гайд — слой рекомендаций: что задержка значит на самом деле (четыре разных числа, и только одно из них — TPS), почему теперь это продуктовый показатель, как измерять его с бюджетом, который можно защитить, как чинить каждый слой — стриминг, кэширование, распределение моделей по уровням, региональную маршрутизацию — и какие ошибки превращают оптимизацию в суеверие.
Что «задержка» на самом деле значит для LLM API
Ключевой вывод: чисел задержки четыре, и оптимизация не того из них — вот как команды выпускают «быстрые» модели, которые ощущаются медленными.
- TTFT — время до первого токена. Что пользователь ощущает первым: разрыв между «отправить» и первым стриминговым токеном. Самый важный показатель для интерактивных продуктов.
- Inter-token latency — величина, обратная TPS. Как быстро приходит в потоке остальная часть ответа. Важен для длинных выводов и агентных циклов; неважен для ответа в одну строку.
- Общее время запроса. Сумма за вычетом эффекта восприятия стриминга. То, что важно для пакетной и фоновой работы; не то, что ощущает пользователь.
- Воспринимаемая задержка. То, во что превращается стриминг: TTFT плюс темп потока. Система с хорошим TTFT и ровным темпом ощущается быстрой, даже когда общее время велико.
Фиксация индустрии на TPS — ловушка: модель на 800 токенов/сек с TTFT 1.5 секунды проигрывает по первому впечатлению модели на 300 токенов/сек с TTFT 300 мс. Измеряйте все четыре; оптимизируйте под сценарий использования.
Почему задержка — продуктовый показатель
Ключевой вывод: агенты умножают задержку, а пользователи ощущают продукт — числа переехали из таблицы бенчмарков в график оттока.
Две структурные причины, по которым задержка теперь продуктовое решение:
-
Агентные циклы умножают каждое ожидание. Один разговор — это N последовательных вызовов модели; выигрыш 500 мс на вызов превращается в выигрыш 5 секунд на цикле из 10 вызовов. Та же логика сложного процента, что стоит за правилом 800 мс для интерактивных систем, работает и здесь: последовательные вызовы перемножаются, поэтому задержка на вызов — продуктовое решение, а не приятный бонус к производительности.
-
Воспринимаемая скорость — это удержание. Исследования стриминговых интерфейсов стабильно показывают: время до первого токена определяет воспринимаемое качество; самая быстрая по бенчмаркам модель проигрывает, если её TTFT медленный. Продуктовый вопрос не «насколько быстра модель», а «насколько быстр первый токен моего пользователя».
Как измерять: бюджет задержки
Ключевой вывод: измерение — это бюджет, а не бенчмарк — раскладывайте по слоям, измеряйте P50 и P95, в своём регионе, со своими размерами промптов.
Декомпозиция бюджета:
| Слой | Что включает | Типичный диапазон |
|---|---|---|
| Network | DNS, TLS, соединение, расстояние до региона | 20-200 мс |
| Queueing | сторона провайдера, близость к rate limit | 0-500 мс+ |
| TTFT | prefill модели + первый токен | 200-1500 мс |
| Inter-token | темп генерации | 1-5 мс/токен |
| Client | парсинг, рендеринг, стриминговая обвязка | 10-100 мс |
Правила, которые делают бюджет честным:
- Измеряйте в производственных регионах. Замер из US-east для продукта, нацеленного на Сингапур, — совершенно другое число: региональная задержка может превысить задержку самой модели.
- P50 скрывает историю; её рассказывает P95. Медиана прячет таймауты; хвост — вот что запоминают пользователи.
- Те же размеры промптов, та же конкурентность. Бенчмарки на крошечных промптах льстят TTFT и ничего не наказывают. Либо ваш микс промптов, либо измерение — маркетинг.
Скрипт измерения — минимальный, но честный:
import time
from openai import OpenAI
client = OpenAI() # your production endpoint and region
PROMPT = "..." # a representative production prompt
N, STREAM = 50, True # 50 runs, streaming on
ttfts, ipss = [], []
for _ in range(N):
t0 = time.perf_counter()
first = True
stream = client.chat.completions.create(model="gpt-4o-mini",
messages=[{"role": "user", "content": PROMPT}],
stream=STREAM)
for chunk in stream:
if first:
ttfts.append((time.perf_counter() - t0) * 1000) # TTFT in ms
first = False
t_last = time.perf_counter()
else:
ipss.append((time.perf_counter() - t_last) * 1000) # inter-token ms
t_last = time.perf_counter()
def pct(xs, p):
xs = sorted(xs); return xs[int(len(xs) * p)]
print(f"TTFT P50={pct(ttfts, .5):.0f}ms P95={pct(ttfts, .95):.0f}ms")
print(f"Inter-token P50={pct(ipss, .5):.1f}ms P95={pct(ipss, .95):.1f}ms")
Запускайте его из регионов, где реально находятся ваши пользователи, со своими реальными размерами промптов и фиксируйте результаты как базовую линию, с которой ваш CI-набор будет сравнивать.
Привычка измерять должна жить в CI: набор регрессионных тестов задержки, падающий при дрейфе TTFT, — единственное, что не даёт фразе «модель стала лучше» остаться голословной; та же дисциплина, которую хорошая наблюдаемость выстраивает для остального стека.
Как оптимизировать: стриминг, кэширование, маршрутизация
Ключевой вывод: три рычага в порядке внедрения — стримите всё, кэшируйте повторяющееся, маршрутизируйте по уровню — и все три это конфигурация, а не проекты.
Слой 1 — Стриминг. Первый и самый дешёвый рычаг: стримите ответы и рендерите токены по мере поступления. Интерактивное решение — SSE или WebSocket: SSE для потоков «запрос-ответ» (проще, нативно для HTTP, работает через большинство прокси), WebSocket для двунаправленных потоков (агенты, аудио в реальном времени). Производственные детали, ломающие наивный стриминг: буферизация на прокси (посредники, которые держат ответ до полного завершения, сводят смысл на нет), обработка разрыва соединения (клиент ушёл — поток должен прерваться) и backpressure. Стриминг не делает модель быстрее — он растворяет ожидание пользователя в темпе потока.
Слой 2 — Кэширование. Два разных выигрыша: кэширование промптов (повторные префиксы пропускают prefill, сокращая TTFT на втором идентичном вызове) и кэширование ответов (идентичные запросы обслуживаются без обращения к модели). Гайд по кэшированию промптов разбирает экономику; угол задержки — тот же рычаг: стабильные префиксы делают второй вызов быстрее и дешевле. Следите за частотой промахов — кэш, промахивающийся в 90% случаев, добавляет накладные расходы без выгоды.
Слой 3 — Распределение моделей по уровням и маршрутизация. Интерактивному пути не нужна передовая (frontier) модель на каждом ходу: маршрутизируйте критичные для UX вызовы на быстрый уровень (включая провайдеров на специализированных чипах из нашего сравнения быстрого инференса), а фоновую работу — на экономичный уровень. Кастомная маршрутизация делает решение по каждому запросу механическим, а fallback не даёт редкой недоступности быстрого уровня превратиться в вашу историю о задержках.
Как исправить глобальную задержку: региональная маршрутизация
Ключевой вывод: для глобальной аудитории выбор региона важнее выбора модели — одна и та же модель в правильном регионе — это разница между 300 мс и 900 мс.
Цифры не врут: модель, отдаваемая из США европейскому пользователю, несёт 100-200 мс лишней сетевой задержки за каждый хоп по сравнению с региональным endpoint, и разница накапливается на агентных циклах. Исправление архитектурное:
- Маршрутизация в ближайший регион. Обслуживайте каждого пользователя из ближайшего региона, где доступна модель, — слой балансировки нагрузки делает это на уровне endpoint.
- Автоматический фейловер между регионами. Когда провайдер или регион деградирует, переключайтесь на следующий регион до того, как бюджет TTFT пользователя будет исчерпан, — механика описана в документации по auto-failover.
- Edge-вызовы — кратко. Для особо чувствительных к задержке путей edge-функции могут стоять перед вызовом LLM — сокращая сетевой хоп и обеспечивая переиспользование соединений. Честная оговорка: edge добавляет собственные расходы на cold start, и для большинства нагрузок побеждает региональный endpoint; тестируйте перед внедрением (это единственный edge-кейс, который мы отметим, не обещая лишнего).
Правило измерения из начала гайда здесь работает с удвоенной силой: решения о региональной маршрутизации требуют региональных измерений — американский бенчмарк глобального изменения маршрутизации измерением не является.
Частые ошибки
Ключевой вывод: четыре режима отказа — каждый превращает инициативу по задержкам в фарс.
- Оптимизация одной метрики. Фиксация на TPS при игнорируемом TTFT; фиксация на TTFT при игнорируемом стриминге. Модель из четырёх чисел в этом гайде — противоядие.
- Игнорирование сетевого слоя. Вся оптимизация на стороне модели и ноль региональной маршрутизации — для глобального продукта это оптимизация не той половины бюджета.
- Кэширование без дисциплины hit rate. Кэширование «потому что это быстро» с 90% промахов — экономика кэширования работает, только когда префикс стабилен, а hit rate измеряется.
- Нет базовой линии до оптимизации. Поменяли стек, задеплоили, никогда не измерили «до». Без CI-набора по задержке «оптимизация» — это надежда с дашбордом.
FAQ
Какую метрику задержки оптимизировать в первую очередь?
TTFT для интерактивных продуктов — его пользователь ощущает первым. TPS для агентных циклов и длинных выводов. Оптимизируйте метрику, которую ощущает ваш сценарий, а остальные измеряйте, чтобы они не деградировали незаметно.
Стриминг быстрее или просто кажется быстрее?
И то и другое, в разных смыслах: общее время обычно не меняется, но воспринимаемая задержка резко сокращается, потому что первый токен приходит рано, а поток задаёт темп остальному. Для интерактивных продуктов воспринимаемая задержка и есть продуктовая метрика — стримите всё.
Насколько выбор региона влияет на задержку?
Часто сильнее выбора модели: межконтинентальные сетевые хопы добавляют сотни миллисекунд на вызов и накапливаются на агентных циклах. Маршрутизация в ближайший регион — самое результативное изменение задержки, которое большинство глобальных продуктов так и не делают.
SSE или WebSocket для стриминга?
SSE для потоков «запрос-ответ» — проще, нативно для HTTP, дружелюбен к прокси. WebSocket для двунаправленных потоков вроде агентов реального времени. Выбор по форме потока, а не по хайпу, — вот и весь ответ.
Кэширование правда снижает задержку?
Кэширование промптов сокращает TTFT на повторных префиксах (prefill — самая дорогая часть), а кэширование ответов полностью устраняет задержку модели для идентичных запросов — но только когда hit rates реальны. Измеряйте hit rate; частота промахов — это налог.
Почему мой P95 сильно хуже P50?
Хвостовая задержка в LLM API идёт от очередей провайдера под нагрузкой, близости к rate limit и региональной сетевой вариативности. Если хвост важен (а он важен), решение — комбинация запаса мощности, fallback и региональной маршрутизации, а не более быстрая модель.
Итоги
Оптимизация задержек LLM API — задача о четырёх числах: измеряйте TTFT, inter-token, общую и воспринимаемую задержку на P50 и P95 в своих производственных регионах; затем чините каждый слой — стриминг для восприятия, кэширование для повторов, распределение моделей по уровням для баланса «цена-скорость» и региональную маршрутизацию для сетевой половины бюджета. Таблицы бенчмарков говорят, что возможно; ваш бюджет говорит, что ваше. Сначала измеряйте, потом оптимизируйте — и самая быстрая модель в мире станет той, которую реально ощущают ваши пользователи.
Нельзя исправить бюджет задержки, который вы никогда не измеряли. Получите ключ TokSpan API — $5 бесплатных кредитов для измерений — и прогоните те же промпты из нескольких регионов.