Плюс - Как написать клиент GRPC для обернутой модели
После того, как вы обучили свою модель на основе Tensorflow или Keras, нужно подумать о том, как ее использовать, развернуть в производственной среде. Вы можете сделать его Dockerize как микросервис, реализуя собственный интерфейс GRPC (или REST- или нет). Затем разверните его на сервере или в кластере Kubernetes и попросите другие клиентские микросервисы вызывать его. Библиотека Google Tensorflow Serving помогает здесь сохранить вашу модель на диск, а затем загрузить и использовать интерфейс GRPC или RESTful для взаимодействия с ней.
Я пытался использовать это и обнаружил, что учебники / примеры немного сложны, особенно если вы используете настраиваемую модель, поэтому вот более простой вариант. Я до сих пор не уверен в использовании части TF Serving, так как иметь собственную оболочку GRPC поверх вашей модели не так уж сложно. Но обслуживание TF - это многообещающе. Думаю, со временем узнаю. На данный момент мы сосредоточимся на сохранении простой модели и ее работе с помощью клиента GRPC.
Шаг 1. Сохранение модели в режиме, совместимом с TF Serving
У нас есть простая модель. Я использовал простейший классификатор изображений MNIST, модель. См. Это в записной книжке, размещенной на Colab - https://colab.research.google.com/drive/1ioqL7hD-mrruOlAK-d2axenKVTHrU8gQ (пожалуйста, не обращайте внимания на многие отладочные отпечатки в записной книжке). После того, как NW обучен, нам нужно сохранить веса.
# No need to train if weights are already there from pathlib import Path from keras.models import load_model weightfile ='/content/gdrive/My Drive/Colab Notebooks/my_model_20.h5' my_file = Path(weightfile) if my_file.is_file(): print("Weight file exisits") model = load_model(weightfile) else: print("Weight file do not exist") # train the model and save it history =model.fit(X_train, Y_train,batch_size=32, epochs=20, callbacks=[plot], validation_data=(X_test, Y_test), verbose=1) model.save(weightfile)
Обратите внимание на то, как файл веса загружается / или сохраняется в приведенном выше фрагменте.
Что, если мы хотим сохранить модель и загрузить модель, чтобы получить к ней интерфейс REST или GRPC. Это то, что делает служба TF.
Сначала мы можем сохранить его способом, совместимым с TF Serving. Поскольку я использую Google Colab, я сохраняю модель на своем Google Диске, вы можете сохранить ее на диск или где-нибудь еще.
import shutil import os tf.keras.backend.clear_session() # The export path contains the name and the version of the model tf.keras.backend.set_learning_phase(0) # Ignore dropout at inference weightfile ='/content/gdrive/My Drive/Colab Notebooks/my_model_20.h5' export_path = '/content/gdrive/My Drive/Colab Notebooks/ServingModel20' if os.path.exists( export_path+"/1"): shutil.rmtree( export_path+"/1") export_path = export_path+"/1" # Fetch the Keras session and save the model with tf.keras.backend.get_session() as sess: model = load_model(weightfile) tf.saved_model.simple_save( sess, export_path, inputs={'input_image': model.input}, outputs={t.name:t for t in model.outputs})
В случае успеха результат будет похож на
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/saved_model/simple_save.py:85: calling SavedModelBuilder.add_meta_graph_and_variables (from tensorflow.python.saved_model.builder_impl) with legacy_init_op is deprecated and will be removed in a future version. Instructions for updating: Pass your op to the equivalent parameter main_op instead. INFO:tensorflow:Assets added to graph. INFO:tensorflow:No assets to write. INFO:tensorflow:SavedModel written to: /content/gdrive/My Drive/Colab Notebooks/ServingModel20/1/saved_model.pb
Обратите внимание на соглашение о пути к папке в приведенном выше фрагменте - ServingModel20 / 1, где 1 обозначает первую версию модели. TF Serving будет следить за корневым каталогом и автоматически развертывать более поздние версии - это одна из его функций. Итак, после того, как вы каким-то образом выполнили ML CI (что само по себе является публикацией), вы можете развернуть свою модель в ServingModel20 / 2 - и предварительно контейнер TF Serving автоматически загрузит новую модель.
Теперь давайте проверим, можем ли мы загрузить модель с TF Serving. (Обратите внимание, что версии модели по соглашению хранятся в подкаталогах / 1, / 2 и т. Д., Что может быть полезно для управления версиями модели).
!saved_model_cli show --dir '/content/gdrive/My Drive/Colab Notebooks/ServingModel20/1' --all
Вы получите параметры модели, если загрузка прошла успешно, как
MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs: signature_def['serving_default']: The given SavedModel SignatureDef contains the following input(s): inputs['input_image'] tensor_info: dtype: DT_FLOAT shape: (-1, 1, 28, 28) name: conv2d_1_input:0 The given SavedModel SignatureDef contains the following output(s): outputs['dense_2/Softmax:0'] tensor_info: dtype: DT_FLOAT shape: (-1, 10) name: dense_2/Softmax:0 Method name is: tensorflow/serving/predict
Обратите внимание на выделение жирным шрифтом, так как именно так вводятся и выводятся интерфейсы для GRPC или REST после обслуживания модели.
Шаг 2. Загрузка сохраненной модели и ее обслуживание с помощью TF Serve
Я загрузил модель в свою домашнюю папку и использовал образ докера tensorflow / serve: latest-gpu от команды TF Serving для загрузки модели - ServingModel20 из сопоставленной папки тома. (Обратите внимание, что у моего ноутбука есть графический процессор, поэтому я использую образ Docker с тегом графического процессора (обратите внимание, что отображение порта 8900 на локальном компьютере - это GRPC, а 8901 - интерфейс REST)
TFServing server sudo docker run --runtime= -t --rm -p 8900:8500 -p 8901:8501 -v /home/alex/coding/IPython_neuralnet/ServingModel20:/models/mnist -e MODEL_NAME=mnist tensorflow/serving:latest-gpu
В случае успеха вы получите результат, как показано ниже
2019-01-28 10:37:47.192669: I tensorflow_serving/model_servers/server.cc:286] Running gRPC ModelServer at 0.0.0.0:8500 ... [warn] getaddrinfo: address family for nodename not supported [evhttp_server.cc : 237] RAW: Entering the event loop ... 2019-01-28 10:37:47.194034: I tensorflow_serving/model_servers/server.cc:302] Exporting HTTP/REST API at:localhost:8501 .
Обратите внимание, что REST отображается в порту 8501, а интерфейс GRPC - в порту 8500 (порт сопоставлен с 8901 и 8900 на моем компьютере),
Вот и все! Осталось только написать клиента GRPC.
Шаг 3. Написание клиента GRPC.
Хотя есть пример из TF Serving, мне потребовалось некоторое время, чтобы разобраться в том, как заставить его работать. Я упростил для себя проверку, а здесь - клиент python.
Обратите внимание на передачу входных и выходных данных и подпись модели. Также входные изменяющие детали. Для других моделей это изменится.
channel = grpc.insecure_channel(hostport) stub = prediction_service_pb2_grpc.PredictionServiceStub(channel) request = predict_pb2.PredictRequest() request.model_spec.name = 'mnist' request.model_spec.signature_name = 'serving_default'
Получение вывода
result_future.result().outputs['dense_2/Softmax:0'].float_val)
Все эти ключи указаны в спецификации модели. Вот код
Шаг 4. Запуск клиента
Теперь нам нужно запустить клиента. Самый простой - запустить в докер-контейнере. Я использовал тот же контейнер Docker tensorflow_tfserving: latest-gpu для его запуска, но для упрощения обработки MNIST и некоторые модули python установили Keras и некоторые другие библиотеки python и сохранили их как alexcpn / tfserving-dev-gpu. (я сохранил mnist_client.py в / home / alex / coding в приведенном ниже фрагменте)
TFServing Client GPRC sudo docker run --runtime=nvidia --net=host -it -v /home/alex/coding:/coding --rm alexcpn/tfserving-dev-gpu bash
Теперь внутри этого контейнера давайте запустим клиент Python и дадим IP-адрес сервера, на котором запущен контейнер TF Serving.
python mnist_client.py --num_test=1000 --server=<your server ip ex 10.xx.xx.15>:8901
Если все прошло успешно, вы должны получить результат, как показано ниже или аналогичный
Using TensorFlow backend. hello from TFServing client slim Shape is (28, 28) Label is 7 Time to Send 20000 is 5.93926405907 [ 100 ] From Callback Predicted Result is 7 confidence= 1.0 [ 200 ] From Callback Predicted Result is 7 confidence= 1.0
Используйте nvidia-smi, чтобы проверить использование графического процессора. Обратите внимание, что с REST вывод должен быть медленнее, поскольку GRPC использует более эффективный HTTP2.
watch -n 0.5 nvidia-smi
Что-то, что нужно переосмыслить
Поскольку интерфейс выдает вывод последнего уровня, вам может потребоваться добавить микросервис, чтобы преобразовать его в обнаруженные классы; на практике это означает, что вам может потребоваться другая служба Micro, чтобы обернуть это и предоставить клиентам более общий интерфейс GRPC.
Кроме того, вход представляет собой массив numpy. Таким образом, по сравнению с обычными сетями для изображений высокой четкости это добавит много накладных расходов NW. Хотя есть небольшие накладные расходы на вычислительные ресурсы и время для кодирования и отправки в формате jpeg или png и декодирования его на приемнике, эти накладные расходы могут быть компенсированы снижением скорости передачи по сравнению с отправкой необработанного массива numpy по сети. Поэтому нам нужно посмотреть, действительно ли формат ввода массива numpy подходит для обнаружения в реальном времени, например, из видеопотока - когда мы используем несколько узлов с графическим процессором для горизонтального масштабирования.
Кроме того, это тесно связано с другими проектами, такими как Kubeflow. См. Эти прекрасные наборы слайдов от Дэвида Арончика, менеджера Google, а теперь главы отдела стратегии машинного обучения в Microsoft. Это описывает, как Kubeflow, основанный на Kubernetes и использующий TFServing, вписывается в производственный конвейер.
Другие ссылки
[1] Использование TensorFlow для обслуживания с Docker, https://www.tensorflow.org/serving/docker#gpu_serving_example (часть официального документа)
[2] Обучение и обслуживание моделей машинного обучения с tf.keras, Stijn Decubber, https://medium.com/tensorflow/training-and-serving-ml-models-with-tf-keras-fd975cc0fa27 (Показывает, как это через TFServing REST API)
[3] Оптимизация моделей TensorFlow для обслуживания, GCP, Лукман Рэмси, https://medium.com/google-cloud/optimizing-tensorflow-models-for-serving-959080e9ddbf (описывает, почему обслуживание TF)