tensorflow serving过程及线上预测碰到的一些神经网络相关问题

一.安装docker

安装教程很多,例如可参考docker官网:https://docs.docker.com/install/linux/docker-ce/centos/

# 安装yum-utils包
sudo yum install -y yum-utils
# 设置repository
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装最新的Docker
sudo yum install docker-ce docker-ce-cli containerd.io
# 启动Docker
sudo systemctl start docker
# 检查是否安装成功
sudo docker run hello-world

二.用docker安装tf-serving镜像

docker pull tensorflow/serving

三.拉取模型并启动容器

模型保存
对于自建模型,可以在训练完毕后进行保存,如下代码:
会得到一个saved_model.pb、keras_metadata.pb文件和variables文件夹

    tf.keras.models.save_model(
        model,
        "/data/project/serving/tensorflow_serving/servables/tensorflow/testdata/deepfm/{0}".format(today.strftime("%Y%m%d")),
        overwrite=True,
        include_optimizer=True,
        save_format=None,
        signatures=None,
        options=None
    )

常用docker命令

# 查看镜像
docker images

# 查看所有容器
docker ps -a

# 删除容器
docker rm 容器名称

启动容器(参数解释):
–name tfserveing:容器名称 tfserveing

-p 8502:8501:指定暴露端口,左边是启动docker的宿主机的端口(若8501被占用,可以"netstat -nap | grep 8501"查看被占用的进程;或者直接换成8502等其他端口,后续线上serving的post url 链接端口要对应更换),右边是要绑定的容器暴露的端口(8500启动 gRPC服务,在8501启动RestAPI服务)

source:宿主机上保存模型地址,同save_model函数中地址保持一致,但要删除版本号那一级,例如:/data/…/testdata/deepfm [到deepfm模型名称截止]

target:容器上模型路径,需要进入容器内部查看模型位置,例如:/models/testdata/deepfm
MODEL_NAME:指定模型名称

tensorflow/serving:latest:镜像名称 [指定latest最近版本]

–model_base_path=/models/testdata/deepfm & :指定模型基准路径。默认模型基准路径为/models/deepfm,若容器上实际模型路径target与默认不一致,需要重新指定。否则报错:Could not find base path xxxxxx for servable model

docker run --name tfserveing -p 8502:8501 --mount type=bind,source=/data/project/serving/tensorflow_serving/servables/tensorflow/testdata/deepfm,target=/models/testdata/deepfm -e MODEL_NAME=deepfm -t tensorflow/serving:latest --model_base_path=/models/testdata/deepfm &

线上serving测试
"instances"对应键值为列表类型,每个元素为字典类型,对应一个预测样本;注意post端口8502与前述宿主机端口保持一致

curl -d '{"instances": [{"cus_id": 71, "avg_price_7": 0.057, "var_price_7": 0.009},{"cus_id": 38, "avg_price": 0.092, "var_price": 0.005}]}' -X POST http://localhost:8502/v1/models/deepfm:predict

其他相关命令

# 查看模型half_plus_two的基本信息 [half_plus_two为模型名称]
curl http://localhost:8501/v1/models/half_plus_two/metadata
# 查看模型状态
curl localhost:8501/v1/models/half_plus_two

查看模型名称、输入、输出相关信息

# 进入模型所在路径
cd /data/project/serving/tensorflow_serving/servables/tensorflow/testdata/deepfm
# 查看模型详情。 2020-03-03是模型版本,一个模型可以有多个版本或者编号
saved_model_cli show --dir 2020-03-03/ --all

四.线上预测碰到的一些问题及解决过程

问题1
报错文本
"ConcatOp : Expected concatenating dimensions in the range [-1, 1), but got 1\n\t [[{{node model/concatenate_3/concat

原始相关代码

# sparse_embedding_list是由40个shape为(None, 1, 16)的向量组成
# dense_value_list是由22个shape为(None, 1)的向量组成

# (None, 1, 640)  =>  (None, 640)
sparse_dnn_input = Flatten()(tf.keras.layers.Concatenate(axis=-1)(sparse_embedding_list))
# (None, 22)  =>  (None, 22)
dense_dnn_input = Flatten()(tf.keras.layers.Concatenate(axis=-1)(dense_value_list))        

错误原因
一方面将tf.keras.layers.Concatenate函数换为tf.concat,另一方面要注意axis的取值范围为-1,0

更新后代码

# (None, 1, 640)  =>  (None, 640)
sparse_dnn_input = Flatten()(tf.concat(sparse_embedding_list,axis=-1))
# (None, 22)  =>  (None, 22)
dense_dnn_input = Flatten()(tf.concat(dense_value_list,axis=-1))

问题2.
报错文本
indices[0] = 1 is not in [0, 1)\n\t [[{{node model/linear/Tensordot/GatherV2_1
Can not squeeze dim[1], expected a dimension of 1, got 40

原始相关代码

# sparse_input的shape (None, 1, 40);dense_input 的shape (None, 22)
# kernel的shape (40, 1);kernel2的shape (22, 1)
fc1 = tf.tensordot(tf.squeeze(sparse_input, [1,]), kernel1, axes=(-1, 0))
fc2 = tf.tensordot(dense_input, kerne2, axes=(-1, 0))

错误原因
tf.tensordot函数的两个入参维度不匹配,需要先reshape为指定维度;

tf.squeeze函数不知道啥问题,不能删除 sparse_input 的中间维度为1的维度,尽量使用reshape、Flatten等函数

更新后代码

sparse_input = tf.reshape(sparse_input, [-1, sparse_input.shape[-1]])
dense_input = tf.reshape(dense_input, [-1, dense_input.shape[-1]])
fc1 = tf.tensordot(sparse_input , kernel, axes=(-1, 0))
fc2 = tf.tensordot(dense_input , kernel2, axes=(-1, 0))

参考链接:
https://stackoverflow.com/questions/65574746/tensorflow-serving-returns-400-bad-request-error

https://stackoverflow.com/questions/63895144/concatenate-two-tensorflow-datasets-into-one-dataset-element-as-shown-in-the-exa

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值