Модель живёт в проде, а не в ноутбуке

Ноутбук с точностью 97% и сервис с тем же чекпоинтом — это две разные модели. Что меняется, когда инференс переезжает в Kubernetes.

У нас был ноутбук, на котором всё работало. Точность — 97%, датасет чистый, график красивый. Через неделю после переезда в прод тот же чекпоинт выдавал 84%. Модель не деградировала — изменился мир вокруг неё.

Что реально меняется при переезде

В ноутбуке модель получает данные «как есть». В проде между ней и миром стоит инфраструктура, и у неё свои привычки:

  • Парсинг. В датасете дата была datetime, в проде — строка с тремя форматами, потому что три системы-источники пишут по-разному.
  • Пакеты. Train и serve живут в разных образах, и версии должны совпадать. pip freeze — это не документация, это улики.
  • Время. Инференс в ноутбуке — это когда запустили ноутбук. В проде — p99 в конкретную секунду, под конкретным SLA.

Минимальный контейнер инференса

FROM python:3.12-slim
COPY requirements.lock /tmp/
RUN pip install --no-cache-dir -r /tmp/requirements.lock
COPY app/ /app/
HEALTHCHECK --interval=15s CMD python -c "import urllib.request as u; u.urlopen('http://127.0.0.1:8000/healthz')"
CMD ["uvicorn", "app.serve:app", "--host", "0.0.0.0", "--port", "8000"]

/healthz при этом обязан отвечать «неживой», если модель не загружена или не прошла canary-пакет данных. Иначе Kubernetes вернёт трафик на под, который умеет только падать красиво.

Что должно быть в метриках с первого дня

  1. Доля фичей за пределами обучающего распределения.
  2. Распределение предсказаний за час — свои базовые линии, не «в среднем по кластеру».
  3. Время инференса как гистограмма, а не среднее.

Дрейф приходит не с новостями, а с тихим сдвигом гистограммы на второй неделе. Кто следит за средним — тот узнаёт последним.

СКОПИРОВАНО