Обслуживание модели TensorFlow

В этом руководстве показано, как использовать компоненты обслуживания 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 тестовых изображений. Это подтверждает, что сервер успешно загружает и запускает обученную модель!