Blog
Seldon Coreを使った機械学習プロダクトのデプロイ
AILabの松崎です。
最近機械学習プロダクトの基盤構築についての情報をよく見かけますが、特にKubeflowに注目が集まっているようです。
KubeflowはKubernetesクラスタ上で機械学習プロダクトを動かすことに長けたツールキットです。
今回はKubeflowのデプロイに利用されている、Seldon Coreについて紹介します。
Seldon Coreについて
Seldon CoreはSeldon社の提供するオープンソースプロダクトで、機械学習のモデルをKubernetesクラスタ上にデプロイするための基盤として作られています。
特徴としては
- 多様な言語やフレームワークに対応している
- 機械学習のモデルを、RESTやgRPCを介した公開ができる
- デプロイしたモデルの継続的なアップデート、スケーリング、モニタリングなどを可能にする
などがあります。
今回はこちらの例に則って、scikit-learnでMNISTの予測モデルを作成し、それをKubernetesクラスタのAPIとして公開するところまでやってみようと思います。
必要なもの
今回はローカルにDockerを用いたKubernetesクラスタを用意し、そこに予測APIを立てます。
そのため
- Docker
- kubectl
- source-to-image
が必要となります。
手順概要
Seldonを用いたAPIの公開はざっくりとは以下の手順になってます。
- 予測モデル(pklファイル)の作成
- source-to-image(s2iコマンド)を用いた予測APIを内包したDockerイメージの作成
- SeldonDeploymentによるデプロイ
となっています。
下準備
まずseldon-coreのリポジトリをクローンします。
次に作業ディレクトリ(名前は myModel
としています)を作成します。
場所は基本的にどこでもいいですが、今回は seldon-core
リポジトリに入っているスクリプトなどを使いたいので、クローンした seldon-core
のリポジトリと同じ階層に作りました。
1 2 3 4 5 6 |
$ git clone https://github.com/SeldonIO/seldon-core.git $ mkdir myModel $ ls myModel seldon-core $ cd myModel |
次に kubectl
で namespace
、cluterrolebinding
の設定を行います。
1 2 3 4 5 6 7 8 |
$ kubectl create namespace seldon namespace/seldon created $ kubectl config set-context $(kubectl config current-context) --namespace=seldon Context "docker-for-desktop" modified. $ kubectl create clusterrolebinding kube-system-cluster-admin --clusterrole=clus ter-admin --serviceaccount=kube-system:default clusterrolebinding.rbac.authorization.k8s.io/kube-system-cluster-admin created |
さらに、Helmによる操作を行うために、Helmのセットアップを行いましょう。
1 2 3 4 5 6 |
$ kubectl -n kube-system create sa tiller serviceaccount/tiller created $ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller clusterrolebinding.rbac.authorization.k8s.io/tiller created $ helm init --service-account tiller |
最後にHelmを使ってSeldon Coreをクラスタに入れて行きます。
1 2 3 |
$ helm install ../seldon-core/helm-charts/seldon-core-crd --name seldon-core-crd --set usage_metrics.enabled=true $ helm install ../seldon-core/helm-charts/seldon-core --name seldon-core |
これで準備は完了です。
予測モデル(pklファイル)の作成
まずscikit-learnによるMNISTの予測モデルを作成しましょう。
最終的な成果物としてpklファイルが生成されれば良いので、例えば こちら に含まれている学習のコードを使ってみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
from sklearn.ensemble import RandomForestClassifier from sklearn import datasets, metrics from sklearn.utils import shuffle from sklearn.datasets import fetch_mldata from sklearn.externals import joblib from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets("MNIST_data/") mnist_images = mnist.train.images mnist_labels = mnist.train.labels n_samples = len(mnist_images) data = mnist_images.reshape((n_samples, -1)) targets = mnist_labels data,targets = shuffle(data,targets) classifier = RandomForestClassifier(n_estimators=30) classifier.fit(data[:n_samples // 2], targets[:n_samples // 2]) expected = targets[n_samples // 2:] test_data = data[n_samples // 2:] predicted = classifier.predict(data[n_samples // 2:]) joblib.dump(classifier, 'sk.pkl') |
上記のスクリプトを sklearn-train.py
という名前で保存して実行すると sk.pkl
というモデルのファイルが作成されます。
1 2 3 4 |
$ python sklearn-train.py $ ls MNIST_data sk.pkl sklearn-train.py |
これで学習モデルの用意ができました。
予測APIを内包したDockerイメージの作成
これを使って予測APIを内包したdocker imageを作成します。
今回は、source-to-image(以降s2i)を使ってdocker imageを作成して行きます。
seldon-coreのs2iを利用するためには、作業ディレクトリに
- requirements.txt
- Mnist.py
- .s2i/environment
が必要になります。
(参照:https://github.com/SeldonIO/seldon-core/blob/master/docs/wrappers/python.md)
requirements.txt
このファイルにはモデルを動かす際に必要な依存関係を書いて行きます。
今回必要な依存関係は scikit-learn
のみですのでそれを書いておきます。
1 2 |
scikit-learn |
Mnist.py
このファイルでは作成したモデルでどのように予測のAPIを返すかを定義します。
今回は単純に、画像データの配列を受け取り、その予測を返すだけなので下のようなコードになります。
1 2 3 4 5 6 7 8 9 10 |
from sklearn.externals import joblib class Mnist(object): def __init__(self): self.clf = joblib.load('sk.pkl') def predict(self, X, feature_names): predictions = self.clf.predict(X) return predictions |
.s2i/environment
このファイルではモデルをラップするための変数を定義します。
MODEL_NAME
は上記で定義したクラスの名前を入れておきます。
またAPIは今回REST
にしています。
1 2 3 4 5 |
MODEL_NAME=Mnist API_TYPE=REST SERVICE_TYPE=MODEL PERSISTENCE=0 |
以上でs2iの準備は完了です。
作業ディレクトリの構造は
1 2 3 4 5 6 7 |
$ ls -a . .s2i Mnist.py requirements.txt sklearn-train.py .. MNIST_data sk.pkl $ cd .s2i $ ls environment |
となっています。
これらを用意した上で以下のコマンドを実行すると、
1 2 |
s2i build . seldonio/seldon-core-s2i-python3:0.2 predict-mnist:0.1 |
predict-mnist:0.1
というdocker imageが出来上がります。
これを利用して、予測APIのデプロイを行います。
SeldonDeploymentによるデプロイ
予測用のイメージが出来上がったので、クラスタ上にデプロイします。
まず mnist.yaml
によって SeldonDeployment を定義し、
実際にAPIを動かして見ます。
mnist.yaml
SeldonDeployment
というkindを用いて、予測APIのデプロイを行います。
この中で先ほど作った predict-mnist:0.1
を image
にしてあげます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
apiVersion: machinelearning.seldon.io/v1alpha2 kind: SeldonDeployment metadata: labels: app: seldon name: mnist spec: annotations: project_name: Sklearn MNIST deployment_version: v1 name: mnist oauth_key: oauth-key oauth_secret: oauth-secret predictors: - componentSpecs: - spec: containers: - image: predict-mnist:0.1 imagePullPolicy: IfNotPresent name: classifier resources: requests: memory: 1Mi terminationGracePeriodSeconds: 20 graph: children: [] name: classifier endpoint: type: REST type: MODEL name: single-model replicas: 1 annotations: predictor_version: v1 |
このyamlファイルを適用しましょう。
1 2 3 4 5 |
$ ls MNIST_data Mnist.py mnist.yaml requirements.txt sk.pkl sklearn-train.py $ kubectl apply -f mnist.yaml seldondeployment.machinelearning.seldon.io/mnist configured |
これでデプロイが完了しました!
実際にAPIを叩いて見ます。
seldon-core/util/api_tester/
に api-tester.py
というランダムに0から9の画像データをPOSTしてくれるスクリプトがあるのでこちらを利用します。
1 2 |
$ python ../seldon-core/util/api_tester/api-tester.py ../seldon-core/examples/models/sk_mnist/contract.json localhost `kubectl get svc -l app=seldon-apiserver-container-app -o jsonpath='{.items[0].spec.ports[0].nodePort}'` --ambassador-path "" --oauth-key oauth-key --oauth-secret oauth-secret -p |
すると、
1 2 |
{'meta': {'puid': 'ngm211fcmg71lq74aonieacd3j', 'tags': {}, 'routing': {}}, 'data': {'names': [], 'ndarray': [8.0]}} |
のようにレスポンスが返ってきて、ndarray
の部分に予測クラス(0.0-9.0)を返してくれます。
以上でSeldon Coreによるモデルのデプロイが完了しました!
まとめ
以上のようにSeldon Coreを使うと、kubernetes上に予測モデルを内包したAPIを簡単にデプロイすることができます。
特に便利だなと感じたのはモデル作成を行なった後に予測APIを内包するDockerイメージへの変換するところです。
定義ファイルを作成すれば、コマンド一つで行えるため、APIサーバーなどについて考えるコストが0になります。
さらにSeldon CoreはTensorflowやKeras、Sparkなどに使えるため、ライブラリや言語に依存せず統一的なモデルデプロイのフローにできることに強みを感じました。
また、ここでは紹介しきれませんでしたが、 Grafanaを用いた監視ツールの構築もかなり簡単に行えます。
一方でまだプロダクトが発展途上なため、公式のドキュメントが粗かったり参考にできる文献が少ないと感じました。
そのため今後より自分たちのプロダクトに近い構成で使用してみるとともに、より良いプロダクトのアップデートを期待することとします。
Author