newsmode
search
Меню
arrow_back Назад

TorchServe – Hamel’s Blog - Hamel Husain

auto_awesomeКраткое саммари

Хэмел Хусейн делится впечатлениями от экспериментов с TorchServe — инструментом для развёртывания моделей PyTorch. Среди плюсов: автоматическая батчёвка запросов, версионирование моделей, встроенное логирование и метрики. Однако отладка затруднена из-за гибрида Java и Python, а кривая обучения круче, чем у TF Serving, поскольку приходится разбираться в исходниках класса BaseHandler. Автор рекомендует использовать кастомные обработчики вместо «магических» дефолтных и отмечает скрытые ограничения вроде обязательного расширения .pt для torchscript. Пре- и постобработка в TorchServe проще, чем в TFServing, где приходится менять сигнатуру модели через DSL. При этом TF Serving выигрывает в управлении версиями за счёт алиасов вроде «staging» и «production», которых в TorchServe без обратного прокси не реализовать.

Эксперименты с Torch Serve

Зачем использовать Torch Serve

Автоматическая батчёвка запросов (опционально). Версионирование моделей. Логирование и метрики «из коробки».

Впечатления

Torch Serve — это сущее мучение для отладки, поскольку он частично написан на Java, а частично на Python (например, нельзя использовать интерактивный отладчик). Если вам не нужна автоматическая батчёвка, я бы предпочёл FastAPI и масштабирование через Kubernetes. Во многих практических сценариях (например, при использовании HF-моделей) приходится создавать кастомные обработчики, и в итоге вы пишете кучу кода, чтобы всё это склеить воедино. По сравнению с TF Serving начать сложнее, но настраивать что-то под себя гораздо проще, как только вы освоите API. Начальная кривая обучения TorchServe значительно круче, чем у TF Serving, потому что для понимания принципов работы нужно изучить класс BaseHandler (читать исходный код). Непонятно, как именно различные артефакты, которые вы сохраняете с помощью torch-model-archiver, работают вместе, пока вы не изучите BaseHandler. Например: в справке по torch-model-archiver сказано, что --model-file обязателен для моделей в eager-режиме, что не совсем правда, поскольку можно загрузить модель прямо в обработчике вместо реализации интерфейса, который TorchServe умеет загружать (например, класса с методом load_state_dict, как в этом примере). Более того, этот файл модели может содержать только одно определение класса, унаследованного от torch.nn.modules — странное ограничение. Когда ищешь информацию об использовании torch-serve в интернете, многие игнорируют предписанный интерфейс и вместо этого загружают модели внутри кастомного обработчика. Вот пример такого подхода с fastai и HuggingFace. Я считаю, что использовать кастомный обработчик — лучшая идея, потому что это прозрачнее и понятнее. Дефолтные обработчики из вводных гайдов слишком «магические», и, на мой взгляд, они сбивают новичков с толку. Я бы сказал, что дефолтные обработчики стоит использовать только после того, как вы разберётесь с BaseHandler и напишете несколько кастомных обработчиков. Если хотите использовать torchscript, расширение файла должно быть .pt (не .pth). Это нигде не задокументировано и является примером того, что можно узнать только из исходного кода BaseHandler (это конкретное расширение файла зашито в коде!). Пре- и постобработка в TorchServe значительно проще для понимания по сравнению с TFServe. Кастомные обработчики позволяют делать что угодно на чистом Python, тогда как в TFServing приходится модифицировать сигнатуру модели, что подразумевает встраивание пре-/постобработки в граф модели и другие запутанные шаги с использованием DSL. Это неудивительно — именно за это люди и любят PyTorch в целом. Мне нравится, что управлять моделями можно через REST API-запросы — см. manage models. В TF Serving же приходится править конфиги (которые он периодически проверяет на обновления). Версионирование моделей в TF Serving мне нравится чуть больше, поскольку оно позволяет давать алиасы эндпоинтам — например, «staging» или «production». Похоже, в TorchServe нельзя сделать алиасы для эндпоинтов моделей без обратного прокси.