机器学习应用程序正在蓬勃发展,但是数据工程师没有很多工具可以将这些强大的模型集成到生产系统中。在这里,我将讨论 tensorflow serving 如何帮助您加速在生产中交付模型。这篇博客文章是关于服务机器学习模型的 - 这是什么意思?
Serving 是训练后如何应用 ML 模型的方法 -Noah Fiedel 软件工程师致力于 tensorflow serving。
为了说明 tensorflow serving 的功能,我将逐步介绍 serving 一个对象检测模型的步骤。在我的 GitHub 上找到与本文相关的所有代码:https://github.com/fpaupier/tensorflow-serving_sidecar。
简而言之,Tensorflow Serving 使您能够无缝地为您的机器学习模型提供服务。
- 部署模型的新版本,让 tensorflow serving 优雅地完成当前请求,同时开始为新模型提供新请求。
- 另外,数据科学家可以专注于构建出色的模型,而 Ops 可以专注于构建可以为这些模型提供服务的高弹性和可扩展架构。
Part 1 — 预热: 建立一个本地的 tensorflow server
线上操作之前,最好先确保您的服务器可以在本地运行。我在这里提供了重要步骤,请在项目 readme 文件中找到更多文档。查看设置步骤,以确保您可以充分利用本教程:
- git clone https://github.com/fpaupier/t…,创建一个 python3.6.5 虚拟环境并安装 requirements.txt
- 获取 tensorflow serving 的 docker 镜像。docker pull tensorflow /serving
- 获取一个模型去 serving。我用这个,它执行对象检测 faster_rcnn_resnet101_coco
- 转到模型目录,并使用版本号重命名已保存的模型子目录,因为我们在这里进行的是 v1,因此我们将其称为 00001(必须为数字)。我们这样做是因为 tensorflow serving docker 镜像在搜索要服务的模型时会搜索以该约定命名的文件夹。
-
现在运行 tensorflow 服务
# From tensorflow-serving_sidecar/ docker run -t --rm -p 8501:8501 \ -v "$(pwd)/data/faster_rcnn_resnet101_coco_2018_01_28:/models/faster_rcnn_resnet" \ -e MODEL_NAME=faster_rcnn_resnet \ tensorflow/serving &
在继续之前,需要提到一点:
这里,我们将容器的端口和本地主机绑定在一起。因此,当我们调用 localhost:8501 时,我们实际上将调用 tensorflow 服务器。
您还注意到,我们将本地目录目录 fast_rcnn_resnet101_coco_2018_01_28(用于存储模型)与容器 / models / faster_rcnn_resnet 路径链接。
请切记,此时,saveModel.pb 仅在您的计算机上,而不在容器中。
-
执行客户端调用
# Don't forget to activate your python3.6.5 venv # From tensorflow-serving_sidecar/ python client.py --server_url "http://localhost:8501/v1/models/faster_rcnn_resnet:predict" \ --image_path "$(pwd)/object_detection/test_images/image1.jpg" \ --output_json "$(pwd)/object_detection/test_images/out_image1.json" \ --save_output_image "True" \ --label_map "$(pwd)/data/labels.pbtxt"
去检查 –output_json 指定的路径并享受结果。(可用 json 和 jpeg 输出)
太好了,既然我们的模型运行良好,就让我们将其部署在云上。
Part 2— 通过 tensorflow serving 和 kubernetes 部署你的机器学习模型
在生产环境中,您希望能够随着应用程序负载的增加而扩展。您不希望服务器不堪重负。
为了避免这个问题,您将使用 kubernetes 集群为您的 tensorflow-server 应用程序提供服务。预期的主要改进:
- 您的副本之间的负载将达到平衡,而无需再考虑它。
- 您是否要在不停机的情况下部署新模型?没问题,kubernetes 支持了您。执行滚动更新以逐步服务于您的新模型,同时优雅地终止旧模型上的当前请求。
让我们深入研究一下
首先,我们要创建一个完整的带有嵌入式对象检测模型的 docker 镜像。完成后,我们将其部署在 kubernetes 集群上。我的示例在 Google Cloud Platform 上运行。
创建一个定制的 tensorflow-serving docker image
-
将服务镜像作为守护程序运行:
docker run -d --name serving_base tensorflow/serving
-
拷贝 faster_rcnn_resnet101_coco 模型数据到容器的
models/
文件夹下。# From tensorflow-serving_sidecar/ docker cp $(pwd)/data/faster_rcnn_resnet101_coco_2018_01_28 serving_base:/models/faster_rcnn_resnet
-
commit 容器,将新的镜像保存为 serving faster_rcnn_resnet:
docker commit --change "ENV MODEL_NAME faster_rcnn_resnet" serving_base faster_rcnn_resnet_serving
注意:如果使用其他模型,请在 –change 参数中相应更改 faster_rcnn_resnet。
fast_rcnn_resnet_serving 将是我们的新的镜像。您可以通过运行 docker 镜像进行检查,您应该会看到一个新的 docker 镜像:
-
Stop serving base container
docker kill serving_base docker rm serving_base
太好了,下一步是测试我们全新的 fast_rcnn_resnet_serving 镜像。
测试定制 server
在将我们的应用程序部署到 kubernetes 之前,请确保它可以正常运行。
-
启动服务
docker run -p 8501:8501 -t faster_rcnn_resnet_serving &
注意:确保您已停止(docker stop <CONTAINER_NAME>)先前运行的服务器,否则端口 8501 可能已被绑定。
-
我们可以使用相同的客户端代码来调用服务器。
# From tensorflow-serving_sidecar/ python client.py --server_url "http://localhost:8501/v1/models/faster_rcnn_resnet:predict" \ --image_path "$(pwd)/object_detection/test_images/image1.jpg" \ --output_json "$(pwd)/object_detection/test_images/out_image2.json" \ --save_output_image "True" \ --label_map "$(pwd)/data/labels.pbtxt"
我们可以检查是否具有相同的功能。现在让我们在 kubernetes 集群上运行它。
部署我们的应用到 kubernetes
-
首先将定制的镜像推送到镜像仓库。
docker push gcr.io/tensorflow-serving-229609/faster_rcnn_resnet_serving:v0.1.0
-
创建 deployment 和 service。
通过 Kubernetes deployment 部署 fast-rcnn 推理服务。通过 Kubernetes service 和借助于外部负载均衡器实现外部访问。
使用单个副本实际上没有任何意义。我这样做是为了在免费套餐中通过。如果只有一个实例可以直接进行查询,那么进行负载平衡是没有用的。在生产设置中,使用多个副本。
我们使用示例 Kubernetes 配置 quick_rcnn_resnet_k8s.yaml 创建它们。您只需要更新要在文件中使用的 docker 镜像,将行镜像 <YOUR_FULL_IMAGE_NAME_HERE> 替换为您的实际镜像全名。
执行下面命令:
# From tensorflow-serving_sidecar/ kubectl create -f faster_rcnn_resnet_k8s.yaml
要检查部署和 Pod 的状态,请对整个部署使用 kubectl get 部署,kubectl get pod 可以监视部署的每个副本,并为该服务提供 kubectl get 服务。
一切启动和运行可能需要一段时间。服务外部 IP 地址在 LoadBalancer 入口旁边列出。您可以使用 kubectl describe service 命令进行检查:
kubectl describe service faster-rcnn-resnet-service
查询你的线上模型
最后,让我们测试一下。我们可以使用相同的客户端代码。只需用上面指定的 LoadBalancer Ingress 的 IP 地址替换 –server-url arg 中以前使用的 localhost。
# From tensorflow-serving_sidecar/
python client.py --server_url "http://34.73.137.228:8501/v1/models/faster_rcnn_resnet:predict" \
--image_path "$(pwd)/object_detection/test_images/image1.jpg" \
--output_json "$(pwd)/object_detection/test_images/out_image3.json" \
--save_output_image "True" \
--label_map "$(pwd)/data/labels.pbtxt"
结语
Tensorflow Serving 提供了一个很好的基础,您可以依靠它以极少的开销在生产中快速部署模型。
- 机器学习应用程序的容器化可用于部署,从而将操作人员和数据科学家之间的关注点分开
- 诸如 Kubernetes 之类的容器编排解决方案与 tensorflow-serving 相结合,即使对于不熟悉分布式计算的人,也可以在数分钟内部署高可用性模型。