﻿# p95 нескольких реплик: агрегировать histogram, а не готовые процентили

Как рассчитывать p95 по нескольким inference-репликам: histogram buckets, совместимость границ, фильтры cohort и почему среднее p95 неверно.

Автор: Команда Retrivium
Обновлено: 2026-11-01
Канонический URL: https://retrivium.ai/ru/journal/provider-latency-histogram-aggregation/
Language: ru

У каждой реплики есть график p95, и хочется получить общий показатель простым средним. Но percentile зависит от полного распределения и числа наблюдений. Реплика с малым трафиком не должна автоматически иметь тот же вес, что узел с большим объёмом. Для inference API нужны совместимые histogram и явная группа запросов, иначе итоговое число будет выглядеть точным, не отвечая поставленному вопросу.

## Определите вопрос сводки

Сначала укажите, какое время измеряется: полный ответ, первый useful content либо другой SLI. Затем выберите модель, endpoint, режим и интервал. Смешивание коротких и длинных профилей может быть допустимо для общего сервиса, но оно отвечает на другой вопрос, чем оценка одной конкретной задачи.

[Prometheus о histograms и summaries](https://prometheus.io/docs/practices/histograms/) объясняет, почему готовые quantiles нельзя произвольно агрегировать. Среднее двух p95 не восстанавливает распределение объединённых наблюдений. Даже если результат случайно похож на ожидаемый, метод остаётся неверным и сломается при изменении долей трафика.

## Сохраните распределение

Histogram хранит наблюдения в форме, пригодной для последующего объединения при соответствующих условиях. Для classic histogram существенны bucket boundaries; для других вариантов нужно учитывать поддержку используемой версии инструментов. Не смешивайте несопоставимые серии только потому, что их имена похожи.

[Метрики vLLM](https://docs.vllm.ai/en/stable/usage/metrics/) описывают доступные наблюдения и настройку histogram buckets. Проверяйте установленную версию и фактическую выдачу endpoint. Объявленное в документации имя не подтверждает, что тот же тип и набор границ присутствуют на каждом вашем экземпляре после обновления.

## Выберите bucket resolution

Границы должны давать полезную точность в области интересующего порога. Очень широкие buckets дают грубую оценку quantile, а чрезмерная детализация увеличивает стоимость хранения. Нельзя обещать произвольную точность p95 без объяснения способа представления распределения.

Сделайте маленький synthetic набор задержек и посчитайте ожидаемые свойства независимо от dashboard. Затем пропустите его через выбранный тип histogram. Такой fixture проверяет запрос и exporter, не требуя реальной генерации. Сохраняйте исходные значения, чтобы округление не стало скрытой причиной расхождения.

## Ограничьте cohort labels

[Правила именования Prometheus](https://prometheus.io/docs/practices/naming/) помогают сохранять единицы и смысл labels. Для сводки полезны ограниченные категории, например model или outcome. Уникальный request ID не должен превращаться в label каждого наблюдения: он резко расширяет число рядов и не помогает корректной агрегации percentile.

Не объединяйте успешные завершения с обрывами без явной политики. Если duration ошибок учитывается отдельно, запрос dashboard должен это отражать. Иначе быстро отклонённая перегрузка способна улучшить общий p95, хотя пользователи получают меньше пригодных ответов.

## Проверьте запрос после релиза

Сохраните выражение, тип histogram, границы и выбранные фильтры рядом с версией instrumentation. При смене metric name или units повторите synthetic fixture. Падение p95 после изменения определения не является доказательством ускорения, даже если форма графика выглядит лучше.

Связанные темы — [мониторинг GPU](/ru/journal/gpu-monitoring-scorecard/) и [методика бенчмарка](/ru/journal/inference-benchmark-method/). Итогом является объяснимый percentile конкретной группы, а не универсальный SLA или утверждение о производительности неизвестного пула. Сопоставимость измерений важнее удобного одного числа на панели.
