Решения
Наблюдаемость сервинга LLM: метрики и трассировка
Задача страницы. Дать практический план по наблюдаемости LLM‑сервисов: какие SLI/SLO фиксировать, как мерить TTFT/TBT/TTLT, где смотреть TPS/QPS, как собирать GPU/KV‑кэш и стоимость за 1M токенов, как устроить трейсинг запросов (OpenTelemetry) и построить дашборды/алерты.
TL;DR
- Разбейте запрос на этапы: queue → prefill → first_token → decode(stream) → post → done. На каждом этапе собирайте время/ошибки.
- Ключевые метрики: TTFT, TBT, TTLT, QPS, TPS_decode/prefill_rate, KV‑occupancy/evictions, GPU‑util/HBM.
- Для управления SLA держите пулы short/long, жёсткие лимиты max_tokens/context и стриминг; алертите по p95 и timeouts.
- Логи — структурные события без PII. Трейсинг — сквозной trace_id от шлюза до сервера модели и инструментов.
Связанные разделы:
/solutions/monitoring-logging/ • /solutions/llm-inference/streaming/ • /solutions/llm-inference/guardrails/ • /solutions/llm-inference/vllm/ • /solutions/llm-inference/tgi/ • /solutions/llm-inference/tensorrt-llm/ • /solutions/llm-inference/sglang/ • /solutions/llm-inference/llama-cpp/ • /solutions/llm-inference/multi-model/ • /solutions/llm-inference/costs/ • /solutions/cost-planner/ • /solutions/llm-inference/quantization/
SLI/SLO: что считаем «качеством сервиса»
SLI (показатели):
- TTFT — время до первого токена.
- TBT — средняя задержка между токенами (stream decode).
- TTLT — время до последнего токена (время ответа).
- QPS — запросов/с, TPS_decode/prefill_rate — токенов/с на декоде/префилле.
- Error/Timeout rate, Queue wait (время ожидания планировщика).
- GPU: utilization, HBM usage, power, SM occupancy; KV‑кэш: occupancy, evictions.
SLO (цели, пример):
- TTFT p95 ≤ 300 мс (short‑pool), TBT p95 ≤ 50 мс/токен, TTLT p95 ≤ 2.5 с при L_out ≤ 200.
- Ошибки ≤ 0.5%, timeouts ≤ 0.2%.
- Цена за 1M токенов в short‑pool ≤ X ₽ (см. формулы ниже).
Таймлайн запроса и точки измерения
client → gateway
→ queue_in
→ prefill_start … prefill_end
→ first_token (TTFT)
→ decode_tick (много раз; мерим TBT/TPS)
→ postprocess
→ done (TTLT)
События логируйте с общим trace_id и метаданными: модель, пул, лимиты, длины (L_in/L_out), параметры генерации, GPU‑узел, версия весов.
Метрики: полный базовый набор

