docker
$ docker pull tensorflow/serving
docker run -it --rm -p 8500:8500 -p 8501:8501 \
-v "$ML_PATH/my_mnist_model:/models/my_mnist_model" \
-e MODEL_NAME=my_mnist_model \
tensorflow/serving
運行后我們要仔細看看日志,有沒有報錯,如果有報錯,對外8500和8501端口是不對外訪問的,但是內網可以訪問8501(即使報錯).
我們也可以使用下面命令看日志:
docker logs 容器名
2021-11-10 14:27:21.176828: W tensorflow_serving/sources/storage_path/file_system_storage_path_source.cc:268] No versions of servable my_mnist_model found under base path /models/my_mnist_model. Did you forget to name your leaf
說明沒有找到我們的模型:
我的路徑是
-v "/opt/tfmodel/mnist/saved/1:/models/my_mnist_model" \
后面去掉具體的版本號/1就可以了
-v "/opt/tfmodel/mnist/saved:/models/my_mnist_model"
上述命令需要注意:①當saved_model下有多個版本的模型時,它會自動選擇最大版本號的模型。②模型的存放路徑需要是絕對路徑。③saved_model文件夾下面一定要有版本號文件夾,模型放在版本號文件夾中,否則會報錯。
TensorFlow Serving 支持熱更新模型,其典型的模型文件夾結構如下:
/saved_model_files /1 # 版本號為1的模型文件 /assets /variables saved_model.pb ... /N # 版本號為N的模型文件 /assets /variables saved_model.pb
上面 1~N 的子文件夾代表不同版本號的模型。當指定 --model_base_path
時,只需要指定根目錄的 絕對地址 (不是相對地址)即可。例如,如果上述文件夾結構存放在 home/snowkylin
文件夾內,則 --model_base_path
應當設置為 home/snowkylin/saved_model_files
(不附帶模型版本號)。TensorFlow Serving 會自動選擇版本號最大的模型進行載入。
-it
使容器可交互(Ctrl-C 關閉),展示服務器的輸出。
--rm
停止時刪除容器。但不刪除鏡像。
-p 8500:8500
將 Docker 引擎將主機的 TCP 端口 8500 轉發到容器的 TCP 端口 8500。默認時,TF Serving 使用這個端口服務 gRPC API。
-p 8501:8501
將 Docker 引擎將主機的 TCP 端口 8501 轉發到容器的 TCP 端口 8501。默認時,TF Serving 使用這個端口服務 REST API。
-v "$ML_PATH/my_mnist_model:/models/my_mnist_model"
使主機的$ML_PATH/my_mnist_model
路徑對容器的路徑/models/mnist_model
開放。在 Windows 上,可能需要將/
替換為\
。
-e MODEL_NAME=my_mnist_model
將容器的MODEL_NAME
環境變量,讓 TF Serving 知道要服務哪個模型。默認時,它會在路徑/models
查詢,並會自動服務最新版本。
tensorflow/serving
鏡像名。
在客戶端調用以 TensorFlow Serving 部署的模型
TensorFlow Serving 支持以 gRPC 和 RESTful API 調用以 TensorFlow Serving 部署的模型。本手冊主要介紹較為通用的 RESTful API 方法。
RESTful API 以標准的 HTTP POST 方法進行交互,請求和回復均為 JSON 對象。為了調用服務器端的模型,我們在客戶端向服務器發送以下格式的請求:
服務器 URI: http://服務器地址:端口號/v1/models/模型名:predict
請求內容:
{
"signature_name": "需要調用的函數簽名(Sequential模式不需要)", "instances": 輸入數據 }
回復為:
{
"predictions": 返回值 }
ython 客戶端示例
以下示例使用 Python 的 Requests 庫 (你可能需要使用 pip install requests
安裝該庫)向本機的 TensorFlow Serving 服務器發送 MNIST 測試集的前 10 幅圖像並返回預測結果,同時與測試集的真實標簽進行比較。
import json import numpy as np import requests from zh.model.utils import MNISTLoader data_loader = MNISTLoader() data = json.dumps({ "instances": data_loader.test_data[0:3].tolist() }) headers = {"content-type": "application/json"} json_response = requests.post( 'http://localhost:8501/v1/models/MLP:predict', data=data, headers=headers) predictions = np.array(json.loads(json_response.text)['predictions']) print(np.argmax(predictions, axis=-1)) print(data_loader.test_label[0:10])
輸出:
[7 2 1 0 4 1 4 9 6 9] [7 2 1 0 4 1 4 9 5 9]
可見預測結果與真實標簽值非常接近。
(上面代碼可以簡化:
import requests
SERVER_URL = 'http://localhost:8501/v1/models/my_mnist_model:predict'
response = requests.post(SERVER_URL, data=input_data_json)
response.raise_for_status() # raise an exception in case of error
response = response.json()
)
對於自定義的 Keras 模型,在發送的數據中加入 signature_name
鍵值即可,即將上面代碼的 data
建立過程改為
data = json.dumps({ "signature_name": "call", "instances": data_loader.test_data[0:10].tolist() })
tensorflow serving熱部署
這個文件里面說了,可以自己配置模型配置文件定期檢查時間,那就是支持熱部署的。如果不指定有默認的檢查時間
- 一方面,支持多版本的熱部署(比如當前生產環境部署的是1版本的模型,訓練完成后生成一個2版本的模型,tensorflow會自動加載這個模型,停掉之前的模型)。
--model_config_file=/models/models.config \
--model_config_file_poll_wait_seconds=60
https://github.com/tensorflow/serving/blob/master/tensorflow_serving/g3doc/serving_config.md
https://www.136.la/shida/show-161983.html
https://tf.wiki/zh_hans/deployment/serving.html
https://jackiexiao.github.io/eat_tensorflow2_in_30_days/chinese/6.%E9%AB%98%E9%98%B6API/6-6,%E4%BD%BF%E7%94%A8tensorflow-serving%E9%83%A8%E7%BD%B2%E6%A8%A1%E5%9E%8B/
https://www.kancloud.cn/apachecn/hands-on-ml-2e-zh/1948582
https://blog.csdn.net/u011734144/article/details/82107610