nikkie-ftnextの日記

イベントレポートや読書メモを発信

週末ログ | GKEでKFServingを使ってPyTorchのモデルをサーブを試しハマりました(前編:GKE環境構築)

はじめに

頑張れば、何かがあるって、信じてる。nikkieです。
自然言語処理ネタで週1ブログは完結したので、気の向くまま不定期にブログを書いていきます。

今回は週末に手を動かしたことをまとめます。
うまくいっていない😢(悔しくて死にそう)のですが、記録に残します。
調査事項や工夫点を探して見返すことで次に繋げられたらと考えています。

目次

取り組んだこと

PyTorchのモデルをKFServingでサーブするサンプルに沿って手を動かしました(KFServingが何かは追って説明します)。

サーブする環境にはGCPを選択しました。
GCPのGKEを利用し、Kubernetes(以降、k8sクラスタを用意し、KFServingが使えるようにして進めています。

KFServingとは

KFServingとKubeflow

タイトルにあるKFServingは、k8s機械学習をするツールKubeflow1コンポーネント2の1つです(執筆時点でBeta版です)。
KFServingはその名の通りモデルのサーブ(=モデルをAPIにして予測結果を利用可能にする)に関係します3
複数の機械学習フレームワークのモデルに対応しており、今回はPyTorch製モデルのサーブを試しました。

Kubeflowの全容を掴むには、ドキュメント4にあった以下の図が分かりやすいです。
元の図:https://www.kubeflow.org/docs/images/kubeflow-overview-workflow-diagram-2.svg

f:id:nikkie-ftnext:20200412235349p:plain

この図によれば、KFServingの用途はProduction(本番環境)でのモデルのサーブです。

KFServingの依存要素

KFServingを動かすには、k8s以外にも必要なものが2つあります。
それが、

  • Knative、特にKnative Serving5(Knativeをざっくりいうとk8sでサーバレス?)
  • Istio(マイクロサービスにおけるサービスメッシュ?なるもの)

です6
ドキュメント7に分かりやすい図がありました。
元の図:https://www.kubeflow.org/docs/components/serving/kfserving.png

f:id:nikkie-ftnext:20200412235113p:plain

やったこと

依存要素を揃えてKFServingが使える環境を用意したあと、PyTorchのモデルを用意し、KFServingでサーブできるか手を動かしました。

  1. KFServingが使える環境を用意する
    1. GKE
    2. Knative
    3. Istio
    4. KFServing
  2. PyTorchのモデルを用意する
  3. KFServingでサーブを試す
    1. ローカルでサーブする
    2. GKEでサーブする

結論を言えば、3-2で動いていません。
1の環境構築に不備があったと考えています。

動作環境

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.6
BuildVersion:   18G3020
$ gcloud version
Google Cloud SDK 288.0.0
beta 2019.05.17
bq 2.0.56
core 2020.04.03
gsutil 4.49
kubectl 2020.02.07
$ kubectl version  # gcloud components install kubectl で入ったもの(GKEのクラスタ作成後に確認)
Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.9", GitCommit:"2e808b7cb054ee242b68e62455323aa783991f03", GitTreeState:"clean", BuildDate:"2020-01-18T23:33:14Z", GoVersion:"go1.12.12", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"15+", GitVersion:"v1.15.11-gke.5", GitCommit:"a5bf731ea129336a3cf32c3375317b3a626919d7", GitTreeState:"clean", BuildDate:"2020-03-31T02:49:49Z", GoVersion:"go1.12.17b4", Compiler:"gc", Platform:"linux/amd64"}

1. KFServingが使える環境を用意する

1-1 GKEでk8sクラスタを構築する

KnativeのドキュメントにあったGKEの環境構築を進めていきます。

  1. まずGCPのプロジェクトを作成
  2. 1のプロジェクトの中にGKEのクラスタを作成
$ gcloud components install kubectl
$ gcloud auth login

$ export CLUSTER_NAME=knative
$ export CLUSTER_ZONE=asia-northeast1-c  # 東京
$ export PROJECT=nikkie-knative-project

$ gcloud projects create $PROJECT --set-as-default

コマンドラインからプロジェクトを作りました。
gcloud config get-value core/projectで確認すると、作ったプロジェクトがデフォルトとして設定されています。

プロジェクトを作ったあとは請求先を設定する必要がありました8(請求先がないと続くコマンドがエラーになります)。

クラスタの作成です。

$ gcloud beta container clusters create $CLUSTER_NAME \
  --addons=HorizontalPodAutoscaling,HttpLoadBalancing \  # Istioを外した
  --machine-type=n1-standard-4 \
  --cluster-version=latest --zone=$CLUSTER_ZONE \
  --enable-stackdriver-kubernetes --enable-ip-alias \
  --enable-autoscaling --min-nodes=1 --max-nodes=10 \
  --enable-autorepair \
  --scopes cloud-platform

gcloudコマンドのbetaコンポーネントをインストールしていなかったため、インストールしてからクラスタ作成と進みました。

クラスタの作成コマンド9は、以下の記事(☆)を参照し、Istio addonを入れないように変更しています。

東京Zoneのn1-standard-4タイプのGCEインスタンスの料金は1時間あたり$0.2440です10💸

# gcloud beta container clusters create の出力の一部です
kubeconfig entry generated for knative.
NAME     LOCATION           MASTER_VERSION  MASTER_IP       MACHINE_TYPE   NODE_VERSION   NUM_NODES  STATUS
knative  asia-northeast1-c  1.15.11-gke.5   104.198.88.245  n1-standard-4  1.15.11-gke.5  3          RUNNING

$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value core/account)

