使用TensorFlow Serving优化TensorFlow模型
大家好!今天向您介绍如何使用 TensorFlow Serving 组件导出已经过训练的 TensorFlow 模型,并使用标准 tensorflow_model_server 来对它提供服务。如您早已熟知 TensorFlow Serving,欲了解有关服务器内部工作方式的更多信息,请参阅 TensorFlow Serving 高阶教程(https://tensorflow.google.cn/serving/serving_advanced?hl=zh-CN)。
本文使用 TensorFlow 教程中引入的简单 Softmax 回归模型进行手写图像(MNIST 数据)分类。 如您尚不知晓 TensorFlow 或 MNIST 是什么,请参阅 MNIST For ML Beginners 教程(http://tensorflow.google.cn/tutorials/mnist/beginners/index.html?hl=zh-CN#mnist-for-ml-beginners)。
本文的代码由两部分组成:
一个 Python 文件 mnist_saved_model.py(https://github.com/tensorflow/serving/tree/master/tensorflow_serving/example/mnist_saved_model.py),用于训练和导出模型。
ModelServer 二进制文件,可以使用 Apt 安装,也可以从 C ++ 文件(main.cc)编译(https://github.com/tensorflow/serving/tree/master/tensorflow_serving/model_servers/main.cc)。TensorFlow Serving 的 ModelServer 发现新的导出模型, 并运行 gRPC 服务来为其服务(http://www.grpc.io/)。
正式开始之前,首先安装 Docker(https://tensorflow.google.cn/serving/docker?hl=zh-CN#installing-docker)。
训练和导出TensorFlow模型
正如您在 mnist_saved_model.py 中所见,训练的方式与在 MNIST For ML Beginners 教程中完成的方式相同(https://tensorflow.google.cn/get_started/mnist/beginners?hl=zh-CN)。 TensorFlow 图在 TensorFlow 会话中启动,输入张量(图像)为 x,输出张量(Softmax 得分)为 y。
之后我们使用 TensorFlow 的 SavedModelBuilder 模块导出模型(https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/builder.py)。 SavedModelBuilder 将训练模型的“快照”保存到可靠存储中,以便稍后加载以进行推理。
有关 SavedModel 格式的详细信息,请参阅 SavedModel 中的 README.md 文档(https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/README.md)。
从 mnist_saved_model.py 中可以看出(https://github.com/tensorflow/serving/tree/master/tensorflow_serving/example/mnist_saved_model.py),下面一个简短的代码片段用于说明将模型保存到磁盘的一般过程。
export_path_base = sys.argv[-1]
export_path = os.path.join(
compat.as_bytes(export_path_base),
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, [tag_constants.SERVING],
signature_def_map={
'predict_images':
prediction_signature,
signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
classification_signature,
},
main_op=main_op)
builder.save()
SavedModelBuilder .__ init__ 采用以下参数:
export_path 是导出目录的路径
如果目录不存在,SavedModelBuilder 将创建该目录。在示例中,我们连接命令行参数和 FLAGS.model_version 以获取导出目录。 FLAGS.model_version 指定模型的版本。导出同一模型的较新版本时,应指定较大的整数值。 每个版本将导出到给定路径下的不同子目录。
您可以使用带有以下参数的 SavedModelBuilder.add_meta_graph_and_variables()将元图和变量添加到构建器:
sess 是 TensorFlow 会话,包含您正在导出的训练模型。
tags 是用于保存元图的标记集。在这种情况下,由于我们打算在服务中使用图形,因此我们使用来自预定义的 SavedModel 标记常量的 serve 标记。 更多详细信息,请参阅 tag_constants.py(https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/tag_constants.py)和相关的 TensorFlow API 文档(https://tensorflow.google.cn/api_docs/python/tf/saved_model/tag_constants?hl=zh-CN)。
signature_def_map 指定用户提供的签名映射到 tensorflow :: SignatureDef 以添加到元图的签名。Signature 指定正在导出的模型类型,以及在运行推理时绑定到的输入/输出张量。
特殊签名密钥 serving_default 指定默认服务签名。 默认服务签名 def 键以及与签名相关的其他常量被定义为 SavedModel 签名常量的一部分。 更多详细信息,请参阅 signature_constants.py(https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/signature_constants.py)和相关的 TensorFlow 1.0 API 文档(https://tensorflow.google.cn/api_docs/python/tf/saved_model/signature_constants?hl=zh-CN)。
此外,为了帮助轻松构建签名定义,SavedModel API 提供了签名 def utils(https://tensorflow.google.cn/api_docs/python/tf/saved_model/signature_def_utils?hl=zh-CN) 具体来说,在原始的 mnist_saved_model.py 文件中(https://github.com/tensorflow/serving/tree/master/tensorflow_serving/example/mnist_saved_model.py) 我们将 signature_def_utils.build_signature_def()用于 buildpredict_signature和classification_signature。
如何定义 predict_signature? 作为示例,util 会使用以下参数:
inputs={'images': tensor_info_x} 指定输入张量信息。
outputs={'scores': tensor_info_y} 指定分数张量信息。
method_name 是用于推理的方法。对于预测请求,应将其设置为 tensorflow / serving / predict。有关其他方法名称,请参阅 signature_constants.py(https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/signature_constants.py) 和 relatedTensorFlow 1.0 API 文档(https://tensorflow.google.cn/api_docs/python/tf/saved_model/signature_constants?hl=zh-CN)。
请注意,tensor_info_x 和 tensor_info_y 具有此处定义的 tensorflow :: TensorInfo 协议缓冲区的结构(https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/protobuf/meta_graph.proto)。 为了轻松构建张量信息,TensorFlow SavedModel API 还提供 utils.py(https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/utils.py)以及相关的 TensorFlow 1.0 API 文档(https://tensorflow.google.cn/api_docs/python/tf/saved_model/utils?hl=zh-CN)。
另外一点需要注意的是,图像和分数是张量别名。它们可以是您想要的任何特定的独一无二的字符串,作为张量 x 和 y 的逻辑名称,您可以在稍后发送预测请求时引用张量绑定。
例如,如果 x 引用名称为 “long_tensor_name_foo” 的张量,y 引用名称为 “generated_tensor_name_bar” 的张量,则构建器将张量逻辑名称存储为实名映射('images' - >'long_tensor_name_foo')和(' 得分 ' ' - >'generated_tensor_name_bar')。 这允许用户在运行推理时使用其逻辑名称来引用这些张量。
注意:除了上面的描述之外,您还可以在此处找到与签名 def 结构以及如何设置的相关文档(https://tensorflow.google.cn/serving/signature_defs?hl=zh-CN)。
开始运行!
您如果还没开始这样做,首先请将此存储库克隆到本地计算机:
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 是序列化的 tensorflow :: SavedModel。它包括模型的一个或多个图形定义,以及模型的元数据(如签名)。
变量是包含图形序列化变量的文件。
这样,您的 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 实用程序来测试服务器(https://github.com/tensorflow/serving/tree/master/tensorflow_serving/example/mnist_client.py)。 客户端下载 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%,前 1,000 个测试图像的推理误差率为 11%。 这就确认服务器成功加载并运行了已训练的模型!
更多 AI 相关阅读: