このチュートリアルでは、Docker コンテナーで実行されている TensorFlow Serving コンポーネントを使用して TensorFlow ResNet モデルにサービスを提供する方法と、Kubernetes を使用してサービング クラスターをデプロイする方法を示します。
TensorFlow Serving の詳細については、 TensorFlow Serving の基本チュートリアルとTensorFlow Serving の高度なチュートリアルをお勧めします。
TensorFlow ResNet モデルの詳細については、 「TensorFlow の ResNet」を読むことをお勧めします。
- パート 1 では環境をセットアップします
- パート 2 では、ローカルの Docker サービス イメージを実行する方法を示します。
- パート 3 では、 Kubernetes にデプロイする方法を示します。
パート 1: セットアップ
始める前に、まずDocker をインストールします。
ResNet SavedModel をダウンロードする
すでにローカル モデル ディレクトリがある場合に備えて、それをクリアしましょう。
rm -rf /tmp/resnet
ディープ残差ネットワーク (略して ResNet) は、非常に深い畳み込みニューラル ネットワークのトレーニングを可能にするアイデンティティ マッピングの画期的なアイデアを提供しました。この例では、ImageNet データセット用の ResNet の TensorFlow SavedModel をダウンロードします。
# Download Resnet model from TF Hub
wget https://tfhub.dev/tensorflow/resnet_50/classification/1?tf-hub-format=compressed -o resnet.tar.gz
# Extract SavedModel into a versioned subfolder ‘123’
mkdir -p /tmp/resnet/123
tar xvfz resnet.tar.gz -C /tmp/resnet/123/
SavedModel があることを確認できます。
$ ls /tmp/resnet/*
saved_model.pb variables
パート 2: Docker での実行
デプロイメント用のイメージをコミットする
次に、提供イメージを取得し、Kubernetes デプロイメント用の新しいイメージ$USER/resnet_serving
にすべての変更をコミットします。
まず、サービス提供イメージをデーモンとして実行します。
docker run -d --name serving_base tensorflow/serving
次に、ResNet モデル データをコンテナーのモデル フォルダーにコピーします。
docker cp /tmp/resnet serving_base:/models/resnet
最後に、ResNet モデルを提供するためにコンテナーをコミットします。
docker commit --change "ENV MODEL_NAME resnet" serving_base \
$USER/resnet_serving
次に、サービングベースコンテナを停止しましょう
docker kill serving_base
docker rm serving_base
サーバーを起動します
次に、ResNet モデルを使用してコンテナーを起動して、gRPC ポート 8500 を公開して提供できるようにしましょう。
docker run -p 8500:8500 -t $USER/resnet_serving &
サーバーに問い合わせる
クライアントの場合は、TensorFlow Serving GitHub リポジトリのクローンを作成する必要があります。
git clone https://github.com/tensorflow/serving
cd serving
resnet_client_grpc.pyを使用してサーバーにクエリを実行します。クライアントはイメージをダウンロードし、それをImageNetカテゴリに分類するために gRPC 経由で送信します。
tools/run_in_docker.sh python tensorflow_serving/example/resnet_client_grpc.py
これにより、次のような出力が得られます。
outputs {
key: "classes"
value {
dtype: DT_INT64
tensor_shape {
dim {
size: 1
}
}
int64_val: 286
}
}
outputs {
key: "probabilities"
value {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 1
}
dim {
size: 1001
}
}
float_val: 2.41628322328e-06
float_val: 1.90121829746e-06
float_val: 2.72477100225e-05
float_val: 4.42638565801e-07
float_val: 8.98362372936e-07
float_val: 6.84421956976e-06
float_val: 1.66555237229e-05
...
float_val: 1.59407863976e-06
float_val: 1.2315689446e-06
float_val: 1.17812135159e-06
float_val: 1.46365800902e-05
float_val: 5.81210713335e-07
float_val: 6.59980651108e-05
float_val: 0.00129527016543
}
}
model_spec {
name: "resnet"
version {
value: 123
}
signature_name: "serving_default"
}
それは動作します!サーバーは猫の画像を正常に分類しました。
パート 3: Kubernetes でのデプロイ
このセクションでは、パート 0 で構築されたコンテナ イメージを使用して、 Google Cloud PlatformにKubernetesを備えたサービング クラスタをデプロイします。
GCloud プロジェクトへのログイン
ここでは、 tensorflow-serving
という名前のgcloudプロジェクトを作成し、ログインしていると仮定します。
gcloud auth login --project tensorflow-serving
コンテナクラスターを作成する
まず、サービスをデプロイするためのGoogle Kubernetes Engineクラスターを作成します。
$ gcloud container clusters create resnet-serving-cluster --num-nodes 5
次のような出力が得られます。
Creating cluster resnet-serving-cluster...done.
Created [https://container.googleapis.com/v1/projects/tensorflow-serving/zones/us-central1-f/clusters/resnet-serving-cluster].
kubeconfig entry generated for resnet-serving-cluster.
NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
resnet-serving-cluster us-central1-f 1.1.8 104.197.163.119 n1-standard-1 1.1.8 5 RUNNING
gcloudcontainer コマンドのデフォルトのクラスターを設定し、クラスターの認証情報をkubectlに渡します。
gcloud config set container/cluster resnet-serving-cluster
gcloud container clusters get-credentials resnet-serving-cluster
その結果、次のようになります。
Fetching cluster endpoint and auth data.
kubeconfig entry generated for resnet-serving-cluster.
Dockerイメージをアップロードする
次に、イメージをGoogle Container Registryにプッシュして、Google Cloud Platform で実行できるようにしましょう。
まず、Container Registry 形式とプロジェクト名を使用して$USER/resnet_serving
イメージにタグを付けます。
docker tag $USER/resnet_serving gcr.io/tensorflow-serving/resnet
次に、gcloud を認証ヘルパーとして使用するように Docker を構成します。
gcloud auth configure-docker
次に、イメージをレジストリにプッシュします。
docker push gcr.io/tensorflow-serving/resnet
Kubernetesのデプロイメントとサービスを作成する
このデプロイメントは、 Kubernetes デプロイメントによって制御されるresnet_inference
サーバーの 3 つのレプリカで構成されます。レプリカは、外部ロード バランサーとともにKubernetes サービスによって外部に公開されます。
Kubernetes 構成例resnet_k8s.yamlを使用してそれらを作成します。
kubectl create -f tensorflow_serving/example/resnet_k8s.yaml
出力あり:
deployment "resnet-deployment" created
service "resnet-service" created
デプロイメントとポッドのステータスを表示するには:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
resnet-deployment 3 3 3 3 5s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
resnet-deployment-bbcbc 1/1 Running 0 10s
resnet-deployment-cj6l2 1/1 Running 0 10s
resnet-deployment-t1uep 1/1 Running 0 10s
サービスのステータスを表示するには:
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
resnet-service 10.239.240.227 104.155.184.157 8500/TCP 1m
すべてが稼働するまでには時間がかかる場合があります。
$ kubectl describe service resnet-service
Name: resnet-service
Namespace: default
Labels: run=resnet-service
Selector: run=resnet-service
Type: LoadBalancer
IP: 10.239.240.227
LoadBalancer Ingress: 104.155.184.157
Port: <unset> 8500/TCP
NodePort: <unset> 30334/TCP
Endpoints: <none>
Session Affinity: None
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 1m 1 {service-controller } Normal CreatingLoadBalancer Creating load balancer
1m 1m 1 {service-controller } Normal CreatedLoadBalancer Created load balancer
サービスの外部 IP アドレスは、LoadBalancer Ingress の横にリストされます。
モデルをクエリする
これで、ローカル ホストから外部アドレスでサービスにクエリを実行できるようになりました。
$ tools/run_in_docker.sh python \
tensorflow_serving/example/resnet_client_grpc.py \
--server=104.155.184.157:8500
outputs {
key: "classes"
value {
dtype: DT_INT64
tensor_shape {
dim {
size: 1
}
}
int64_val: 286
}
}
outputs {
key: "probabilities"
value {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 1
}
dim {
size: 1001
}
}
float_val: 2.41628322328e-06
float_val: 1.90121829746e-06
float_val: 2.72477100225e-05
float_val: 4.42638565801e-07
float_val: 8.98362372936e-07
float_val: 6.84421956976e-06
float_val: 1.66555237229e-05
...
float_val: 1.59407863976e-06
float_val: 1.2315689446e-06
float_val: 1.17812135159e-06
float_val: 1.46365800902e-05
float_val: 5.81210713335e-07
float_val: 6.59980651108e-05
float_val: 0.00129527016543
}
}
model_spec {
name: "resnet"
version {
value: 1538687457
}
signature_name: "serving_default"
}
Kubernetes でサービスとして機能する ResNet モデルが正常にデプロイされました。