本教學課程說明如何使用 TensorFlow Serving 元件匯出已訓練的 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
。
接著,我們使用 TensorFlow 的 SavedModelBuilder 模組匯出模型。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
是用於儲存中繼圖表的標記集。在本例中,由於我們打算在提供模型時使用圖表,因此我們使用預先定義的 SavedModel 標記常數中的serve
標記。如需更多詳細資訊,請參閱 tag_constants.py 和相關的 TensorFlow API 文件。signature_def_map
指定使用者提供的金鑰地圖,用於將簽名新增至中繼圖表的 tensorflow::SignatureDef。簽名指定要匯出的模型類型,以及在執行推論時要繫結的輸入/輸出張量。特殊的簽名金鑰
serving_default
指定預設提供模型簽名。預設提供模型簽名定義金鑰,以及其他與簽名相關的常數,皆定義為 SavedModel 簽名常數的一部分。如需更多詳細資訊,請參閱 signature_constants.py 和相關的 TensorFlow API 文件。此外,為了協助輕鬆建構簽名定義,SavedModel API 提供了簽名定義公用程式。具體來說,在原始 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 和相關的 TensorFlow API 文件。
請注意,tensor_info_x
和 tensor_info_y
具有 此處定義的 tensorflow::TensorInfo
通訊協定緩衝區結構。為了輕鬆建構張量資訊,TensorFlow SavedModel API 也提供 utils.py,以及相關的 TensorFlow API 文件。
另請注意,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
是序列化的 tensorflow::SavedModel。它包含模型的一個或多個圖表定義,以及模型的 Metadata (例如簽名)。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%,而前 1000 張測試圖片的推論錯誤率為 11%。這證實伺服器已成功載入並執行已訓練的模型!