Научитесь использовать Tensorflow Serving для создания веб-сервиса для обслуживания вашей модели Tensorflow.
Это вторая часть серии блогов, посвященных обучению модели Tensorflow, обслуживанию Tensorflow и его производительности. «В предыдущем посте мы использовали объектно-ориентированный подход для обучения модели классификатора изображений и экспортировали ее как SavedModel. Я рекомендую просмотреть его перед этим постом, так как мы собираемся использовать одну и ту же модель. Вы можете найти полные коды приложений для серии блогов здесь:
Что такое обслуживание Tensorflow?
Существует множество альтернативных способов использования моделей Tensorflow в приложениях. Одним из самых простых является использование Tensorflow вместе с фреймворками Flask, Django, Fastapi и т. д. для создания веб-приложения на основе Python. Фреймворки вроде ML.NET или deeplearning4j можно использовать, если требуется разработка на других языках. Tensorflow Lite, Pytorch Live и CoreML — это платформы для мобильных приложений. Однако в многоуровневых архитектурах и микросервисах рекомендуется делать модели машинного обучения автономными приложениями. Эта концепция называется обслуживание модели, и обслуживание модели как услуги имеет много преимуществ. Например, модели можно обновлять в производстве без простоев или использовать множество различных клиентских приложений. Для обслуживания моделей можно использовать такие приложения, как Tensorflow Serving, TorchServe, Triton, KFServing.
Tensorflow Serving позволяет нам обслуживать модели Tensorflow в качестве веб-сервисов без необходимости в дополнительном приложении. Он поддерживает обслуживание нескольких версий нескольких моделей через протоколы gRPC и REST. Однако для этого требуется, чтобы модели были в формате SavedModel Tensorflow. Сохраненные модели открыты для тонкой настройки и некоторых модификаций после обучения, особенно если они созданы с использованием Keras. Дополнительные функции и подписи могут быть добавлены в SavedModels, а затем обслуживаться с помощью TFServing.
Изучите сохраненную модель
Мы обучили модель ResNet50 в предыдущем среднем посте и сохранили ее в формате SaveModel. Мы можем использовать эту команду, чтобы показать сигнатуры моделей, которые будут обслуживаться Tensorflow Serving: saved_model_cli show --all --dir model_path
signature_def['serving_bytes']:
The given SavedModel SignatureDef contains the following input(s):
inputs['image_bytes_string'] tensor_info:
dtype: DT_STRING
shape: unknown_rank
name: serving_bytes_image_bytes_string:0
The given SavedModel SignatureDef contains the following output(s):
outputs['output_0'] tensor_info:
dtype: DT_FLOAT
shape: (1, 10)
name: StatefulPartitionedCall:0
Method name is: tensorflow/serving/predict
signature_def['serving_default']:
The given SavedModel SignatureDef contains the following input(s):
inputs['input_tensor'] tensor_info:
dtype: DT_FLOAT
shape: (-1, -1, -1, 3)
name: serving_default_input_tensor:0
The given SavedModel SignatureDef contains the following output(s):
outputs['output_0'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 10)
name: StatefulPartitionedCall_1:0
Method name is: tensorflow/serving/predict
Из вывода видно, что signalserving_default
принимает ввод массива 4d, тогда как serving_bytes
принимает ввод массива в кодировке base64 (в виде строки). Обе подписи выводят массив с 10 числами (вероятностями), так как модель обучена на MNIST и имеет 10 классов.
Запуск обслуживания Tensorflow
Tensorflow рекомендует использовать образ Docker для Tensorflow Serving, поскольку это самый простой способ использовать Tensorflow Serving с поддержкой GPU. Следуйте инструкциям по этой ссылке, если у вас нет докера и вы хотите установить Tensorflow Serving вручную.
Приведенный ниже скрипт создает и запускает контейнер Tensorflow Serving с заданной моделью. Порт 8500 используется для gRPC API, а 8501 — для REST API. Этот скрипт привязывает каталог модели на хосте к контейнеру и считывает модель оттуда. Однако при использовании Tensorflow Serving в производственных средах рекомендуется размещать модели в образах Docker вместо использования привязок.
docker run -p 8500:8500 -p 8501:8501 -d --name resnet_serving \
-v /directory/on/host/models:/models \
-e MODEL_NAME=ResnetModel tensorflow/serving:2.8.0-gpu
Чтобы проверить, правильно ли он работает, перейдите по этому адресу в веб-браузере: http://hostname:8501/v1/models/ResnetModel
. Он возвращает json, как показано ниже, если он работает правильно:
{
"model_version_status": [
{
"version": "1",
"state": "AVAILABLE",
"status": {
"error_code": "OK",
"error_message": ""
}
}
]
}
Использование службы REST
И протоколы REST, и gRPC имеют свои преимущества и недостатки. Вероятно, наиболее важным из них является то, что протокол REST более распространен.
Чтобы вызвать модель с помощью REST API, отправьте POST-запрос на http://hostname:8501/v1/models/ResnetModel:predict
с таким телом запроса:
{
"signature_name": "serving_bytes",
"instances": [{"b64": "fill_with_base64_encoded_image_bytes"}]
}
Поскольку модель обучается на наборе данных MNIST, содержащем рукописные цифры от 0 до 9, сервис возвращает активации без применения softmax для 10 классов. В приведенном ниже примере прогнозом модели будет класс с наивысшим значением активации, 3-й индекс (принадлежащий номеру 2):
{"predictions": [[-14.9772987, -6.99252939, 13.5781298, -8.89471, -6.88773823, -4.63609457, 0.168618962, -9.86182785, -2.09211802, -1.32305372]]}
Тот же результат можно получить, вызвав serving_default
signature со значениями пикселей RGB. Эта подпись поддерживает одновременную обработку нескольких изображений, поскольку она имеет 4-мерный ввод (пакет, высота, ширина, канал):
{ "signature_name": "serving_default", "instances":
[[[[0, 0, 0], [0, 0, 0], [255, 255, 255], ...]}
Для REST API эта сигнатура работает медленнее, чем serving_bytes
, при отправке изображений с высоким разрешением, поскольку целочисленные массивы потребляют гораздо больше памяти при преобразовании в строки.
Использование службы gRPC
Использование gRPC Tensorflow Serving API официально поддерживается только для Python. Есть несколько клиентов с открытым исходным кодом для других языков, но они могут быть недоступны для последних версий Tensorflow Serving. Для Python должен быть установлен tensorflow-serving-api: pip install tensorflow-serving-api
. Сервисная заглушка с незащищенным соединением (отметьте здесь для безопасного соединения) создается ниже:
Прогнозы для serving_default
signature можно сделать с помощью заглушки, определенной выше:
Методы tf.make_tensor_proto
и tf.make_ndarray
используются для преобразования массива numpy в/из тензора. В одном запросе serving_default
можно отправить несколько изображений для получения более быстрых результатов. Для относительно больших изображений (например, 600x600px) можно использовать serving_bytes
signature для получения более быстрых результатов:
Заключение
Мы использовали Tensorflow Serving для создания REST и gRPC API для двух сигнатур нашей модели классификации изображений. REST API прост в использовании и работает быстрее при использовании массивов байтов base64 вместо целочисленных массивов. Для использования gRPC API необходимо использовать внешние платформы. Однако это происходит быстрее при отправке нескольких изображений в виде пустых массивов.
Пожалуйста, проверьте репозиторий GitHub для получения полного кода. Не стесняйтесь задавать любые вопросы в комментариях. В следующем посте мы измерим производительность Tensorflow Serving и обсудим, как повысить ее производительность.