Развернуть модель на продакшн — не просто запустить файл с весами. Здесь важны упаковка, интерфейсы, управление версиями и производительность. В статье разберём, как подготовить PyTorch‑модель, собрать архив для сервера, написать обработчик, подать модель в TorchServe и настроить масштабирование и мониторинг.
Зачем выбирать сервер для моделей
Когда модель переходит из эксперимента в приложение, требования меняются: стабильные API, одновременные запросы, наблюдаемость и возможность обновлять версию без простоя. Специальный сервер упрощает эти задачи и снимает рутинную часть из ваших рук.
TorchServe появляется как инструмент, который уже знаком с экосистемой PyTorch. Он поддерживает кастомные обработчики, пакетирование запросов, версионирование и интеграцию с инфраструктурой, чего обычно не хватает при простом запуске модели в скрипте.
Подготовка модели: сохранить, скриптовать или оставить state_dict
Перед упаковкой решите, в каком виде сохранить модель. Два распространённых варианта — экспорт через torch.jit (scripted/traced) или сохранение state_dict. Scripted модель легче разворачивать без знания кода класса, но иногда потребуются кастомные модули, которые удобнее грузить через state_dict и писать загрузку в обработчике.
Практический совет: для простых классификаторов я обычно создаю scripted версию, чтобы не мучиться с импортами и зависимостями. Для больших проектов с кастомными слоями предпочитаю state_dict и небольшой загрузочный код в handler.
Команда для создания архива модели
Инструмент torch-model-archiver формирует .mar — архив, который потом подаётся в сервер. Он принимает сериализованный файл, обработчик и дополнительные файлы с метаданными.
> torch-model-archiver --model-name my_model --version 1.0 --serialized-file model.pt --handler handler.py --extra-files index_to_name.json --export-path model_store --force
В extra-files удобно класть словари классов, конфигурации предобработки и метаинформацию о преобразованиях входа. Архив содержит манифест и всё, что нужно для загрузки модели на другом хосте.
Кастомный обработчик: где логика предобработки и постобработки
По умолчанию TorchServe предоставляет стандартные обработчики для классов задач, но реальная жизнь требует кастомной предобработки, агрегации результатов и поддержания сторонних библиотек. Обработчик — это место, где это реализуется.
Типичная структура обработчика включает методы initialize (загрузка модели), preprocess (подготовка ввода), inference (выполнение предсказания) и postprocess (форматирование ответа). Такой разбиение делает код читабельным и тестируемым.
from ts.torch_handler.base_handler import BaseHandler
class MyHandler(BaseHandler):
def initialize(self, context):
self.model = ... # загрузка state_dict или scripted model
def preprocess(self, data):
...
def inference(self, inputs):
...
def postprocess(self, inference_output):
...
В своём опыте я видел, как одна небольшая ошибка в preprocess приводила к падению скорости на 30%. Тестируйте каждый шаг локально, прежде чем архивировать.
Запуск сервера и регистрация модели
Запуск TorchServe можно выполнить локально или в контейнере. Обычно сервер предоставляет два REST‑интерфейса: management API для загрузки/удаления моделей и inference API для предсказаний.
Быстрый рабочий сценарий: поместить .mar в папку model_store, запустить сервер и зарегистрировать модель через management API. После регистрации модель становится доступной по предикшн‑эндпоинту.
- Поместите my_model.mar в model_store/
- Запустите TorchServe
- Зарегистрируйте модель через management API или укажите её при старте
Примеры взаимодействия с API
После старта вы можете отправлять запросы на предсказание и управлять моделями через HTTP. Небольшой curl‑пример обычно работает без сюрпризов.
> curl -X POST "http://127.0.0.1:8081/models?url=my_model.mar" > curl -X POST "http://127.0.0.1:8080/predictions/my_model" -T input.jpg
Первый запрос регистрирует модель, второй отправляет изображение на предсказание. В продакшне обычно ставят перед сервером reverse proxy и включают HTTPS.
Параметры производительности и масштабирование
Производительность зависит от числа рабочих процессов, батчинга, использования GPU и задержек между пакетами. Для онлайн‑сервисов важно найти баланс между латентностью и пропускной способностью.
Batching полезен при большом потоке мелких запросов: сервер агрегирует несколько входов и пропускает их через модель одним вызовом, что часто уменьшает накладные расходы на GPU. Минус — повышение P95‑латентности, поэтому всё нужно измерять.
Краткая таблица: варианты сериализации
| Вариант | Плюсы | Минусы |
|---|---|---|
| Scripted (torch.jit) | Не требует класса модели при загрузке, быстрее старт | Нужны корректные trace/script, сложнее дебажить |
| state_dict | Гибкость, удобно с кастомными слоями | Нужен код класса в handler |
Мониторинг, логирование и метрики
Наблюдаемость — ключ к стабильности. Сервер генерирует логи ошибок, метрики latency/throughput и информацию о загрузке моделей. Эти данные нужны, чтобы распознавать деградацию производительности и реагировать вовремя.
В практических развёртываниях я подключал Prometheus для сбора метрик и Grafana для дашбордов. Это позволило быстро увидеть рост очереди при изменении числа воркеров и скорректировать масштабирование.
Развёртывание в Docker и Kubernetes
Контейнеризация упрощает переносимость. Официальный образ TorchServe служит базой: в него можно добавить model_store, дополнительные зависимости и стартовый скрипт, который автоматически регистрирует нужные модели.
В Kubernetes удобно вынести model_store в shared volume или использовать модельный репозиторий. Для масштабирования применяют стандартные инструменты: replica‑set, HPA и GPU device plugin, если нужны ускорители.
Советы из практики
Я однажды разворачивал модель в нескольких регионах и столкнулся с тем, что одинаковые настройки воркеров давали разную производительность на разных нодах. Вывод: измеряйте локально и в рамках той инфраструктуры, где будет работать модель.
Также полезно поддерживать образ с версиями зависимостей, чтобы обновление PyTorch или библиотек не ломало продакшн‑контейнеры внезапно.
Отладка и распространённые проблемы
Частая ошибка — неправильный формат входа в обработчике: разница между ожидаемым тензором и JSON приводит к 500‑ым ответам. Локальное тестирование обработчика с имитацией запроса сокращает время на поиск подобных ошибок.
Если сервер долго стартует, проверьте, не пытается ли он загрузить слишком много моделей одновременно. В таких случаях полезно добавлять модели по одной и включать lazy loading.
Лучшие практики по организации работы с моделями
Храните в репозитории не только веса, но и точную процедуру сборки архива, версии зависимостей и тесты для handler. Наличие reproducible архива облегчает воспроизведение инцидентов и перенос модели между средами.
Старайтесь держать модельную логику изолированной от инфраструктурного кода, тогда обновления сервера не потребуют изменений в предобработке или валидации входных данных.
TorchServe даёт работающий каркас для промышленного развёртывания PyTorch‑моделей, но реальная ценность достигается сочетанием правильно подготовленной модели, аккуратного handler и тщательной настройки продакшн‑метрик. Экспериментируйте с батчингом и воркерами, проверяйте сценарии отказа и автоматизируйте развёртывание — тогда вы получите предсказуемый и управляемый сервис.

