💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 使用 TensorFlow 服务 在本节中,我们将向您展示如何设置 RNN 模型以预测 TensorFlow 上的垃圾邮件或火腿文本消息。我们将首先说明如何以 protobuf 格式保存模型,然后将模型加载到本地服务器,监听端口`9000`以进行输入。 ## 做好准备 我们通过鼓励读者阅读 [https://www.tensorflow.org/serving/serving_basic](https://www.tensorflow.org/serving/serving_basic) 上提供的 TensorFlow 服务网站上的官方文档和简短教程来开始本节。 对于这个例子,我们将在[第 9 章](../Text/68.html),循环神经网络中重用我们在预测垃圾邮件中使用的大部分 RNN 代码和 RNNs 秘籍。我们将更改模型保存代码,以便将 protobuf 模型保存在使用 TensorFlow 服务所需的正确文件夹结构中。 > 请注意,本章中的所有脚本都应该从命令行 bash 提示符执行。 有关更新的安装说明,请访问官方安装站点: [https://www.tensorflow.org/serving/setup](https://www.tensorflow.org/serving/setup) 。正常安装就像向 Linux 源添加 gpg-key 并运行以下安装命令一样简单: ```py $ sudo apt install tensorflow-model-server ``` ## 操作步骤 1. 在这里,我们将以与以前相同的方式开始,通过加载必要的库并设置 TensorFlow 标志,如下所示: ```py 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 的事实。 ```py # 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 需要特定的文件或文件夹结构来加载模型。该脚本将以以下格式安装文件: ![](https://img.kancloud.cn/d8/ec/d8ecfb33a993023a625a65d75ba6f918_380x136.png) A screenshot of the directory structure that TensorFlow Serving expects. 上面的屏幕截图显示了所需的目录结构。在其中,我们有我们定义的数据目录`temp`,然后是我们的模型版本号`1`。在版本号目录中,我们保存我们的 protobuf 模型和一个包含要保存的所需变量的`variables`文件夹。 > 我们应该知道,在我们的数据目录中,TensorFlow 服务将查找整数文件夹。 TensorFlow 服务将自动启动并在最大整数下获取模型。这意味着要部署新模型,我们需要将其标记为版本 2,并将其粘贴在也标记为`2`的新文件夹下。然后,TensorFlow 服务将自动获取模型。 1. 要启动我们的服务器,我们使用端口,`model_name`和`model_base_path`参数调用命令`tensorflow_model_server`。然后,TensorFlow Serving 查找版本号文件夹并选择最大版本编号的模型。然后它将它部署到机器上,命令通过作为参数给出的端口运行。在以下示例中,我们在本地计算机(`0.0.0.0`)上运行,并且接受的默认端口是`9000`: ```py $ 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。 ## 更多 本章未涉及的体系结构工具和资源的链接如下: * 在 Docker 中使用 TensorFlow 服务: [https://www.tensorflow.org/serving/docker](https://www.tensorflow.org/serving/docker) * 在 Kubernetes 中使用 TensorFlow 服务: [https://www.tensorflow.org/serving/serving_inception](https://www.tensorflow.org/serving/serving_inception) * Luigi,批量作业的管道工具: [https://github.com/spotify/luigi](https://github.com/spotify/luigi) * 在 Flask 中使用 TensorFlow: [https://guillaumegenthial.github.io/serving.html](https://guillaumegenthial.github.io/serving.html) * 用于分布式任务排队的 Python 框架: [http://www.celeryproject.org/community/](http://www.celeryproject.org/community/) * 如何在 TensorFlow 模型中使用 AWS lambdas: [https://aws.amazon.com/blogs/machine-learning/how-to-deploy-deep-learning-models-with-aws-lambda-and-tensorflow/](https://aws.amazon.com/blogs/machine-learning/how-to-deploy-deep-learning-models-with-aws-lambda-and-tensorflow/)