使用 TensorFlow 服务

在本节中,我们将向您展示如何设置 RNN 模型以预测 TensorFlow 上的垃圾邮件或火腿文本消息。我们将首先说明如何以 protobuf 格式保存模型,然后将模型加载到本地服务器,监听端口9000以进行输入。

做好准备

我们通过鼓励读者阅读 https://www.tensorflow.org/serving/serving_basic 上提供的 TensorFlow 服务网站上的官方文档和简短教程来开始本节。

对于这个例子,我们将在第 9 章,循环神经网络中重用我们在预测垃圾邮件中使用的大部分 RNN 代码和 RNNs 秘籍。我们将更改模型保存代码,以便将 protobuf 模型保存在使用 TensorFlow 服务所需的正确文件夹结构中。

请注意,本章中的所有脚本都应该从命令行 bash 提示符执行。

有关更新的安装说明,请访问官方安装站点: https://www.tensorflow.org/serving/setup 。正常安装就像向 Linux 源添加 gpg-key 并运行以下安装命令一样简单:

$ sudo apt install tensorflow-model-server

操作步骤

  1. 在这里,我们将以与以前相同的方式开始,通过加载必要的库并设置 TensorFlow 标志,如下所示:
import os
import re
import io
import sys
import requests
import numpy as np
import tensorflow as tf
from zipfile import ZipFile
from tensorflow.python.framework import ops

ops.reset_default_graph()

# Define App Flags
tf.flags.DEFINE_string("storage_folder", "temp", "Where to store model and data.")
tf.flags.DEFINE_float('learning_rate', 0.0005, 'Initial learning rate.')
tf.flags.DEFINE_float('dropout_prob', 0.5, 'Per to keep probability for dropout.')
tf.flags.DEFINE_integer('epochs', 20, 'Number of epochs for training.')
tf.flags.DEFINE_integer('batch_size', 250, 'Batch Size for training.')
tf.flags.DEFINE_integer('rnn_size', 15, 'RNN feature size.')
tf.flags.DEFINE_integer('embedding_size', 25, 'Word embedding size.')
tf.flags.DEFINE_integer('min_word_frequency', 20, 'Word frequency cutoff.')
tf.flags.DEFINE_boolean('run_unit_tests', False, 'If true, run tests.')

FLAGS = tf.flags.FLAGS
  1. 我们将以完全相同的方式继续完成脚本。为简洁起见,我们只会在训练脚本中包含差异,这就是我们如何保存 protobuf 模型。这是通过在训练完成后插入以下代码来完成的:

请注意此代码与教程代码的相似之处。这里的主要区别在于模型名称,版本号以及我们正在保存 RNN 而不是 CNN 的事实。

# Save the finished model for TensorFlow Serving (pb file)
# Here, it's our storage folder / version number
out_path = os.path.join(tf.compat.as_bytes(os.path.join(storage_folder, '1')))
print('Exporting finished model to : {}'.format(out_path))
builder = tf.saved_model.builder.SavedModelBuilder(out_path)

# Build the signature_def_map.
classification_inputs = tf.saved_model.utils.build_tensor_info(x_data_ph)
classification_outputs_classes = tf.saved_model.utils.build_tensor_info(rnn_model_outputs)

classification_signature = (tf.saved_model.signature_def_utils.build_signature_def(
                inputs={tf.saved_model.signature_constants.CLASSIFY_INPUTS:   
                        classification_inputs},
                outputs={tf.saved_model.signature_constants.CLASSIFY_OUTPUT_CLASSES: 
                         classification_outputs_classes},
                method_name=tf.saved_model.signature_constants.CLASSIFY_METHOD_NAME))

        tensor_info_x = tf.saved_model.utils.build_tensor_info(x_data_ph)
        tensor_info_y = tf.saved_model.utils.build_tensor_info(y_output_ph)

        prediction_signature = (
            tf.saved_model.signature_def_utils.build_signature_def(
                inputs={'texts': tensor_info_x},
                outputs={'scores': tensor_info_y},
                method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME))

        legacy_init_op = tf.group(tf.tables_initializer(), name='legacy_init_op')
        builder.add_meta_graph_and_variables(
            sess, [tf.saved_model.tag_constants.SERVING],
            signature_def_map={
                'predict_spam': prediction_signature,
                tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
                    classification_signature,
            },
            legacy_init_op=legacy_init_op)

        builder.save()

        print('Done exporting!')
  1. 对我们来说,重要的是要意识到 TensorFlow Serving 需要特定的文件或文件夹结构来加载模型。该脚本将以以下格式安装文件:

A screenshot of the directory structure that TensorFlow Serving expects.

上面的屏幕截图显示了所需的目录结构。在其中,我们有我们定义的数据目录temp,然后是我们的模型版本号1。在版本号目录中,我们保存我们的 protobuf 模型和一个包含要保存的所需变量的variables文件夹。

我们应该知道,在我们的数据目录中,TensorFlow 服务将查找整数文件夹。 TensorFlow 服务将自动启动并在最大整数下获取模型。这意味着要部署新模型,我们需要将其标记为版本 2,并将其粘贴在也标记为2的新文件夹下。然后,TensorFlow 服务将自动获取模型。

  1. 要启动我们的服务器,我们使用端口,model_namemodel_base_path参数调用命令tensorflow_model_server。然后,TensorFlow Serving 查找版本号文件夹并选择最大版本编号的模型。然后它将它部署到机器上,命令通过作为参数给出的端口运行。在以下示例中,我们在本地计算机(0.0.0.0)上运行,并且接受的默认端口是9000
$ tensorflow_model_server --port=9000 --model_name=spam_ham --model_base_path=<directory of our code>/tensorflow_cookbook/10_Taking_TensorFlow_to_Production/06_Using_TensorFlow_Serving/temp/

2018-08-09 12:05:16.206712: I tensorflow_serving/model_servers/main.cc:153] Building single TensorFlow model file config: model_name: spam_ham model_base_path: .../temp/
2018-08-09 12:05:16.206874: I tensorflow_serving/model_servers/server_core.cc:459] Adding/updating models.
2018-08-09 12:05:16.206903: I tensorflow_serving/model_servers/server_core.cc:514] (Re-)adding model: spam_ham
2018-08-09 12:05:16.307681: I tensorflow_serving/core/basic_manager.cc:716] Successfully reserved resources to load servable {name: spam_ham version: 1}
2018-08-09 12:05:16.307744: I tensorflow_serving/core/loader_harness.cc:66] Approving load for servable version {name: spam_ham version: 1}
2018-08-09 12:05:16.307773: I tensorflow_serving/core/loader_harness.cc:74] Loading servable version {name: spam_ham version: 1}
2018-08-09 12:05:16.307829: I external/org_tensorflow/tensorflow/contrib/session_bundle/bundle_shim.cc:360] Attempting to load native SavedModelBundle in bundle-shim from: .../temp/1
2018-08-09 12:05:16.307867: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:242] Loading SavedModel with tags: { serve }; from: .../temp/1
2018-08-09 12:05:16.313811: I external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2018-08-09 12:05:16.325866: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:161] Restoring SavedModel bundle.
2018-08-09 12:05:16.329290: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:196] Running LegacyInitOp on SavedModel bundle.
2018-08-09 12:05:16.332936: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:291] SavedModel load for tags { serve }; Status: success. Took 25074 microseconds.
2018-08-09 12:05:16.332972: I tensorflow_serving/servables/tensorflow/saved_model_warmup.cc:83] No warmup data file found at .../temp/1/assets.extra/tf_serving_warmup_requests
2018-08-09 12:05:16.333335: I tensorflow_serving/core/loader_harness.cc:86] Successfully loaded servable version {name: spam_ham version: 1}
2018-08-09 12:05:16.334678: I tensorflow_serving/model_servers/main.cc:323] Running ModelServer at 0.0.0.0:9000 ...
  1. 我们现在可以将二进制数据提交给&lt;host&gt;:9000并返回显示结果的 JSON 响应。我们可以通过任何机器和任何编程语言来完成。不必依赖客户端拥有 TensorFlow 的本地副本是非常有用的。

工作原理

如果我们将早期的生产规模部分与前一部分进行比较,主要区别在于我们在主机上部署了可以响应传入请求的模型服务器。前面的部分是一个很好的设置示例,用于执行批量结果或在可以加载 TensorFlow 的机器上工作,但秘籍不是很擅长部署可用的模型,可以进行计算,并将结果返回给任何客户。在本节中,我们将了解如何处理这种体系结构,如下表所示:

第 5 节 - 批量生产 第 6 节 - 通过 TensorFlow 服务生产
优点 不依赖于网络连接或主机 结果与客户端结构无关,唯一的要求是 Numpy 数组的正确格式化二进制文件
缺点 客户端必须具有 TensorFlow 和模型文件 依靠主机可用
理想的用途 大批量数据 生产服务始终可用,通常是小的请求

当然,每种方法的优缺点都值得商榷,两者都能满足每种情况的要求。还有许多其他可用的架构可以满足不同的需求,例如 Docker,Kubernetes,Luigi,Django / Flask,Celery,AWS 和 Azure。

更多

本章未涉及的体系结构工具和资源的链接如下:

results matching ""

    No results matching ""