用Python/Keras/Flask/Docker在Kubernetes上部署深度学习模型
简单到老板也可以亲自部署
这篇博文演示了如何通过Docker和Kubernetes,用Keras部署深度学习模型,并且通过Flask提供REST API服务。这个模型并不是强壮到可供生产的模型,而是给Kubernetes新手一个尝试的机会。我在Google Cloud上部署了这个模型,而且工作的很好。另外用户可以用同样的步骤重现以上功能。如果用户担心成本,Google提供了大量免费机会,这个演示基本没有花钱。
为什么用Kubernetes来做机器学习和数据科学
但是如果从数据科学角度看并没有使用Kubernetes的特殊原因。但是从部署,扩展和管理REST API方面来看,Kubernetes正在实现简易化的特性。
步骤预览
- 在Google Cloud上创建用户
- 使用Keras/Flask/Docker搭建一个REST API的机器学习模型服务
- 用Kubernetes部署上述模型
- enjoy it
步骤一:在Google Cloud上创建用户
我在Google Compute Engine上创建了一个对外提供服务的容器化深度学习模型,当然Google平台并不是必须的,只要能够安装Docker,随便选择平台模式。步骤二:用Keras创建深度学习模型
SSH登录到虚机开始建立模型。最简单方式就是点击虚机下方的SSH图标,会在浏览器中打开一个终端。sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine
2、安装最新Docker版本
sudo yum install -y yum-utils device-mapper-persistent-data lvm2 sudo yum-config-manager — add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install docker-ce
3、启动容器运行测试脚本
sudo systemctl start docker sudo docker run hello-world
以下是正确输出:
Hello from Docker! This message shows that your installation appears to be working correctly.To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal
4、创建深度学习模型
这里会借用Adrian Rosebrock的一个脚本,他提供了使用Keras的深度学习模型并通过Flask提供服务的教程,可以从 这里 访问。
这个模型可以直接执行。但是我修改了两个配置信息:
首先,改变了容器配置,默认flask使用127.0.0....作为默认服务地址,这会在容器内部运行时出现问题。我将它修改成0.0.0.0,这样就可以实现对外和对内都可以工作的IP地址。
第二是关于Tensorflow的配置,可以从GitHub中找到这个 问题描述 。
global graph graph = tf.get_default_graph() ... with graph.as_default(): preds = model.predict(image)
运行脚本,首先创建专用目录:
mkdir keras-app cd keras-app
创建app.py文件:
vim app.py
# USAGE
Start the server:
python app.py
Submit a request via cURL:
curl -X POST -F image=@dog.jpg 'http://localhost:5000/predict'
import the necessary packages
from keras.applications import ResNet50 from keras.preprocessing.image import img_to_array from keras.applications import imagenet_utils from PIL import Image import numpy as np import flask import io import tensorflow as tfinitialize our Flask application and the Keras model
app = flask.Flask(__name__) model = None def load_model(): # load the pre-trained Keras model (here we are using a model # pre-trained on ImageNet and provided by Keras, but you can # substitute in your own networks just as easily) global model model = ResNet50(weights="imagenet") global graph graph = tf.get_default_graph() def prepare_image(image, target): # if the image mode is not RGB, convert it if image.mode != "RGB": image = image.convert("RGB") # resize the input image and preprocess it image = image.resize(target) image = img_to_array(image) image = np.expand_dims(image, axis=0) image = imagenet_utils.preprocess_input(image) # return the processed image return image @app.route("/predict", methods=["POST"]) def predict(): # initialize the data dictionary that will be returned from the # view data = {"success": False} # ensure an image was properly uploaded to our endpoint if flask.request.method == "POST": if flask.request.files.get("image"): # read the image in PIL format image = flask.request.files["image"].read() image = Image.open(io.BytesIO(image)) # preprocess the image and prepare it for classification image = prepare_image(image, target=(224, 224)) # classify the input image and then initialize the list # of predictions to return to the client with graph.as_default(): preds = model.predict(image) results = imagenet_utils.decode_predictions(preds) data["predictions"] = [] # loop over the results and add them to the list of # returned predictions for (imagenetID, label, prob) in results[0]: r = {"label": label, "probability": float(prob)} data["predictions"].append(r) # indicate that the request was a success data["success"] = True # return the data dictionary as a JSON response return flask.jsonify(data)if this is the main thread of execution first load the model and
then start the server
if __name__ == "__main__": print(("* Loading Keras model and Flask starting server..." "please wait until server has fully started")) load_model() app.run(host='0.0.0.0')5、创建requirements.txt文件
为了在容器内运行代码,需要创建requirements.txt文件,其中包括需要运行的包,例如keras、flask、一起其它相关包。这样无论在哪里运行代码,依赖包都保持一致。
keras tensorflow flask gevent pillow requests
6、创建Dockerfile
FROM python:3.6 WORKDIR /app COPY requirements.txt /app RUN pip install -r ./requirements.txt COPY app.py /app CMD ["python", "app.py"]~
首先让容器自行下载Python 3安装image,然后让Python调用pip安装requirements.txt中的依赖包,最后运行python app.py。
7、创建容器
sudo docker build -t keras-app:latest .
在keras-app目录下创建容器,后台开始安装Python 3 image等在步骤6中定义的操作。
8、运行容器
sudo docker run -d -p 5000:5000 keras-app
用
sudo docker ps -a
检查容器状态,应该看到如下输出: [gustafcavanaugh@instance-3 ~]$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d82f65802166 keras-app "python app.py" About an hour ago Up About an hour 0.0.0.0:5000->5000/tcp nervous_northcutt
9、测试模型
现在可以测试此模型。用狗的照片作为输入,可以返回狗的品种。在Adrian的示例中都有 详细代码和图片 ,我们也使用它们,并保存自工作目录下,命名为dog.jpg。
curl -X POST -F image=@dog.jpg 'http://localhost:5000/predict'
应该得到如下输出:
{"predictions":[{"label":"beagle","probability":0.987775444984436},{"label":"pot","probability":0.0020967808086425066},{"label":"Cardigan","probability":0.001351703773252666},{"label":"Walker_hound","probability":0.0012711131712421775},{"label":"Brittany_spaniel","probability":0.0010085132671520114}],"success":true}
可以看到此模型成功将狗归类为比格犬。下一步,我们用Kubernetes部署容器模型。
第三步:用Kubernetes部署模型
1、创建Docker Hub账号第一步需要在 Docker hub 上传模型,以便使用Kubernetes集中管理。
2、登录到Docker Hub
sudo docker login
, 登录到Docker Hub,应该看到如下输出: Login Succeeded
3、给容器打标签
给模型容器命名,上传前先给它打标签。
sudo docker images
,应该得到容器的id,输出如下: REPOSITORY TAG IMAGE ID CREATED SIZE keras-app latest ddb507b8a017 About an hour ago 1.61GB
打标签命令如下:
#Format sudo docker tag <your image id> <your docker hub id>/<app name>
My Exact Command - Make Sure To Use Your Inputs
sudo docker tag ddb507b8a017 gcav66/keras-app4、将模型容器上传到Docker Hub
运行命令如下:
#Format sudo docker push <your docker hub name>/<app-name>
My exact command
sudo docker push gcav66/keras-app5、创建Kubernetes集群
在Google Cloud Home界面,选择Kubernetes Engine。
kubectl run keras-app --image=gcav66/keras-app --port 5000
确认是否Pod正确运行
kubectl get pods
,输出如下: gustafcavanaugh@cloudshell:~ (basic-web-app-test)$ kubectl get pods NAME READY STATUS RESTARTS AGE keras-app-79568b5f57-5qxqk 1/1 Running 0 1m
为了安全起见,将服务端口暴露与80端口:
kubectl expose deployment keras-app --type=LoadBalancer --port 80 --target-port 5000
确认服务正常启动:
kubectl get service
,正常输出如下: gustafcavanaugh@cloudshell:~ (basic-web-app-test)$ kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE keras-app LoadBalancer 10.11.250.71 35.225.226.94 80:30271/TCP 4m kubernetes ClusterIP 10.11.240.1 <none> 443/TCP 18m
提取cluster-IP,并将其合并于服务提交命令:
curl -X POST -F image=@dog.jpg 'http://<your service IP>/predict'
,得到正常输入如下: $ curl -X POST -F image=@dog.jpg 'http://35.225.226.94/predict' {"predictions":[{"label":"beagle","probability":0.987775444984436},{"label":"pot","probability":0.0020967808086425066},{"label":"Cardigan","probability":0.001351703773252666},{"label":"Walker_hound","probability":0.0012711131712421775},{"label":"Brittany_spaniel","probability":0.0010085132671520114}],"success":true}
第四步:总结
本文提供了一个使用Keras和Flask提供REST API服务的深度学习模型,并把它集成到容器内部,上传到Docker Hub,并用Kubernetes部署,非常容易地实现了对外提供服务和访问。现在,我们可以对这个项目进行很多改进。对于初学者,可以改变本地Python服务到更加强壮的gunicorn;可以横向扩展Kubernetes,实现服务扩容;也可以从头搭建一套Kubernetes环境。
本文转自DockOne-用Python/Keras/Flask/Docker在Kubernetes上部署深度学习模型
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
如何在Kubernetes上扩展MongoDB?
Kubernetes主要用于无状态应用程序。 但是,在1.3版本中引入了PetSets,之后它们演变为StatefulSets。 官方文档将StatefulSets描述为“StatefulSets旨在与有状态应用程序和分布式系统一起使用”。 对此最好的用例之一是对数据存储服务进行编排,例如MongoDB,ElasticSearch,Redis,ZooKeeper等。 我们可以把StatefulSets的特性归纳如下: 有序索引Pod 稳定的网络ID 有序并行的Pod管理 滚动更新 这些细节可以在 这里 找到。 StatefulSets的一个非常明显的特征是提供稳定网络ID,与 Headless Services 一起使用时,功能可以更加强大。 我们在Kubernetes文档中随时可以查看的信息上不会花费很多时间,让我们专注于运行和扩展MongoDB集群。 你需要一个可以运行的Kubernetes群集并启用RBAC(推荐)。 在本教程中,我将使用GKE集群,但是,AWS EKS或Microsoft的AKS或Kops管理的Kubernetes也是可行的替代方案。 我们将为MongoDB集群...
- 下一篇
如何测试Kubernetes RBAC?
建设Kubernetes集群的安全是一回事,而维护它也会越来越困难。幸运的是,Kubernetes引入的新特性使这两件事都变得容易起来。 Kubernetes(从1.6版本)引入了基于角色的访问控制(RBAC),允许系统管理员定义策略来限制集群使用者的行为。这意外着创建有限访问权限的用户是可能的。它允许你限制如Secrets等资源的访问,或限制用户对某个命名空间的访问。 本文不会介绍如何实现RBAC,因为它已经有很多不错的详实的资料: https://medium.com/containerum ... 17d5d https://www.cncf.io/blog/2018/ ... etes/ https://docs.bitnami.com/kuber ... ster/ https://kubernetes.io/docs/ref ... rbac/ 本文将聚集于怎样使你业务的合规性和需求得到切实满足。为此,我们需要测试被应用的RBAC对象,以确保它们像我们期望地那样工作。 我们的场景 某个组织有多组团队的人员,刚开始上手使用Kubernetes集群。这时要求一个团队不能去修改另...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Red5直播服务器,属于Java语言的直播服务器