This tutorial shows you how to use TensorFlow Serving components to export a trained TensorFlow model and use the standard tensorflow_model_server to serve it. If you are already familiar with TensorFlow Serving, and you want to know more about how the server internals work, see the TensorFlow Serving advanced tutorial.
This tutorial uses the simple Softmax Regression model introduced in the TensorFlow tutorial for handwritten image (MNIST data) classification. If you do not know what TensorFlow or MNIST is, see the MNIST For ML Beginners tutorial.
The code for this tutorial consists of two parts:
-
A Python file (mnist_saved_model.py) that trains and exports the model.
-
A C++ file main.cc which is the standard TensorFlow model server that discovers new exported models and runs a gRPC service for serving them.
Before getting started, please complete the prerequisites.
As you can see in mnist_saved_model.py, the training is done the same way it
is in the MNIST For ML Beginners tutorial. The TensorFlow graph is launched in
TensorFlow session sess, with the input tensor (image) as x and output
tensor (Softmax score) as y.
Then we use TensorFlow Serving SavedModelBuilder module to export the model.
SavedModelBuilder saves a "snapshot" of the trained model to reliable storage
so that it can be loaded later for inference.
from tensorflow.python.saved_model import builder as saved_model_builder
...
export_path_base = sys.argv[-1]
print 'Exporting trained model to', export_path
builder = saved_model_builder.SavedModelBuilder(export_path)
builder.add_meta_graph_and_variables(
sess, [tag_constants.SERVING],
signature_def_map={
'predict':
prediction_signature,
signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
classification_signature,
},
legacy_init_op=legacy_init_op)
builder.save()SavedModelBuilder.__init__ takes the following argument:
export_pathis the path of the export directory.SavedModelBuilderwill create the directory if it does not exist. In the example, we concatenate the command line argument andFLAGS.model_versionto obtain the export directory.FLAGS.model_versionspecifies the version of the model. You should specify a larger integer value when exporting a newer version of the same model. Each version will be exported to a different sub-directory under the given path.
You can add meta graph and variables to the builder using
SavedModelBuilder.add_meta_graph_and_variables() with the following arguments:
-
sessis the TensorFlow session that holds the trained model you are exporting. -
tagsis the set of tags with which to save the meta graph. -
signature_def_mapspecifies the map of user-supplied key for a signature to a tensorflow::SignatureDef to add to the meta graph. Signature specifies what type of model is being exported, and the input/output tensors to bind to when running inference. The special signature keyserving_defaultspecifies the default serving signature.signature_def_utils.build_signature_def()accepts the following arguments:-
inputs={'images': tensor_info_x}specifies the input tensor info. -
outputs={'scores': tensor_info_y}specifies the scores tensor info. -
imagesandscoresare tensor alias names. They can be whatever unique strings you want, and they will become the logical names of tensorxandythat you refer to for tensor binding when sending prediction requests later. For instance, ifxrefers to the tensor with name 'long_tensor_name_foo' andyrefers to the tensor with name 'generated_tensor_name_bar',builderwill store tensor logical name to real name mapping ('images' -> 'long_tensor_name_foo' and 'scores' -> 'generated_tensor_name_bar') and allow user to refer to these tensors with their logical names when running inference. -
method_nameis the method used for the inference. For Prediction requests, it should be set totensorflow/serving/predict.
-
Let's run it!
Clear the export directory if it already exists:
$>rm -rf /tmp/mnist_model$>bazel build //tensorflow_serving/example:mnist_saved_model
$>bazel-bin/tensorflow_serving/example/mnist_saved_model /tmp/mnist_model
Training model...
...
Done training!
Exporting trained model to /tmp/mnist_model
Done exporting!Now let's take a look at the export directory.
$>ls /tmp/mnist_model
1As mentioned above, a sub-directory will be created for exporting each version
of the model. FLAGS.model_version has the default value of 1, therefore
the corresponding sub-directory 1 is created.
$>ls /tmp/mnist_model/1
saved_model.pb variablesEach version sub-directory contains the following files:
-
saved_model.pbis the serialized tensorflow::SavedModel. It includes the the one or more graph definitions of the model, as well as metadata of the model such as signatures. -
variablesare files that hold the serialized variables of the graphs.
With that, your TensorFlow model is exported and ready to be loaded!
$>bazel build //tensorflow_serving/model_servers:tensorflow_model_server
$>bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server --port=9000 --model_name=mnist --model_base_path=/tmp/mnist_model/We can use the provided mnist_client utility to test the server. The client downloads MNIST test data, sends them as requests to the server, and calculates the inference error rate.
To run it:
$>bazel build //tensorflow_serving/example:mnist_client
$>bazel-bin/tensorflow_serving/example/mnist_client --num_tests=1000 --server=localhost:9000
...
Inference error rate: 10.5%We expect around 91% accuracy for the trained Softmax model and we get 10.5% inference error rate for the first 1000 test images. This confirms that the server loads and runs the trained model successfully!