Как запустить собственный Model-as-a-Service в облаке

Вы обучили модель, проверили её на тестовых данных, и она работает. Теперь нужно, чтобы этой моделью могли пользоваться другие — через API, из приложения, из внутреннего сервиса. По сути, нужно превратить файл с весами в полноценный сервис, который отвечает по HTTP, масштабируется и не падает под нагрузкой. Это и есть Model-as-a-Service (MaaS).

Ниже — практический путь от обученного файла до работающего API в облаке. Без абстракций, с конкретными шагами и решениями, к которым приходишь на практике.

Что на самом деле значит «Model-as-a-Service»

Под MaaS понимают сервис, который принимает запрос, прогоняет его через модель и возвращает результат. Звучит просто, но за этим стоит инфраструктура: контейнеризация, балансировка, мониторинг, управление версиями моделей, обработка ошибок, логирование и безопасность.

Если совсем коротко: MaaS — это когда ваша модель доступна по сети, отвечает предсказуемо и может масштабироваться без вашего ручного вмешательства.

С чего начать: упаковка модели

Прежде чем думать об облаке, нужно упаковать модель так, чтобы её можно было запустить на любом сервере без танцев с бубном.

  1. Экспортируйте модель в стандартный формат. Для PyTorch — TorchScript или ONNX. Для TensorFlow — SavedModel. ONNX удобнее, если хотите запускать на разных фреймворках без привязки к исходному.
  2. Напишите обёртку для инференса. Это скрипт, который загружает модель, принимает входные данные, проводит предобработку, делает предсказание и возвращает результат. Не смешивайте обучение и инференс в одном коде.
  3. Запакуйте всё в контейнер. Docker — самый предсказуемый вариант. В Dockerfile пропишите зависимости, скопируйте код и файл модели, укажите точку входа. Контейнер должен запускаться одной командой и отвечать на запрос.

Пример минимального Dockerfile для Python-модели:

FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY model.onnx .
COPY serve.py .
EXPOSE 8080
CMD ["python", "serve.py"]

Здесь serve.py — это ваш серверный скрипт, который поднимает FastAPI или Flask и обрабатывает запросы. Важно: модель загружается один раз при старте контейнера, а не на каждый запрос.

Выбор облачной платформы: на что смотреть

У каждого крупного провайдера есть готовые решения для MaaS, но выбор зависит от ваших реалий: где команда работает, какие инструменты уже освоены, какие требования к задержкам и бюджету.

Параметр AWS Google Cloud Azure Собственный Kubernetes
Готовый MaaS SageMaker Endpoints Vertex AI Prediction Azure ML Managed Endpoints Нет (собирается вручную)
GPU-инференс Да, от g4dn Да, от T4 Да, от NCasT4_v3 Да, если есть кластер
Сложность настройки Средняя Средняя Высокая Высокая
Автоскейлинг Встроенный Встроенный Встроенный Настраивается вручную
Когда подходит Уже на AWS, нужен быстрый старт Уже на GCP, работаете с BigQuery и Vertex Корпоративная среда на Azure Полный контроль, мультиоблачность

Практический совет: если у вас нет выделенной DevOps-команды, начинайте с управляемого решения вашего текущего провайдера. Сэкономите недели работы по настройке инфраструктуры.

Архитектура: что должно быть помимо самой модели

Сама модель — это только ядро. Полноценный сервис состоит из нескольких слоёв:

  • API-шлюз — принимает внешние запросы, проверяет аутентификацию, маршрутизирует трафик. Можно использовать Nginx, Traefik или облачный API Gateway.
  • Сервис инференса — контейнер с моделью, который обрабатывает запросы. Их может быть несколько за балансировщиком.
  • Очередь запросов — если модель тяжёлая и запросы приходят пиками, очередь (Redis, RabbitMQ, облачная очередь) сглаживает нагрузку.
  • Мониторинг и логи — время ответа, количество ошибок, использование GPU. Без этого вы не узнаете, что сервис деградирует, пока не позвонит клиент.
  • Хранилище моделей — версионное хранилище для весов моделей (S3, GCS), чтобы можно было откатиться на предыдущую версию.

Пошаговый запуск: от контейнера до рабочего API

Вот реальная последовательность действий, которая работает на практике:

  1. Локальное тестирование контейнера. Запустите Docker-образ на своей машине, отправьте тестовый запрос через curl. Убедитесь, что ответ приходит корректно и время инференса укладывается в ваши требования.
  2. Загрузите образ в registry. Docker Hub, ECR, GCR, ACR — зависит от провайдера. Образ должен быть доступен из облачной среды.
  3. Настройте облачный сервис контейнеров. ECS на AWS, Cloud Run на GCP, Container Instances на Azure. Укажите ресурсы: память, CPU, при необходимости — GPU.
  4. Настройте автоскейлинг. Минимум по двум метрикам: количество запросов в секунду и использование ресурсов. Не ставьте максимум под потолок — оставьте запас.
  5. Подключите домен и TLS. Облачные балансировщики умеют выпускать сертификаты автоматически. Не пускайте трафик на HTTP в продакшене.
  6. Настройте CI/CD. При появлении новой версии модели — автоматическая сборка контейнера, прогон тестов, деплой. Без этого каждый релиз превращается в стресс.

GPU или CPU: когда что использовать

Не каждая модель требует GPU. На практике разделение такое:

  • CPU достаточно: табличные модели (градиентный бустинг, логистическая регрессия), модели для работы с текстом на базе эмбеддингов, лёгкие модели для классификации изображений. Инференс на CPU может занимать 50–200 мс, что приемлемо для многих задач.
  • GPU нужен: трансформеры (BERT, GPT-свёртки), детекция объектов на изображениях, генеративные модели. Здесь инференс на CPU может уйти на секунды, что неприемлемо для интерактивных сервисов.

