В этом руководстве показано, как использовать компоненты обслуживания TensorFlow для экспорта обученной модели TensorFlow и использовать стандартный tensorflow_model_server для ее обслуживания. Если вы уже знакомы с TensorFlow Serving и хотите узнать больше о том, как работают внутренние компоненты сервера, см. расширенное руководство по TensorFlow Serving .
В этом руководстве используется простая модель регрессии Softmax, которая классифицирует рукописные цифры. Он очень похож на представленный в уроке TensorFlow по классификации изображений с использованием набора данных Fashion MNIST .
Код этого руководства состоит из двух частей:
Файл Python mnist_saved_model.py , который обучает и экспортирует модель.
Бинарный файл ModelServer, который можно либо установить с помощью Apt, либо скомпилировать из файла C++ ( main.cc ). Сервер TensorFlow Serving ModelServer обнаруживает новые экспортированные модели и запускает службу gRPC для их обслуживания.
Прежде чем приступить к работе, сначала установите Docker .
Обучение и экспорт модели TensorFlow
На этапе обучения граф TensorFlow запускается в сеансе TensorFlow sess
с входным тензором (изображением) как x
и выходным тензором (показатель Softmax) как y
.
Затем мы используем модуль SavedModelBuilder TensorFlow для экспорта модели. SavedModelBuilder
сохраняет «моментальный снимок» обученной модели в надежном хранилище, чтобы его можно было загрузить позже для вывода.
Подробную информацию о формате SavedModel см. в документации SavedModel README.md .
Ниже приведен короткий фрагмент кода из mnist_saved_model.py , иллюстрирующий общий процесс сохранения модели на диск.
export_path_base = sys.argv[-1]
export_path = os.path.join(
tf.compat.as_bytes(export_path_base),
tf.compat.as_bytes(str(FLAGS.model_version)))
print('Exporting trained model to', export_path)
builder = tf.saved_model.builder.SavedModelBuilder(export_path)
builder.add_meta_graph_and_variables(
sess, [tf.compat.v1.saved_model.tag_constants.SERVING],
signature_def_map={
'predict_images':
prediction_signature,
tf.compat.v1.saved_model.signature_constants
.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
classification_signature,
},
main_op=tf.compat.v1.tables_initializer(),
strip_default_attrs=True)
builder.save()
SavedModelBuilder.__init__
принимает следующий аргумент:
-
export_path
— это путь к каталогу экспорта.
SavedModelBuilder
создаст каталог, если он не существует. В этом примере мы объединяем аргумент командной строки и FLAGS.model_version
, чтобы получить каталог экспорта. FLAGS.model_version
указывает версию модели. При экспорте более новой версии той же модели следует указать большее целое значение. Каждая версия будет экспортирована в отдельный подкаталог по указанному пути.
Вы можете добавить метаграфик и переменные в построитель, используя SavedModelBuilder.add_meta_graph_and_variables()
со следующими аргументами:
sess
— это сеанс TensorFlow, в котором хранится обученная модель, которую вы экспортируете.tags
— набор тегов, с помощью которых сохраняется метаграфик. В этом случае, поскольку мы намерены использовать граф при обслуживании, мы используем тегserve
из предопределенных констант тега SavedModel. Дополнительные сведения см. в tag_constants.py и связанной с ним документации по API TensorFlow .signature_def_map
указывает карту предоставленного пользователем ключа для подписи в tensorflow::SignatureDef для добавления в метаграф. Сигнатура указывает, какой тип модели экспортируется, а также тензоры ввода/вывода, к которым необходимо привязаться при выполнении вывода.Специальный ключ подписи
serving_default
определяет подпись обслуживания по умолчанию. Ключ определения обслуживающей подписи по умолчанию, а также другие константы, связанные с подписями, определяются как часть констант подписи SavedModel. Дополнительные сведения см. в Signature_constants.py и связанной с ним документации по API TensorFlow .Кроме того, чтобы облегчить создание определений сигнатур, API SavedModel предоставляет утилиты определения сигнатур . В частности, в исходном файле mnist_saved_model.py мы используем
signature_def_utils.build_signature_def()
для построенияpredict_signature
иclassification_signature
.В качестве примера того, как определяется
predict_signature
, утилита принимает следующие аргументы:inputs={'images': tensor_info_x}
указывает входную информацию о тензоре.outputs={'scores': tensor_info_y}
указывает информацию о тензоре оценок.method_name
— это метод, используемый для вывода. Для запросов прогнозирования должно быть установлено значениеtensorflow/serving/predict
. Другие имена методов см. в Signature_constants.py и связанной с ним документации по API TensorFlow .
Обратите внимание, что tensor_info_x
и tensor_info_y
имеют структуру буфера протокола tensorflow::TensorInfo
, определенную здесь . Чтобы легко создавать информацию о тензоре, API TensorFlow SavedModel также предоставляет utils.py с соответствующей документацией по API TensorFlow .
Также обратите внимание, что images
и scores
являются псевдонимами тензоров. Это могут быть любые уникальные строки, которые вы хотите, и они станут логическими именами тензоров x
и y
, на которые вы будете ссылаться для привязки тензора при отправке запросов прогнозирования позже.
Например, если x
относится к тензору с именем «long_tensor_name_foo», а y
относится к тензору с именем «generated_tensor_name_bar», builder
сохранит логическое имя тензора для сопоставления реального имени («images» -> «long_tensor_name_foo») и ('scores ' -> 'generated_tensor_name_bar'). Это позволяет пользователю ссылаться на эти тензоры по их логическим именам при выполнении вывода.
Давайте запустим это!
Во-первых, если вы еще этого не сделали, клонируйте этот репозиторий на свой локальный компьютер:
git clone https://github.com/tensorflow/serving.git
cd serving
Очистите каталог экспорта, если он уже существует:
rm -rf /tmp/mnist
Теперь давайте обучим модель:
tools/run_in_docker.sh python tensorflow_serving/example/mnist_saved_model.py \
/tmp/mnist
Это должно привести к выводу, который выглядит следующим образом:
Training model...
...
Done training!
Exporting trained model to models/mnist
Done exporting!
Теперь давайте посмотрим на каталог экспорта.
$ ls /tmp/mnist
1
Как упоминалось выше, для экспорта каждой версии модели будет создан подкаталог. FLAGS.model_version
имеет значение по умолчанию 1, поэтому создается соответствующий подкаталог 1
.
$ ls /tmp/mnist/1
saved_model.pb variables
Подкаталог каждой версии содержит следующие файлы:
saved_model.pb
— это сериализованный тензорный поток::SavedModel. Он включает в себя одно или несколько определений графа модели, а также метаданные модели, такие как подписи.variables
— это файлы, содержащие сериализованные переменные графиков.
После этого ваша модель TensorFlow экспортирована и готова к загрузке!
Загрузите экспортированную модель с помощью стандартного TensorFlow ModelServer.
Используйте образ обслуживания Docker, чтобы легко загрузить модель для обслуживания:
docker run -p 8500:8500 \
--mount type=bind,source=/tmp/mnist,target=/models/mnist \
-e MODEL_NAME=mnist -t tensorflow/serving &
Протестируйте сервер
Мы можем использовать предоставленную утилиту mnist_client для тестирования сервера. Клиент загружает тестовые данные MNIST, отправляет их в виде запросов на сервер и рассчитывает частоту ошибок вывода.
tools/run_in_docker.sh python tensorflow_serving/example/mnist_client.py \
--num_tests=1000 --server=127.0.0.1:8500
Это должно вывести что-то вроде
...
Inference error rate: 11.13%
Мы ожидаем, что точность обученной модели Softmax составит около 90 %, и мы получим коэффициент ошибок вывода 11 % для первых 1000 тестовых изображений. Это подтверждает, что сервер успешно загружает и запускает обученную модель!