← Назад к вопросам
Как развернуть ML модель в production?
2.4 Senior🔥 251 комментариев
#MLOps и инфраструктура#Python
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Развёртывание ML модели в production
Развёртывание (deployment) модели в production — это процесс переноса обученной модели из экспериментальной среды на боевой сервер, где она будет обслуживать реальные запросы. Это намного сложнее, чем просто сохранить модель в файл. Нужно обеспечить масштабируемость, надёжность, мониторинг и актуальность модели.
Основные этапы
1. Сохранение модели
Первый шаг — правильно сохранить обученную модель:
import pickle
import joblib
import json
from sklearn.ensemble import RandomForestClassifier
# Обучить модель
model = RandomForestClassifier(n_estimators=100)
model.fit(X_train, y_train)
# Вариант 1: pickle (простой, но может быть несовместим между версиями)
with open('model.pkl', 'wb') as f:
pickle.dump(model, f)
# Вариант 2: joblib (рекомендуется для sklearn моделей)
joblib.dump(model, 'model.joblib')
# Сохранить также параметры масштабирования
scaler_params = {
'mean': X_train.mean().tolist(),
'std': X_train.std().tolist()
}
with open('scaler_params.json', 'w') as f:
json.dump(scaler_params, f)
2. Создание REST API
Обычно модель оборачивают в API, чтобы её можно было вызывать по HTTP:
from fastapi import FastAPI
from pydantic import BaseModel
import joblib
import numpy as np
app = FastAPI()
model = joblib.load('model.joblib')
class PredictionRequest(BaseModel):
features: list[float]
class PredictionResponse(BaseModel):
prediction: float
probability: float
@app.post('/predict')
async def predict(request: PredictionRequest):
X = np.array([request.features])
prediction = model.predict(X)[0]
probability = model.predict_proba(X)[0].max()
return PredictionResponse(
prediction=float(prediction),
probability=float(probability)
)
@app.get('/health')
async def health():
return {"status": "ok"}
3. Контейнеризация (Docker)
Оберните приложение в Docker контейнер для переносимости и изоляции:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY model.joblib .
COPY app.py .
EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
docker build -t my-ml-model:1.0 .
docker run -p 8000:8000 my-ml-model:1.0
4. Развёртывание на сервере
Вариант A: Облачные сервисы
AWS Lambda + API Gateway:
import json
import joblib
model = joblib.load('/tmp/model.joblib')
def lambda_handler(event, context):
body = json.loads(event['body'])
features = body['features']
prediction = model.predict([features])[0]
return {
'statusCode': 200,
'body': json.dumps({'prediction': float(prediction)})
}
Google Cloud Run (Docker контейнер):
gcloud run deploy my-ml-model --source . --platform managed --region us-central1
Вариант B: Собственный сервер (VPS)
# SSH на сервер
ssh user@example.com
# Установить Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Запустить контейнер с nginx в качестве reverse proxy
docker run -d -p 80:8000 --name ml-api my-ml-model:1.0
# Настроить SSL (Let's Encrypt)
certbot certonly --standalone -d example.com
5. Мониторинг и логирование
Важно отслеживать работу модели в production:
from fastapi import FastAPI
import logging
from datetime import datetime
import json
app = FastAPI()
logger = logging.getLogger(__name__)
# Логирование запросов и предсказаний
@app.post('/predict')
async def predict(request: PredictionRequest):
start_time = datetime.now()
try:
X = np.array([request.features])
prediction = model.predict(X)[0]
# Логировать успешное предсказание
logger.info(json.dumps({
'timestamp': start_time.isoformat(),
'features': request.features,
'prediction': float(prediction),
'latency_ms': (datetime.now() - start_time).total_seconds() * 1000
}))
return {'prediction': float(prediction)}
except Exception as e:
logger.error(f'Prediction error: {str(e)}')
raise
6. Версионирование и Canary развёртывание
Обновление модели должно быть безопасным:
# Использовать версии моделей
models = {
'v1.0': joblib.load('model_v1.0.joblib'),
'v1.1': joblib.load('model_v1.1.joblib'),
}
config = {'active_model': 'v1.0', 'v1.1_traffic': 0.1} # 10% трафика на новую версию
def get_model():
import random
if random.random() < config['v1.1_traffic']:
return models['v1.1']
return models[config['active_model']]
Архитектура production ML системы
┌─────────────────┐
│ Клиент │
└────────┬─────────┘
│ HTTP запрос
▼
┌─────────────────┐
│ Load Balancer │ (распределение нагрузки)
└────────┬─────────┘
│
┌────┴────┐
▼ ▼
┌────────┐ ┌────────┐
│ API v1 │ │ API v2 │ (несколько инстансов)
└────┬───┘ └───┬────┘
│ │
├─────────┤
▼
┌──────────────────────┐
│ Model Server │
│ (FastAPI, Flask) │
└────┬─────────────────┘
│
▼
┌──────────────────────┐
│ Модель (pickle) │
│ Кэш (Redis) │
└──────────────────────┘
Чеклист production развёртывания
# 1. Валидация входных данных
@app.post('/predict')
async def predict(request: PredictionRequest):
if len(request.features) != 10:
raise ValueError('Expected 10 features')
if any(x < 0 for x in request.features):
raise ValueError('All features must be non-negative')
return model.predict([request.features])[0]
# 2. Обработка ошибок
try:
prediction = model.predict(X)
except Exception as e:
logger.error(f'Prediction failed: {e}')
return {'error': 'Service temporarily unavailable'}, 503
# 3. Кэширование результатов
from functools import lru_cache
@lru_cache(maxsize=1000)
def cached_predict(features_tuple):
return model.predict([list(features_tuple)])[0]
# 4. Мониторинг метрик
from prometheus_client import Counter, Histogram
predictions_total = Counter('predictions_total', 'Total predictions')
prediction_latency = Histogram('prediction_latency_seconds', 'Prediction latency')
Инструменты и платформы
- Docker: контейнеризация
- Kubernetes: оркестрация контейнеров в масштабе
- MLflow: версионирование моделей и экспериментов
- BentoML: специализированный фреймворк для ML сервисов
- FastAPI/Flask: REST API
- Prometheus + Grafana: мониторинг и визуализация
- AWS SageMaker / Google Cloud AI: облачные решения
Выводы
- Production deployment требует намного больше, чем просто обученная модель
- Обязательны контейнеризация, API, логирование, мониторинг и версионирование
- Используй canary развёртывание для безопасного обновления моделей
- Постоянно отслеживай производительность и дрейф данных