GPU-инстансы в облаке стоят значительно дороже. Если ваша модель — это CatBoost на табличных данных, не переплачивайте за видеокарту. Но если вы разворачиваете LLM или модель компьютерного зрения — без GPU не обойтись.

Управление версиями моделей

Это то, о чём часто забывают на старте, а потом страдают. Модели обновляются, и вам нужно:

  • Хранить каждую версию в объектном хранилище с версионированием.
  • Иметь возможность развернуть любую предыдущую версию без пересборки контейнера.
  • Делать канареечные деплои — направлять часть трафика на новую версию и сравнивать качество.
  • Логировать, какая версия обслужила каждый запрос, чтобы можно было отследить деградацию.

Простой подход: при старте контейнера он загружает модель из S3/GCS по пути, указанному в переменной окружения. Меняете переменную — перезапускаете поды — новая версия на проде. Не идеально, но работает на первых этапах.

Частые ошибки при создании MaaS

Запуск инференса без очереди при пиковой нагрузке. Если модель обрабатывает запрос 2 секунды, а приходит 100 запросов в секунду — без очереди вы просто потеряете большинство запросов. Добавьте буфер с самого начала.

Отсутствие таймаутов на инференс. Зависший запрос может заблокировать весь воркер. Всегда ставьте таймаут на уровне сервера и на уровне клиента.

Загрузка модели на каждый запрос. Это самая частая ошибка новичков. Модель должна загружаться один раз при старте процесса и жить в памяти.

Игнорирование предобработки данных. Модель ожидает данные в определённом формате. Если клиент присылает «сырые» данные без нормализации — результат будет некорректным. Либо принимайте сырые данные и обрабатывайте на стороне сервиса, либо чётко пропишите контракт API.

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

Что выбрать в зависимости от вашей ситуации

У вас маленькая команда, одна модель, нет DevOps.

→ Google Cloud Run или AWS App Runner. Минимальная настройка, автоскейлинг из коробки, платите только за время выполнения. Загрузка модели из объектного хранилища при старте контейнера.

У вас LLM или тяжёлая модель компьютерного зрения, нужен GPU.

→ AWS SageMaker Endpoints или Google Vertex AI. Они поддерживают GPU-инстансы, автоскейлинг, A/B-тестирование моделей из коробки. Дороже, но меньше головной боли с инфраструктурой.

У вас Kubernetes и вы хотите всё контролировать.

→ KServe (бывший KFServing) или Seldon Core. Это фреймворки для деплоя моделей на Kubernetes, которые дают автоскейлинг, канареечные деплои, управление версиями. Требуют экспертизы, но дают максимальную гибкость.

У вас строгие требования к размещению данных (on-premise или конкретный регион).

→ Собственный кластер с KServe или развёртывание на виртуальных машинах в нужном регионе. Облачные провайдеры позволяют выбирать регионы, но если данные нельзя покидать периметр — только on-premise решение.

Как лучше сделать: практические рекомендации

  • Начните с простого. FastAPI-контейнер на Cloud Run — это 30 минут работы и рабочий API. Не стройте Kubernetes-кластер для одной модели.
  • Отдельите предобработку от инференса. Если предобработка сложная, вынесите её в отдельный сервис. Так проще масштабировать и менять каждую часть независимо.
  • Кэшируйте идемпотентные запросы. Если одни и те же данные приходят часто, кэш на уровне API-шлюза может снять значительную нагрузку с модели.
  • Логируйте вход и выход. При каждом запросе сохраняйте входные данные и ответ модели (или хотя бы сэмпл). Это ваш главный инструмент для отладки и улучшения качества.
  • Договоритесь о SLA с потребителями. Какое время ответа допустимо? Какой процент ошибок приемлем? Без этого вы будете оптимизировать то, что не важно, и упускать то, что критично.
  • Планируйте стоимость. GPU-инстанс в облаке может стоить ощутимо. Считайте экономику заранее: сколько запросов в месяц, среднее время инференса, стоимость ресурсов. Иногда дешевле оптимизировать модель (квантизация, дистилляция), чем платить за дополнительные ресурсы.

Оптимизация стоимости и производительности

Несколько приёмов, которые реально работают на практике:

  • Квантизация модели. INT8-квантизация может ускорить инференс в 2–4 раза при минимальной потере качества. Для большинства задач это лучший первый шаг оптимизации.
  • Батчинг запросов. Если модель поддерживает обработку нескольких запросов за один проход, группируйте их. GPU при этом используется значительно эффективнее.
  • Используйте ONNX Runtime или TensorRT. Эти рантаймы оптимизируют граф модели под конкретное железо и дают заметный прирост скорости без переобучения.
  • Spot-инстансы для инференса. Если ваш сервис устойчив к временным сбоям (есть ретраи), spot-виртуальные машины могут сократить стоимость в 3–5 раз.

Итог: с чего начать прямо сейчас

Если у вас есть обученная модель и вы хотите сделать из неё API:

  1. Напишите FastAPI-обёртку с загрузкой модели при старте.
  2. Упакуйте в Docker, проверьте локально.
  3. Загрузите в облачный реестр контейнеров.
  4. Запустите на Cloud Run / ECS / аналогичном сервисе.
  5. Настройте автоскейлинг и мониторинг.
  6. Подключите TLS и домен.

Это займёт день-два, а не месяц. Всё остальное — очереди, канареечные деплои, сложный мониторинг — добавляйте по мере необходимости, когда сервис реально начнёт получать нагрузку. Главное — не усложняйте раньше времени.

Dfncfg.ru