Бюджет задержки ML-сервиса: сколько времени осталось на модель

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

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

API должен вернуть прогноз за 200 миллисекунд. Модель считает за 60, и по отдельному бенчмарку всё выглядит хорошо. Однако запрос ещё получает признаки, ждёт свободный слот и сериализует результат. При росте очереди ответ приходит после клиентского таймаута, хотя сам инференс не замедлился.

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

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

Проверим остаток до запуска модели

В учебном расчёте бюджет равен 200 мс, на подготовку ответа оставляем 20. Есть три трассы с уже измеренными длительностями получения признаков и очереди. Модель в этом сценарии планируется в пределах 60 мс. Перед запуском сравниваем доступный остаток с этим планом.

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

budget_ms, response_reserve_ms, planned_model_ms = 200, 20, 60
traces = [("fast", 30, 10), ("queue", 40, 110), ("features", 130, 10)]
decisions = {}
for request_id, features_ms, queue_ms in traces:
    remaining = budget_ms - features_ms - queue_ms - response_reserve_ms
    can_start = remaining >= planned_model_ms
    decisions[request_id] = can_start
    print(request_id, "available for model:", remaining, "start:", can_start)
assert decisions == {"fast": True, "queue": False, "features": False}

Первый запрос оставляет модели 140 мс и проходит правило. Второй оставляет 30, третий 40: запуск дорогого вычисления уже нарушит выбранный план. Дальше поведение зависит от продукта: можно вернуть управляемую ошибку, применить заранее проверенный простой прогноз или завершить операцию асинхронно. Fallback нужно оценивать отдельно и явно помечать в ответе и метриках.

Таймаут на клиенте не всегда останавливает серверную работу. Даже отменённая корутина может оставить вычисление в другом процессе или задачу на устройстве. Если запросы продолжают считать после потери клиента, очередь будет расти. Важно проверять поддержку отмены конкретного backend и ограничивать число одновременно выполняемых задач.

В Python асинхронное ожидание можно ограничить через asyncio.timeout. Его область должна соответствовать оставшемуся бюджету операции. Сам факт наличия timeout не заменяет ограничения параллельности: при перегрузке полезнее не принять лишнюю работу, чем принять всё и массово завершать поздно.

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

Для следующего шага пригодится размер батча и хвост задержки.

В платном курсе «ML Engineer / Data Scientist: табличные модели в продакшн» вы доведёте табличную модель до REST API и воспроизводимого инференса. Собственный сервис даст основу для измерения полного пути запроса и поиска задержек вокруг модели. Откройте программу курса.

Продолжить на практике

  • ML Engineer / Data Scientist: табличные модели в продакшн ↗

    Практический курс для тех, кто хочет получить навыки ML Engineer / Data Scientist на реальных табличных задачах. В курсе Вы не просто обучите CatBoost/LightGBM, а соберёте полноценный production-style пайплайн: подготовка данных, feature engineering (генерация признаков), корректная валидация, защита от leakage (утечек), тюнинг через Optuna, интерпретация через SHAP, batch-инференс и REST API для предсказаний.