OpenShift Pipelinesを使用してAI推論のCI/CDを試す

本記事ではOpenShift Pipelinesを使用してAI推論のCI/CDを試してみた時の手順を紹介します。

[前回の記事](https://qiita.com/mmitsugiw/items/b56c1dfd89867ea59c40)ではOpenshift S2Iを使用してAI推論のCI/CDを試してみましたが、今回はより柔軟な対応が可能なOpenShift Pipelinesを使用してみます。

今回は前回のシンプルな推論アプリに少し手を加えてAIモデルのServingを行う部分とServingを利用するUI部分を分けてみました。前回同様AI推論は学習済みモデルを使用したTensorflow/Kerasによる画像分類をサンプルとして使用し、以下のGitHub上のソースコードからOpenShift上に推論アプリをデプロイします。
AIモデル Serving部分: https://github.com/mmitsugi/ic-sample-api
UI部分: https://github.com/mmitsugi/ic-sample-ui

OpenShiftはx86サーバー上のCodeReadyContainers(CRC)を使用しています。またIBM PowerサーバーのSingle Node Cluster上でも動作可能です。IBM Powerサーバーの場合はGitHubのブランチにppc64leを指定してOpenShift Pipelinesを使用する必要があります。

# AI推論アプリの構成
GitHub上にも記載がありますが、今回使用するAI推論アプリの構成は以下となります。
![](https://github.com/mmitsugi/ic-sample-api/raw/main/doc/images/architecture_ui_and_api.png)
前回と異なりUIとAPI部分を別コンテナで分離したマイクロサービス構成で、
UI側はFlaskを使用したPythonアプリ、AIモデル側はTensorFlow Servingを使用したものとなっています。
OpenShift Pipelinesを使用してこれらのCI/CDサンプルを作成してみました。

# OpenShift Pipelinesとは
OpenShift PipelinesはオープンソースのtektonをベースとしてクラウドネイティブなCI/CDとなります。
[OpenShiftのマニュアル](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html/cicd/understanding-openshift-pipelines)に詳細が網羅されているので、ここでは詳しくは述べませんが、下記の図のようにTaskを定義し、PipelineによりTaskを連結し実行するような形をとっています。Task/PipelineはKubernetesのカスタムリソースとなっており、その実行インスタンスとなるTaskRun/PipelineRunも別のKubernetesのカスタムリソースとなっています。
[Introducing OpenShift Pipelinesより引用](https://cloud.redhat.com/blog/introducing-openshift-pipelinesより引用)
![](https://assets.openshift.com/hubfs/Google%20Drive%20Integration/Introducing%20OpenShift%20Pipelines%20-%20external.png)
OpenShift PipelinesはOperatorHubより簡単にOpenShift上にインストールできます。
![pipelines_inst1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419719/1c5cf44f-453f-8c0b-63fa-43a78a74d111.png)

# プロジェクトの作成
前回はOpenShift Web Consoleから行いましたが、今回はCLIを使ってみます。
CLIツールはocとtknを使用します。
どちらもWeb Consoleの?マークのアイコンをクリック -> コマンドラインツールからダウンロードでき、パスの通った場所に配置して使用するだけです。
まずはOpenShift Pipelinesを使用するユーザー(今回はdeveloperを使用)でocコマンドでloginを行います。
(下記はcrcの例ですが、必要に応じてURLを変更します)
```
$ oc login -u developer https://api.crc.testing:6443
```
新しいプロジェクトを作成します。
```
$ oc new-project ic-pipelines
```

# AIモデルServingのPipeline作成と実行
まずは上記AIモデルServingのgithubをcloneします。
```
$ git clone https://github.com/mmitsugi/ic-sample-api.git
```
AIモデルを保存するPersistent Volumeの定義を行います。
```
$ cd ic-sample-api
$ oc create -f pipeline/model_pvc.yaml
```
Pipelineの構成要素となるTaskを定義していきます。
モデル保存Task (KerasにてAIモデルを取得してTensorflow Servingで使用できるモデルに変換、保存)
```
$ oc create -f pipeline/save_model_task.yaml
```
AIモデル配置とServingサービスのManifest適用Task
```
$ oc create -f pipeline/apply_manifest_task.yaml
```
次にPipelineを作成します。上記2タスクとビルトインのgit-cloneのTaskをつなげます。
これにより
git clone -> model save -> apply manifestによるモデル配置とサービス作成
をパイプライン化します。
```
$ oc create -f pipeline/pipeline.yaml
```
これでPipelineの作成は完了です。
tknコマンドで作成したTask / Pipelineの情報を確認することが可能です。
```
$ tkn task list
$ tkn clustertask list
$ tkn pipeline list
```
次にPipelineを実行してみます。
```
$ tkn pipeline start model-save-and-deploy -w name=shared-workspace,claimName=model-pv-claim -p deployment-name=ic-sample-api -p git-url=https://github.com/mmitsugi/ic-sample-api.git --use-param-defaults
```
Pipeline実行の様子は上記tkn pipeline startにて表示されるコマンドtkn pipelinerun logsでも確認できますし、
Web Consoleのパイプラインメニューからの以下のように確認できます。
![pipeline1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419719/690eaef5-d4bb-657b-608d-f193a217ba4b.png)
トポロジーメニューからもサービスがパイプライン実行により作成されていることが確認できます。
![pipeline2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419719/b0caac07-fa4b-b40a-576a-88a1ede0e128.png)

# UI部分のPipeline作成と実行
続いてUI部分のPipeline作成と実行を行います。
基本的な流れはAIモデルのPipelineと同じになります。
UI部分のPipelineはAIモデルの方で作成したapply manifestのTaskとビルトインのTaskを使用するため、
Pipelineのみ定義します。
```
$ git clone https://github.com/mmitsugi/ic-sample-ui.git
$ cd ic-sample-ui
$ oc project ic-pipelines
$ oc create -f pipeline/pipeline.yaml
```
これにより
git clone -> UI用のコンテナをビルド -> apply manifestによるモデル配置とサービス作成
をパイプライン化を行っています。

AIモデル同様、Pipeline実行を行ってみます。
```
tkn pipeline start build-and-deploy -w name=shared-workspace,claimName=model-pv-claim -p deployment-name=ic-sample-ui -p git-url=https://github.com/mmitsugi/ic-sample-ui.git -p IMAGE=image-registry.openshift-image-registry.svc:5000/ic-pipelines/ic-sample-ui --use-param-defaults
```
同様に実行結果がコマンドおよびWeb Consoleにて確認できます。
下記はパイプライン実行ログ画面で、各Taskごとのログが確認できます。
![pipeline3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419719/e22f242d-bb88-5ce6-f95f-8884cdaec7ea.png)
トポロジーメニューからもUIサービスが作成されていることが確認できます。
![pipeline4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419719/05548353-c322-b89f-4524-b8c2db79d335.png)

# AI推論アプリの実行
トポロジーページにあるUIサービスの"URLを開く"をクリックします
![pipeline5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419719/a9e338a6-5cfa-5fba-a8cc-e356f0646054.png)

以下のようにAI推論アプリが立ち上がり、分類したい画像ファイルのアップロードで画像分類が実行できます:smiley_cat:
![ai_inference.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419719/9dfc3aa6-edfc-328d-354e-c8c9babda923.gif)

以上、OpenShift Pipelinesを使用してAI推論のCI/CDを試してみました。今回はUI部分とAIモデル部分を分けてPipelineを作成しました。これによりUIとモデルで別々のPipeline実行が行えるため、並行した開発も可能となりかつOpenShift Pipelinesでより柔軟なCI/CDを構築ができるかと思います。
今回もトリガーの設定は行っていませんが、GitHubのWebHookによるトリガー設定でGitHubの変更をトリガーとしたPipeline実行が可能となります。