API/транспорт
- requests_total{route,model,pool,status} (counter)
- request_duration_seconds p50/p95/p99 (histogram)
- inflight_requests{pool} (gauge)
- SSE/WS: активные соединения, обрывы, heartbeat‑timeouts
Латентность генерации
- ttft_seconds (histogram)
- tbt_seconds_per_token (histogram)
- ttlt_seconds (histogram)
- queue_wait_seconds (histogram)
Throughput
- tokens_generated_total{phase=decode} (counter)
- prefill_tokens_total (counter)
- decode_batch_size (histogram)
- scheduler_efficiency (gauge, 0–1)
KV‑кэш
- kv_cache_bytes_used / kv_cache_evictions_total
- prefix_cache_hit_ratio (где доступно)
GPU/система
- gpu_utilization / gpu_memory_bytes / gpu_power_watts
- nvlink_tx_rx_bytes_total / pcie_tx_rx_bytes_total
- CPU токенизации, дисковый I/O (веса/логи), сеть на стриме
Модель/вызов
- Распределения L_in/L_out, temperature, top_p, stop_reasons
- Ошибки по классам: oom, timeout, over_limit, bad_json
- Экономика
tokens_total → Tokens/hour → Cost_per_1M (см. §10)
Инструментирование по стеку
- vLLM. Снимайте: prefill_rate, decode_tps, размер текущего батча, hit‑rate prefix‑кэша, paged‑KV занятость. См. /solutions/llm-inference/vllm/.
- TGI. Очереди планировщика, max_input_length, max_total_tokens, фактический батч, p95 на short/long пулах. См. /solutions/llm-inference/tgi/.
- TensorRT‑LLM. Время билда/прогрева движка, профиль ядёр, p95 при разных max seq len. См. /solutions/llm-inference/tensorrt-llm/.
- SGLang/LightLLM. decode_tps, конкуренция, context-length распределения. См. /solutions/llm-inference/sglang/.
- llama.cpp. tokens/s, -ngl, -c, CPU threads; p95 на hybrid CPU↔GPU. См. /solutions/llm-inference/llama-cpp/.
Пример метрик (Prometheus) и SSE‑хуки
Python (FastAPI + prometheus_client)
from prometheus_client import Counter, Gauge, Histogram
REQS = Counter("requests_total","",["route","model","pool","status"])
INF = Gauge("inflight_requests","",["pool"])
TTFT = Histogram("ttft_seconds","",buckets=[.05,.1,.2,.3,.5,1,2,5])
TBT = Histogram("tbt_seconds_per_token","",buckets=[.005,.01,.02,.03,.05,.1])
TTLT = Histogram("ttlt_seconds","",buckets=[.5,1,2,3,5,8,13])
TOK = Counter("tokens_generated_total","",["phase","model","pool"])
KV = Gauge("kv_cache_bytes_used","",["model","pool"])
# Пример стрим‑обработчика (события start/first_token/token/done)
async def sse_stream(gen):
import time, json
t0, first = time.time(), None
yield "event: start\ndata: {}\n\n"
async for delta in gen: # delta = {"content": "..."} от сервера модели
NOW = time.time()
if first is None:
TTFT.observe(NOW - t0); first = NOW
else:
TBT.observe(NOW - prev)
prev = NOW
TOK.labels("decode","llama3-8b","short").inc(len(delta["content"])) # грубо: 1 символ = 1 токен? замените на реальный счетчик токенайзера
yield f"data: {json.dumps({'choices':[{'delta':delta}]}, ensure_ascii=False)}\n\n"
TTLT.observe(time.time() - t0)
yield "event: done\ndata: [DONE]\n\n"
PromQL (примеры)
# p95 TTFT по short-пулу
histogram_quantile(0.95, sum(rate(ttft_seconds_bucket{pool="short"}[5m])) by (le))
# QPS
sum(rate(requests_total[1m])) by (route, pool)
# TPS decode
sum(rate(tokens_generated_total{phase="decode"}[1m])) by (model,pool)
# Загруженность KV-кэша
avg(kv_cache_bytes_used) by (model,pool) / on(model,pool) avg(gpu_memory_bytes) by (model,pool)


