Google近日3月23-24日在美国旧金山举办首次谷歌云平台(Google Cloud Platform) GCP NEXT大会,参会人数超过2000人。GCP NEXT大会以机器学习、资料中心和云端安全为主要议题,为未来GCP发展做战略规划。
其中,关于机器学习,谷歌发布了云端机器学习平台(Cloud Machine Learning),为开发者和企业用户提供一整套包含视听及翻译的应用API,例如Cloud Translate API和Cloud Vision API。除了machine learning,谷歌去年就推出了机器学习开放原始码平台TensorFlow,鼓励开发者利用该平台来开发创新应用服务。现在TensorFlow和Kubernetes相结合,将建立更为强大的机器学习模型,扩充功能,开启人工智能机器学习在谷歌云端的新纪元。
在2011年,谷歌开发了一个内部深度学习基础设施叫做“DistBelief”,这个设施允许谷歌人创建更大的神经网络和扩容实训成千上万个核心。最近几年,谷歌引进了TensorFlow,也就是它的二代机器学习系统。TensorFlow的特点是通用,灵活的,便携的,易于使用,最重要的是,它是使用开源社区开发的。
将机器学习引入到你的产品的过程包括创建和训练数据集模型。
引入机器学习到你的产品这个过程涉及到创建和训练模型在你的数据集上,然后push模型到生产过程来提供请求。在这篇博客中,我们将会展示给你们如何通过TensorFlow使用Kubernetes,TensorFlow是一个高性能,满足应用程序的扩展需求,为机器学习模型提供开源服务系统。
现在让我们以镜像作为例子。假设你的应用程序需要能够在一系列类别中正确的识别一个镜像。比如,给出下面这个可爱的小狗图,你的系统应该将它归类到猎犬这一类。
你可以通过TensorFlow使用从ImageNet数据集上面trained的Inception-v3模型,来实现图像分类。这个数据集包含图片和标签,允许TensorFlow学习者train一个模型,该模型可以被用在生产过程中。
一旦模型被训练和输出,TensorFlow服务使用该模型来进行推理——基于客户提供的新数据的预言。在我们的例子中,客户在gRPC请求提交镜像分类,gRPC是一个来自谷歌的高性能,开源RPC的框架。
推理可以是十分资源密集型的。我们的服务器执行以下TensorFlow来处理它接收到的每一个分类的要求。Inception-v3模型有超过2700万个参数,每次运算推理(inference)运行57亿浮点。
幸运地,这就是Kubernetes可以帮助到我们的地方。Kubernetes分布推断请求处理跨集群使用外部负载均衡器。集群中的每个pod都包含一个TensorFlow服务于Docker镜像,还有TensorFlow服务为基础的gRPC服务器,以及一个trained的Inception-v3模型。这个模型以文件集描述TensorFlow图的形式呈现,模型权重,资产等等。既然所有东西都是整齐的打包好放到一起,那么我们就可以使用Kubernetes Replication Controller动态的扩展复制pods,以此来跟上服务要求。
为了帮助你自己试一试,我们写了一个tutorial教程,它展示了如何创建TensorFlow服务Docker容器来给Inception-v3镜像分类模型提供服务,安装Kubernetes集群,并且应对该集群运行分类请求。我们希望这个教程能够让你更加容易地去整合机器学习到你自己的程序上,以及用Kubernetes扩大规模。学习更多关于TensorFlow,请看下文补充:
这个tutorial展示了如何使用TensorFlow Serving组件在容器里面的运用,以此来服务TensorFlow模型,还展示了如何用Kubernetes配置服务中的集群。
为了解更多关于TensorFlow服务的信息,我们推荐《TensorFlow服务初级教程》和《TensorFlow服务教程》。
为了解更多关于TensorFlow Inception模型,我们推荐《Inception in TensorFlow》。
Part0 展示的是怎样为配置创建一个TensorFlow服务Docker
Part1 展示的是如何在本地容器运行镜像
Part2 展示了如何在kubernetes上配置
请参考《通过Docker使用TensorFlow服务》来了解创建过程中的更多细节。
我们使用Dockerfile.devel来创建一个基底镜像 $USER/tensorflow-serving-devel
,然后使用创建好的镜像来启动本地容器。
$ docker build -t $USER/tensorflow-serving-devel -f tensorflow_serving/tools/docker/Dockerfile.devel .$ docker run --name=inception_container -it $USER/tensorflow-serving-devel
在运行的容器中,我们克隆,配置以及创建TensorFlow服务。然后测试运行 inception_inference(网址: 点击 )
root@c97d8e820ced:/# git clone --recurse-submodules https://github.com/tensorflow/servingroot@c97d8e820ced:/# cd serving/tensorflowroot@c97d8e820ced:/serving/tensorflow# ./configureroot@c97d8e820ced:/serving# cd ..root@c97d8e820ced:/serving# bazel build -c opt tensorflow_serving/...root@c97d8e820ced:/serving# ls AUTHORS LICENSE RELEASE.md bazel-bin bazel-out bazel-testlogs tensorflow zlib.BUILD CONTRIBUTING.md README.md WORKSPACE bazel-genfiles bazel-serving grpc tensorflow_servingroot@c97d8e820ced:/serving# bazel-bin/tensorflow_serving/example/inception_inference E tensorflow_serving/example/inception_inference.cc:362] Usage: inception_inference --port=9000 /path/to/exports
在容器中,我们运行inception_export.py( 点击 )使用发布的Inception model training checkpoint( 点击 )来出口inception模型。我们使用训练有素的现成的动态检查点来恢复直接推理,并且直接输出它。
root@c97d8e820ced:/serving# curl -O http://download.tensorflow.org/models/image/imagenet/inception-v3-2016-03-01.tar.gzroot@c97d8e820ced:/serving# tar xzf inception-v3-2016-03-01.tar.gzroot@c97d8e820ced:/serving# ls inception-v3 README.txt checkpoint model.ckpt-157585root@c97d8e820ced:/serving# bazel-bin/tensorflow_serving/example/inception_export --checkpoint_dir=inception-v3 --export_dir=inception-export Successfully loaded model from inception-v3/model.ckpt-157585 at step=157585. Successfully exported model to inception-exportroot@c97d8e820ced:/serving# ls inception-export 00157585root@c97d8e820ced:/serving# [Ctrl-p] + [Ctrl-q]
注意我们从上述指令的容器中分离出来而不是终止它,因为我们想要为Kubernetes配置提交所有的修改到新的镜像 $USER/inception_serving
。
$ docker commit inception_container $USER/inception_serving$ docker stop inception_container
让我们在本地用创建的镜像测试一下服务流程。
$ docker run -it $USER/inception_serving
开启服务器
在容器中运行gRPC服务器
root@f07eec53fd95:/# cd servingroot@f07eec53fd95:/serving# bazel-bin/tensorflow_serving/example/inception_inference --port=9000 inception-export &> inception_log &[1] 45
查询服务器
用inception_client.py.( 点击 )。客户端通过gRPC用一个命令行参数发送一个指定的镜像到服务器。然后查找ImageNet同义词集合和元数据文件,并且返回到人类可读的分类。
root@f07eec53fd95:/serving# bazel-bin/tensorflow_serving/example/inception_client --server=localhost:9000 --image=/path/to/my_cat_image.jpg 8.976576 : tabby, tabby cat 8.725506 : Egyptian cat 6.883981 : tiger cat 2.659257 : lynx, catamount 2.028728 : window screenroot@f07eec53fd95:/serving# exit
它运行起来了!服务器成功地分类了你的cat镜像!
在这一节里,我们使用Part0中创建的容器镜像来配置一个服务集群,用的是Google Cloud Platform中的Kubernetes。
Cloud项目登录
这里我们假设你已经创建并且已经登陆了名 “ tensorflow-serving”gcloud
项目。
$ gcloud auth login --project tensorflow-serving
创建一个容器集群
首先,我们为服务配置创建一个Google Container Engine集群。
$ gcloud container clusters create inception-serving-cluster --num-nodes 5 Creating cluster inception-serving-cluster...done. Created [https://container.googleapis.com/v1/projects/tensorflow-serving/zones/us-central1-f/clusters/inception-serving-cluster]. kubeconfig entry generated for inception-serving-cluster. NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS inception-serving-cluster us-central1-f 1.1.8 104.197.163.119 n1-standard-1 1.1.8 5 RUNNING
为gcloud容器命令设置默认集群,并且发送集群凭证到kubectl。
$ gcloud config set container/cluster inception-serving-cluster$ gcloud container clusters get-credentials inception-serving-cluster Fetching cluster endpoint and auth data. kubeconfig entry generated for inception-serving-cluster.
上传Docker镜像
现在让我们来把我们的镜像push到[Google Container Registry]( https://cloud.google.com/container-regis... ),这样我们就可以在Google Cloud Platform上面运行了。
首先,我们给 $USER/inception_serving
镜像贴上标签,用Container Registry格式以及我们的项目名称,
$ docker tag $USER/inception_serving gcr.io/tensorflow-serving/inception
下面我们push镜像到Registry,
$ gcloud docker push gcr.io/tensorflow-serving/inception
创建Kubernetes ReplicationController 和服务配置包括不同的副本inception_inference 被一个kubernetes Replication Controller服务器控制。副本是由Kubernetes以及外部负载均衡起暴露在外部的。
我们使用那个Kubernetes公式inception_k8s.json的例子创建他们。
$ kubectl create -f tensorflow_serving/example/inception_k8s.json replicationcontroller "inception-controller" created service "inception-service" created
来看一下副本控制器和pods:
$ kubectl get rc CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS AGE inception-controller inception-container gcr.io/tensorflow-serving/inception worker=inception-pod 3 20s $ kubectl get pod NAME READY STATUS RESTARTS AGE inception-controller-bbcbc 1/1 Running 0 1m inception-controller-cj6l2 1/1 Running 0 1m inception-controller-t1uep 1/1 Running 0 1m
来看一下服务的状态:
$ kubectl get svc NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE inception-service 10.15.242.244 146.148.88.232 9000/TCP worker=inception-pod 3m kubernetes 10.15.240.1 <none> 443/TCP <none> 1h $ kubectl describe svc inception-service Name: inception-service Namespace: default Labels: <none> Selector: worker=inception-pod Type: LoadBalancer IP: 10.15.242.244 LoadBalancer Ingress: 146.148.88.232 Port: <unnamed> 9000/TCP NodePort: <unnamed> 32006/TCP Endpoints: 10.12.2.4:9000,10.12.4.4:9000,10.12.4.5:9000 Session Affinity: None Events: FirstSeen LastSeen Count From SubobjectPath Reason Message ───────── ──────── ───── ──── ───────────── ────── ─────── 4m 3m 2 {service-controller } CreatingLoadBalancer Creating load balancer 3m 2m 2 {service-controller } CreatedLoadBalancer Created load balancer
任何东西上传或者运行都需要时间。服务的外部IP地址就在LoadBalancer旁边被列出来。
查询模型
我们现在可以从我们的本地主机外部地址查询服务。
$ bazel-bin/tensorflow_serving/example/inception_client --server=146.148.88.232:9000 --image=/path/to/my_cat_image.jpg 8.976576 : tabby, tabby cat 8.725506 : Egyptian cat 6.883981 : tiger cat 2.659257 : lynx, catamount 2.028728 : window screen
你已经在Kubernetes里成功部署了inception服务。
原文在这里