出力1行目にあるように、作成したクラスタへの接続情報が.kube/configkubectl--kubeconfig引数のデフォルトの値)に書かれています (なお、課金を止めるためにリソースは削除済みです)。

1-2 k8sクラスタにKnativeをインストール

k8s クラスタは v1.15以上なので、Knative v0.13.0 を入れるドキュメントにスイッチしました。
KFServingが依存する Knative Servingのみ インストールしています。

$ kubectl apply --filename https://github.com/knative/serving/releases/download/v0.13.0/serving-crds.yaml
$ kubectl apply --filename https://github.com/knative/serving/releases/download/v0.13.0/serving-core.yaml

CRD (Custom Resource Definition)からapplyする手順はこの後も頻出です。

1-3 k8sクラスタにIstioをインストール

1-2で参照したドキュメントの続きを進めます(3.Pick a networking layer の部分)。

Istioのインストールは、クラスタ作成時にIstio Addonを入れないようにしたMedium記事(☆)を参考に読み替えます11

$ export ISTIO_VERSION=1.4.6
$ kubectl apply -f https://raw.githubusercontent.com/knative/serving/master/third_party/istio-${ISTIO_VERSION}/istio-crds.yaml
$ kubectl apply -f https://raw.githubusercontent.com/knative/serving/master/third_party/istio-${ISTIO_VERSION}/istio-minimal.yaml

1-2で参照にしたドキュメントに戻って進めます。

$ kubectl apply --filename https://github.com/knative/serving/releases/download/v0.13.0/serving-istio.yaml

$ kubectl --namespace istio-system get service istio-ingressgateway
NAME                   TYPE           CLUSTER-IP   EXTERNAL-IP     PORT(S)                                      AGE
istio-ingressgateway   LoadBalancer   10.0.5.145   35.243.114.23   15020:32112/TCP,80:31674/TCP,443:30741/TCP   2m19s
$ kubectl --namespace knative-serving get pods
NAME                                READY   STATUS    RESTARTS   AGE
activator-869f6d4f9f-vht4h          1/1     Running   0          7m48s
autoscaler-78994c9fdf-jrvs4         1/1     Running   0          7m47s
controller-b94c5b667-cphpl          1/1     Running   0          7m47s
networking-istio-5847754959-9m2fc   1/1     Running   0          118s
webhook-7cdb467d79-zgfjx            1/1     Running   0          7m47s

1-4. k8sクラスタにKFServingをインストール

$ TAG=0.2.2
$ CONFIG_URI=https://raw.githubusercontent.com/kubeflow/kfserving/master/install/$TAG/kfserving.yaml
$ kubectl apply -f $CONFIG_URI

2. PyTorchでテキスト分類するモデルを用意

長くなってきたので、後編に分割して公開します。→公開しました

3. KFServingでサーブを試す

暗中模索

お片付け

感想


  1. Kubeflowの概要を掴むには、私が見た範囲では id:ymym3412 さんの Kubeflow Pipelinesで日本語テキスト分類の実験管理 - やむやむもやむなし が参考になりました。訓練まわり(実験管理)が簡単にできそうですね。訓練したモデルはKFServingなどでサーブできます。

  2. コンポーネント一覧:Components of Kubeflow | Kubeflow

  3. モデルをサーブするコンポーネントにはKFServingの他にSeldon Coreというものもあります。ref: Overview | Kubeflow

  4. Kubeflow Overview | Kubeflow

  5. Prerequisitesは Knative Serving (v0.8.0 +) と Istio (v1.1.7+) です。ref: KFServing | Kubeflow

  6. KnativeとIstioの説明はKFServing 101 slidesを参考にしていますが、理解が追いついておらずざっくりです

  7. https://www.kubeflow.org/docs/components/serving/kfserving/#install-with-kubeflow

  8. コンソールから操作します。ref: Create, modify, or close your Cloud Billing account  |  Google Cloud

  9. GCEインスタンスが3台できていたので、--num-nodes引数を指定するのがよさそうです。今回のようなちょっとした検証に3台というのはオーバースペックです

  10. https://cloud.google.com/compute/vm-instance-pricing?hl=ja#n1_standard_machine_types

  11. (☆)にあるように https://github.com/knative/serving/tree/master/third_party を見てバージョンを指定しました