Трейсинг (OpenTelemetry): сквозные спаны
Дерево спанов (минимум):
Serve.Chat (span)
├─ Pre.Filter
├─ Queue.Wait
├─ Prefill
├─ FirstToken
├─ Decode (stream, многократно)
├─ Postprocess
└─ Store.Log/Audit
Добавляйте атрибуты: model, pool, L_in/L_out, kv_used, batch_size, gpu_id, node, tenant, quant (int4/int8/fp8), finish_reason.
Идентификаторы
- Пробрасывайте trace_id/span_id с gateway до сервера модели (заголовок traceparent).
- Для SSE/WS — передавайте trace_id в первом чанке и в конце (done) для корреляции.
Сэмплинг
- 100% для ошибок/тайм‑аутов, 10% — для нормальных запросов; burst sampling для всплесков.
Дашборды: роли и панели
SRE‑дашборд
- TTFT/TBT/TTLT p50/p95/p99 (short/long).
- Ошибки/тайм‑ауты, queue_wait, inflight, распред. длин.
- GPU util/HBM, KV‑occupancy/evictions, сеть/CPU/диск.
ML‑инженер
- Prefill vs Decode доли, TPS, распределение параметров (temperature/top_p), контекст/выход, stop_reasons.
- Влияние квантизации на TPS/латентность. См. /solutions/llm-inference/quantization/.
Продакт/стоимость
- Tokens/hour, цена за 1M, доля short/long, пер‑тенантные графики. См. /solutions/llm-inference/costs/, /solutions/cost-planner/.
Логи: события вместо «сырого текста»
Событие (рекомендация)
{
«ts»:»2025-08-22T12:34:56Z»,
«trace_id»:»tr_abc123″,
«tenant»:»acme»,
«model»:»llama3-8b@int8″,
«pool»:»short»,
«len_in»:512, «len_out»:180,
«ttft_ms»:180, «ttlt_ms»:1200,
«kv_bytes»: 268435456,
«finish_reason»:»stop»,
«error»: null
}
Без PII/секретов; для PII — маски и хэши. См. /solutions/llm-inference/guardrails/ и /solutions/security/.
Стоимость: как вывести из метрик
Обозначим: TPS_decode — токены/с на декоде, Num_GPU, GPU_hour_price.
Tokens_per_hour ≈ TPS_decode × 3600
Cost_per_1M ≈ (GPU_hour_price × Num_GPU) / (Tokens_per_hour / 1e6)Добавьте в экспортер счётчик tokens_generated_total и агрегируйте по модели/пулу/тенанту.
Сводные графики и планирование: /solutions/llm-inference/costs/, /solutions/cost-planner/.
Нагрузочное тестирование и ёмкость
Типы тестов: ступенчатая нагрузка, всплеск, длительное замачивание (soak), деградация.
Набор сценариев: short (L_in≤1K, L_out≤200), balanced, long (≥8K контекста).
Фиксируйте: p95 TTFT/TBT/TTLT, Timeouts/Errors, Queue wait, KV‑occupancy, GPU HBM/util, Tokens/hour.
Цель: найти «колено» — при каком QPS растут p95/тайм‑ауты; обновить лимиты и размеры пулов.
Интеграция со стримингом/агентами
- Для SSE/WS измеряйте TTFT/TBT/TTLT в самих потоках; отправляйте trace_id и finish_reason. См. /solutions/llm-inference/streaming/.
- Для агентов логируйте шаги инструментов: tool_start, tool_result, tool_error, длительность и объём контента. См. /solutions/llm-inference/agents/.
Чек‑лист перед продом
- Зафиксированы SLO (TTFT/TBT/TTLT p95, ошибки/тайм‑ауты, цена/1M).
- Включены метрики API/латентности/throughput/KV/GPU/стоимости.
- Настроен трейсинг с trace_id от шлюза до сервера модели/инструментов.
- Дашборды: SRE / ML / Стоимость; алерты по p95/тайм‑аутам/KV/GPU.
- Логи — событийные, без PII; аудит и ретеншн.
- План деградации: пулы short/long, лимиты max_tokens/context, квантизация/масштабирование.

/solutions/llm-inference/ • /solutions/llm-inference/vllm/ • /solutions/llm-inference/tgi/ • /solutions/llm-inference/tensorrt-llm/ • /solutions/llm-inference/sglang/ • /solutions/llm-inference/llama-cpp/ • /solutions/llm-inference/multi-model/ • /solutions/llm-inference/quantization/ • /solutions/llm-inference/streaming/ • /solutions/llm-inference/guardrails/ • /solutions/llm-inference/costs/ • /solutions/cost-planner/ • /solutions/monitoring-logging/