Сервинг моделей
| Режимы | онлайн (REST/gRPC), пакетный (batch), потоковый, на устройстве |
|---|---|
| Ключевые метрики | задержка p50/p99, пропускная способность, стоимость запроса |
| Универсальные серверы | Triton, KServe, BentoML, Ray Serve, TorchServe |
| Серверы LLM | vLLM, TGI, SGLang, llama.cpp |
| Форматы | ONNX, TorchScript, SavedModel, GGUF |
Сервинг моделей (англ. model serving), или инференс, — этап MLOps, на котором обученная модель машинного обучения разворачивается так, чтобы другие системы могли получать от неё предсказания. Обучение происходит редко и может длиться часами, а сервинг работает постоянно и должен отвечать быстро, надёжно и дёшево. Именно здесь модель начинает приносить пользу — и здесь же возникает большая часть инженерных проблем ML-систем.[5]
Режимы
| Режим | Как | Когда |
|---|---|---|
| Онлайн | синхронный запрос по REST или gRPC, ответ за миллисекунды | скоринг заявки, рекомендации, чат-бот |
| Пакетный | периодический прогон по таблице, результат в БД | ночной прогноз спроса, рассылки |
| Потоковый | обработка событий из очереди (Kafka) | антифрод, мониторинг |
| На устройстве | модель внутри приложения или браузера | офлайн-работа, приватность, без затрат на сервер |
Пакетный режим проще и дешевле; онлайн нужен, когда признаки появляются в момент запроса. Многие системы сочетают оба: тяжёлые признаки предвычисляются пакетно и кладутся в Feature store, а лёгкая модель отвечает онлайн.
Простейший вариант
Модель загружается в веб-приложение один раз при старте:
# app.py — минимальный онлайн-сервинг
import joblib
from fastapi import FastAPI
from pydantic import BaseModel
model = joblib.load("model.joblib")
app = FastAPI()
class Features(BaseModel):
age: int
income: float
city: str
@app.post("/predict")
def predict(f: Features):
proba = model.predict_proba([[f.age, f.income, f.city]])[0, 1]
return {"churn_probability": float(proba)}
Такой сервис на FastAPI упаковывают в Docker-образ и запускают в Kubernetes за балансировщиком. Для небольших моделей этого достаточно.
Специализированные серверы
При росте нагрузки и числа моделей используют готовые серверы:[1][2][3]
- NVIDIA Triton — много фреймворков и ONNX, динамический батчинг, несколько моделей на одном GPU, ансамбли.
- KServe — стандартный протокол инференса поверх Kubernetes, автомасштабирование до нуля, канареечные выкаты.
- BentoML, Ray Serve — упаковка Python-кода с моделями, композиция моделей в графы.[6]
- MLflow —
mlflow models serveдля быстрого старта из реестра моделей.
Для языковых моделей — отдельный класс серверов с непрерывным батчингом и управлением KV-кэшем: vLLM, TGI, SGLang; для локального запуска — llama.cpp и Ollama.
Производительность
- Задержка (latency) — важны хвосты распределения, p95 и p99, а не среднее.
- Пропускная способность (throughput) — запросы или токены в секунду.
- Батчинг — объединение запросов повышает загрузку GPU ценой небольшой задержки.
- Оптимизация модели — квантизация, дистилляция, компиляция (TensorRT, ONNX Runtime,
torch.compile). - Холодный старт — загрузка большой модели занимает минуты, что мешает масштабированию до нуля.
Выкат и безопасность изменений
Новые версии модели выкатывают постепенно:[4]
- Теневой режим (shadow) — новая модель получает копию трафика, её ответы только журналируются.
- Канареечный выкат — небольшая доля трафика, затем увеличение.
- A/B-тест — сравнение по бизнес-метрикам.
- Быстрый откат — переключение на предыдущую версию одной командой.
Мониторинг
Помимо обычных метрик сервиса (ошибки, задержка, ресурсы — см. Мониторинг и алертинг) нужно следить за качеством: распределение входных признаков и предсказаний меняется со временем — это Дрейф данных. Частая ошибка — расхождение обучения и сервинга (training-serving skew): признаки в продакшене вычисляются иначе, чем при обучении, и модель тихо деградирует.[5]
Стоимость
Для нейросетей основная статья расходов — GPU, которые простаивают ночью и перегружены днём. Снижают затраты автомасштабирование по длине очереди запросов, размещение нескольких небольших моделей на одной карте, перенос нетребовательных моделей на CPU и кэширование повторяющихся ответов. Для языковых моделей стоимость считают в токенах: выгоднее всего короткие промпты, переиспользование префикса (Кэширование промптов) и выбор самой маленькой модели, которая справляется с задачей. Иногда дешевле не держать собственный сервер, а обращаться к внешнему API, — решение зависит от объёма трафика, требований к приватности данных и задержке.