使用docker的TensorFlow Serving相关部署流程,在tensorflow的网站上演示的比较清楚链接: https://tensorflow.google.cn/tfx/serving/docker?hl=zh_cn。远程服务器的部署有几个具体细节问题在实际踩坑之后才注意到,所以在这里作为记录。目的是使用centos的一台服务器部署TensorFlow Serving并远程调用模型实现数字分类任务。
先看官方示例流程如下:
# Download the TensorFlow Serving Docker image and repo
docker pull tensorflow/serving
git clone https://github.com/tensorflow/serving
# Location of demo models
TESTDATA="$(pwd)/serving/tensorflow_serving/servables/tensorflow/testdata"
# Start TensorFlow Serving container and open the REST API port
docker run -t --rm -p 8501:8501 \
-v "$TESTDATA/saved_model_half_plus_two_cpu:/models/half_plus_two" \
-e MODEL_NAME=half_plus_two \
tensorflow/serving &
# Query the model using the predict API
curl -d '{"instances": [1.0, 2.0, 5.0]}' \
-X POST http://localhost:8501/v1/models/half_plus_two:predict
# Returns => { "predictions": [2.5, 3.0, 4.5] }
step 1:
docker安装就不提了,docker的运行需要sudo,daemon启动的问题没有记录下来,可以用下面的方法解决
systemctl status docker.service
先将tensorflow serving pull到本地:
[root@******* home]# docker pull tensorflow/serving
Using default tag: latest
latest: Pulling from tensorflow/serving
Digest: sha256:****************************************************************
Status: Image is up to date for tensorflow/serving:latest
docker.io/tensorflow/serving:latest
step 2 :git一个模型到本地,TESTDATA就是模型的位置、
step 3 : docker run创建并运行容器,模型路径在TESTDATA/saved_model_half_plus_two_cpu,映射到/models/half_plus_two位置,half_plus_two就是映射之后的模型名称,也就是后面的MODEL_NAME,之后调用的时候需要指明
step 4 :curl发起请求,端口8501,half_plus_two:predict即使用half_plus_two进行一次前向传播预测。
NOTICE:
使用scp把模型文件上传到服务器:
scp -r path/to/model root@111.111.111.11:path/in/ECS
路径结构为
└── tmp
└── numreg
└── 00000123
├── assets
├── saved_model.pb
└── variables
├── variables.data-00000-of-00002
├── variables.data-00001-of-00002
└── variables.index
numreg就是模型名,对应于上述的saved_model_half_plus_two_cpu,00000123是模型的版本号,这里需要注意路径位置的层次。
运行容器就是
docker run -t --rm -p 8501:8501 \
-v "/tmp/numreg:/models/numreg" \
-e MODEL_NAME=numreg\
tensorflow/serving &
也有其他命令可以,路径正确的话就会正常loop运行
NOTICE:远程调用需要将8501端口加入到服务器的安全组的出入站允许列表中,新建出入站规则
这时候服务器才能够就收8501端口的数据。
接下来在本地预处理好待分类的图像数据,从本地文件路径读取灰度图片,并resize归一化
image = tf.io.read_file(path) # 读取图片
image = tf.image.decode_png(image, channels=1)
image = tf.image.resize(image, [28, 28]) # H * W
image /= 255.0 # 归一化
image = tf.expand_dims(image, 0)
然后利用requests发送json数据:
data = json.dumps({"signature_name": "serving_default", "instances": image.numpy().tolist()})
# image.numpy() tensor to numpy
headers = {"content-type": "application/json"}
json_response = requests.post('http://111.111.111.111:8501/v1/models/numreg:predict', data=data, headers=headers)
predictions = json.loads(json_response.text)['predictions']
pred = np.argmax(predictions[0])
argmax得到分类结果
其他操作和官方的TFX for TensorFlow Serving一样了,暂时只想到这些。