inference_service
FastAPI-инференс ML-модуля: POST /predict, /predict/batch, /whatif/predict; GET /health, /metrics/model, /model/info; POST /reload.
Модель — ансамбль CatBoost из ml/artifacts/catboost_seed*.cbm (train_catboost.py --fit) плюс модели
неопределённости: catboost_quantiles.cbm (интервал 10–90%, конформно откалиброван на 80% покрытия) и
catboost_classes.cbm (вероятности early / ontime / late). Если моделей неопределённости нет — сервис
работает на одном ансамбле, риск считается сигмоидой от задержки (как в контракте §7.1).
Онлайн-фичи строятся тем же кодом, что и в батче (features/tabular.build_features через
point_features; быстрый путь без DataFrame, см. _features) — онлайн-прогноз совпадает с submission.csv.
Клиент шлёт сырой контекст: буфер телеметрии (пакеты с event_time <= T; более поздние сервис
отбрасывает сам) и слайс планового расписания ТС. Если schedule не передан, берётся план ТС из
SCHEDULE_PATH (если файл есть).
Запуск:
uvicorn inference_service:app --app-dir ml/src --host 0.0.0.0 --port 8001 # Swagger: /docs
Classes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Всё, что сервис держит в памяти. |
|
|
|
|
|
|
|
- class inference_service.BatchRequest(*args: Any, **kwargs: Any)[исходный код]
Базовые классы:
BaseModel- requests: list[PredictRequest]
- class inference_service.BatchResponse(*args: Any, **kwargs: Any)[исходный код]
Базовые классы:
BaseModel- responses: list[PredictResponse]
- class inference_service.Cause(*args: Any, **kwargs: Any)[исходный код]
Базовые классы:
BaseModel- code: str
- contribution_sec: float
- text: str
- class inference_service.HealthResponse(*args: Any, **kwargs: Any)[исходный код]
Базовые классы:
BaseModel- model_version: str
- n_features: int
- n_models: int
- status: str
- uncertainty_models: bool = False
- vehicles_in_schedule: int = 0
- class inference_service.MetricsResponse(*args: Any, **kwargs: Any)[исходный код]
Базовые классы:
BaseModel- latency_ms_p50: float | None = None
- latency_ms_p95: float | None = None
- mae_baseline_test_s: float | None = None
- mae_baseline_train_s: float | None = None
- mae_test_s: float | None = None
- mae_train_s: float | None = None
- model_version: str
- n_features: int
- n_models: int
- requests_served: int = 0
- score_estimate: float | None = None
- class inference_service.PredictRequest(*args: Any, **kwargs: Any)[исходный код]
Базовые классы:
BaseModel- T: str = Ellipsis
- cur_dev_s: float = Ellipsis
- sample_id: str
- target_stop_id: int
- target_time_begin: str = Ellipsis
- tr_id: int
- class inference_service.PredictResponse(*args: Any, **kwargs: Any)[исходный код]
Базовые классы:
BaseModel- confidence: float
- data_status: str = 'live'
- delay_pred_sec: float = Ellipsis
- horizon_ok: bool | None = None
- latency_ms: float = 0.0
- lead_min: float | None = None
- model_version: str
- off_route_m: float | None = None
- p_early: float | None = None
- p_late: float | None = None
- p_ontime: float | None = None
- reason_pattern: str
- recommendation: str = Ellipsis
- recommendation_text: str = ''
- risk_level: str = 'green'
- risk_score: float = Ellipsis
- sample_id: str
- top_features: list[TopFeature]
- class inference_service.ScheduleStop(*args: Any, **kwargs: Any)[исходный код]
Базовые классы:
BaseModel- building_address: str | None = None
- geom: str
- manual_fill: bool | str = 'false'
- time_begin: str
- tr_id: int
- tt_action_item_id: int
- class inference_service.State[исходный код]
Базовые классы:
objectВсё, что сервис держит в памяти.
loadможно вызывать повторно (POST /reload).- __init__() None[исходный код]
- clf: catboost.CatBoostClassifier | None
- latencies: deque
- load() None[исходный код]
- meta: dict
- metrics: dict
- models: list[catboost.CatBoostRegressor]
- plan_by_tr: dict[int, list[dict]]
- q: catboost.CatBoostRegressor | None
- stops_by_tr: dict
- unc: dict
- property version: str
- class inference_service.TelemetryPing(*args: Any, **kwargs: Any)[исходный код]
Базовые классы:
BaseModel- event_time: str
- is_hist_data: int | bool = 0
- lat: float | None = None
- location_valid: bool | str = 'true'
- lon: float | None = None
- speed: float | None = None
- tr_id: int
- class inference_service.TopFeature(*args: Any, **kwargs: Any)[исходный код]
Базовые классы:
BaseModel- contribution: float = 0.0
- contribution_sec: float = 0.0
- name: str
- value: float | None = None
- class inference_service.WhatIfRequest(*args: Any, **kwargs: Any)[исходный код]
Базовые классы:
PredictRequest- scenario: str = Ellipsis
- class inference_service.WhatIfResponse(*args: Any, **kwargs: Any)[исходный код]
Базовые классы:
BaseModel- delay_baseline_sec: float
- delay_scenario_sec: float
- delta_sec: float
- model_version: str
- recommendation_still_applies: bool
- risk_baseline: float
- risk_scenario: float
- sample_id: str
- scenario: str
- inference_service.health() HealthResponse
- inference_service.metrics_model() MetricsResponse
Витринные метрики: MAE по схемам валидации, live-latency, покрытие интервала.
- inference_service.model_info() dict
- inference_service.predict(req: PredictRequest) PredictResponse
- inference_service.predict_batch(batch: BatchRequest) BatchResponse
- inference_service.reload() HealthResponse
Подхватить переобученные модели из ML_ARTIFACTS без перезапуска контейнера.
- inference_service.whatif_predict(req: WhatIfRequest) WhatIfResponse
«Что если применить сценарий»: эвристический сдвиг задержки, риск пересчитывается по интервалу модели.