Watson NLP Hands-On Lab: Deploy Model - 組み込みAI セルフサービス型デジタル共創体験(DSCE)

# 組み込みAI セルフサービス型デジタル共創体験(DSCE)とは

[組み込みAI セルフサービス型デジタル共創体験](https://qiita.com/trtrbohz/items/356a5a4b66624b2c94a2)に記載しておりますが、現在STT(speech-to-text)、TTS(test-to-speech)、NLU(natural-language-understanding)等のAIがサーバーに接続しなくても組み込んで利用することが可能となりました。

その情報がこちらの[サイト](https://dsce.ibm.com/)、DSCE([Digital Self-Serve Co-Create Experience](https://dsce.ibm.com/);"組み込みAI セルフサービス型デジタル共創体験"？)にて紹介されております。

今回はそのDSCEの中から、「Watson NLP Hands-On Lab」 を実施してみます。
ただし、NLPはNLUと違いSaaS版のAIエンジンに接続します。
※個人的な利用は無償ですが、商用利用は有償となります。

# 今回  「Watson NLP Hands-On Lab: Deploy Model」で感情分析をやってみた。
今回の[「Watson NLP Hands-On Lab: Deploy Model」](https://github.com/ibm-build-lab/Watson-NLP/blob/main/hands-on-lab/deploy-model/README.md)はOpenShift上に Watson NLP を構築するものです。前半に学習済モデルでの感情分析を行い、後半でカスタムモデルでの感情分析を行ないます。

# 1.前提
*  IBM Entitled Registry にアクセスしてするための entitlement key を [container soft library](https://myibm.ibm.com/products-services/containerlibrary)から入手していること
* IBM Technology Zone (TechZone)にアクセスできること
* このリンク先にあるTechZoneで環境を予約すること : [https://techzone.ibm.com/collection/watson-nlp-library-hands-on-lab/journey-deploy-model:](https://techzone.ibm.com/collection/watson-nlp-library-hands-on-lab/journey-deploy-model)

上のURLにアクセスすると下の左のサイトにアクセスできます。そこで、「Environment: Deploy Model」枠下にある「Reserve」をクリックし、開く画面（下の右）で「Reserve now」「Schedule for later」どちらかを選択。
![スクリーンショット 2023-06-06 15.00.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/1c58b789-6aea-46a5-ed67-262898f0b450.png)

＊ 上記のTechZoneで環境を予約したする時には以下のように記入すること
　　* Purpose: Practice/Self-Education
　　* Purpose description: Hands-on lab
　　* Preferred geography: AMERICAS - us-south region - any datacenter

![スクリーンショット 2023-06-06 13.39.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/5b7c36f3-f5c1-2fbb-14b9-0aaf7c4d1f1c.png)


# 2. deploy a pretrained nlp model
## 2.1. メールからtechzoneにアクセスする

予約するをするとまずプロビジョニング開始を📢メールが飛んできます。数分後に準備完了との連絡が届きます。そのメール内に「Project URL」というリンクがあります。こちらに OpenShift Web Console の URL　が連携してされていますのでこれにアクセスします。

![スクリーンショット 2023-06-06 15.24.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/05ddd4c7-91d8-b4b9-5396-b5cbb0907487.png)

＊　この環境は３日間有効です。３日経過すると自動的に削除されます。

## 2.2. Open a Terminal in the Image-Builder Pod
下の図参照
①左上に「Administrator」が選択されていることを確認
②ワークロード - Pod を選択
③可動しているPodが表示されますのでリンクをクリック （OpenShiftのビルド構成を使用してコンテナイメージを作成するための機能を持つ基礎的なPodです。）
![スクリーンショット 2023-06-06 15.44.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/f9b4a1f9-0baf-9e7b-9c1f-24329098bfe9.png)
④展開される画面の上、右にある"ターミナル"をクリック
![スクリーンショット 2023-06-06 15.54.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/0651f1c8-ba3d-3023-c6ef-f4f894f6022e.png)

## 2.3: Log in to OpenShift from the Terminal
① 画面右上にある「IAM#＜ログインユーザ名＞」をクリック。
② 「ログインコマンドのコピー」→「Display Token」→「Log in with this token」をコピー
![スクリーンショット 2023-06-06 16.07.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/c52ca8b7-7c8f-7e14-e0fd-ec5a320a7b8c.png)
③ 前のステップ(2.2)にて開いたターミナルに貼り付け＆実行

    oc login --token=xxxx --server=xxxx 

![スクリーンショット 2023-06-06 20.55.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/6118c124-ad19-ac63-cc29-3518acb1b560.png)

④ 後続のステップにて有効な環境変数を設定

    export REGISTRY=$(oc registry info)
    export PROJECT=$(oc config view --minify -o 'jsonpath={..namespace}')

## 2.3' @ローカルホスト
① ご自身のローカル環境でターミナルを開く
② ターミナルにログインコマンドを貼り付け＆実行

![スクリーンショット 2023-06-06 20.57.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/981235f8-3286-9f89-d409-1ca5b97c8b3c.png)

③ ＠ローカルホスト ターミナルで後続のステップにて有効な環境変数を設定

![スクリーンショット 2023-06-06 21.02.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/cf7ca3c3-a0cd-505c-1809-3b1b1fd53586.png)

## 2.4. Add Your Entitlement Key @ OpenShift Terminal
① 次のURLにアクセス [https://myibm.ibm.com/products-services/containerlibrary](https://myibm.ibm.com/products-services/containerlibrary)
② ライセンスキーをコピー
![スクリーンショット 2023-06-06 20.43.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/8606b492-8f60-7b93-691f-d239ebef1dbe.png)
③ 環境変数として設定

    export IBM_ENTITLEMENT_KEY=xxx

④ IBM Entitled Container Registry にアクセスし、Watson NLP イメージを取得するため、プロジェクトに"watson-nlp"という名のシークレットを作成

    oc create secret docker-registry watson-nlp --docker-server=cp.icr.io/cp --docker-username=cp --docker-password=$IBM_ENTITLEMENT_KEY
    oc patch serviceaccount default -p '{"imagePullSecrets": [{"name": "watson-nlp"}]}'

## 2.4' @ローカルホスト
① ライセンスキーを環境変数として設定
 
![スクリーンショット 2023-06-06 21.09.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/022536b9-936f-087a-9a11-0f845410d57f.png)

② IBM Entitled Container Registry にアクセスし、Watson NLP イメージを取得するため、プロジェクトに"watson-nlp"という名のシークレットを作成

![スクリーンショット 2023-06-06 21.13.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/63faf0d8-7280-0f86-02ae-f4ae36bb5d96.png)


## 2.5. Create the Watson NLP Service @ OpenShift Terminal
2.2.④で開いたOpenShift上のターミナルで以下を実行

    cd /workshop
    wget https://raw.githubusercontent.com/ibm-build-lab/Watson-NLP/workshop/MLOps/Init-Container/deployment/deployment.yaml
    oc apply -f deployment.yaml

PodとDeploymentとサービスができました。
![スクリーンショット 2023-06-06 21.31.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/63ed17c6-330b-fea9-1a94-8c4d1e2b9e9b.png)


## 2.5' @ローカルホスト
デプロイメントYamlを入手して、デプロイメント作成

![スクリーンショット 2023-06-06 21.22.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/eb161939-655a-89b5-f155-360a6b69fd41.png)


## 2.6. 確認 @ OpenShift Terminal
サービス確認

    oc get svc 

デプロイメント確認

    oc get deployment 

ポッド確認

    oc get pods

![スクリーンショット 2023-06-06 21.38.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/9b4a4aa4-fd59-f290-861c-fa7632f5ea21.png)

## 2.6' @ローカルホスト
![スクリーンショット 2023-06-06 21.40.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/dbdc61d7-c6dd-2f57-3e05-34803af53738.png)



## 2.7. Test the Pretrained Model @ OpenShift Terminal
「procrasting is fun until im an hour away from the time its due and i still havent finished so i have a panic attack」という文章を使って、事前学習モデルのNLPを実行

    curl -X POST "http://watson-nlp-runtime-service:8080/v1/watson.runtime.nlp.v1/NlpService/EmotionPredict" -H  "accept: application/json" -H  "grpc-metadata-mm-model-id: emotion_aggregated-workflow_lang_en_stock" -H  "content-type: application/json" -d "{  \"rawDocument\": {    \"text\": \"procrasting is fun until im an hour away from the time its due and i still havent finished so i have a panic attack\"  }}" | jq

![スクリーンショット 2023-06-06 21.45.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/5cbdea36-c7cd-7dc6-9c11-6a54626c82ae.png)

## 2.7' @ローカルホスト
ローカルホストで実施する場合、OpenShiftのサービスがまだ外部に公開されていないので、以下のコマンドを使ってサービスを外に公開

    oc port-forward svc/watson-nlp-runtime-service 8080:8080

![スクリーンショット 2023-06-06 21.47.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/12c2a3f8-070c-9c28-df8a-441fc3826db2.png)
上記コマンドにより、Openshiftのサービスがローカルホストにポートフォワードされるので、事前学習モデルのNLPを実行する際にはホスト名を「watson-nlp-runtime-service」から「localhost」に変更
![スクリーンショット 2023-06-06 22.06.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/a396ee12-909c-1440-6435-437cb94421cb.png)

# Deploy a Custom Model
ここから Watson model builder tool を使ってコンテナイメージにカスタムモデルを入れていきます。ここではIBM内部で使われているものと同じツールを使います。カスタムイメージを作って、OpenShift内部のコンテナレジストリに登録していきます。

簡便のため、ここではWatson Studio で作成したNLPカスタムモデルを用いてプロビジョニングされたPodを使います。モデル名は「model_tfidf_emo_classification」です。

※ここから後、/workshop/models ディレクトリをGithubから得ることができなかったので、ローカルホストでの実行は確認できておりません。

## 2.8 Install the model packager tool @ OpenShift Terminal
まずWatson NLP model packager toolをインストールします。このツールはPythonで作成されており、１つ以上のモデルをパッケージングします。

    pip3 install watson-embed-model-packager

![スクリーンショット 2023-06-07 0.29.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/87fefb5c-2ae1-15a6-69f4-6a94f5701a1c.png)

## 2.9 Build the Model Container Image
パッケージングツールをインストールするため以下のコマンドを実行します。

    cd
    python3 -m watson_embed_model_packager setup \
    --library-version watson_nlp:3.6.0 \
    --local-model-dir /workshop/models \
    --output-csv model-manifest.csv

![スクリーンショット 2023-06-07 0.31.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/e0b3cfb7-0fb5-295b-33dd-cbe596513ddd.png)

次で、ビルド。

    python3 -m watson_embed_model_packager build --config model-manifest.csv

![スクリーンショット 2023-06-07 0.34.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/ae734245-60a8-28ab-12bd-a08a82e38ff7.png)

イメージ確認

    docker images

![スクリーンショット 2023-06-07 0.35.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/8e77f398-2b32-6be9-6318-f1910d1eacf1.png)

## 2.10 Push Model Image to Container Registry
できたモデルイメージをOpenShift の内部レジストリに登録していきます。

    echo $(oc whoami -t) | docker login $REGISTRY -u $(oc whoami) --password-stdin --tls-verify=false

    cd /workshop
    for m in $(ls models)
    do 
      docker tag watson-nlp_${m}:latest ${REGISTRY}/${PROJECT}/watson-nlp_${m}:latest
      docker push ${REGISTRY}/${PROJECT}/watson-nlp_${m}:latest --tls-verify=false
    done

![スクリーンショット 2023-06-07 0.38.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/b1923cd4-a562-17e4-fa09-b8b3584e3add.png)

確認

    oc get is

![スクリーンショット 2023-06-07 0.39.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/20315452-af4b-57f4-00ab-2b27ecd72056.png)

## 2.11 Update Kubernetes Manifest
初めに作成された Kubernetes Deployment を次のコマンドで更新します。

    echo "spec:
      template:
        spec:
          initContainers:
          - name: complaint-topic-model-discover
            image: image-registry.openshift-image-registry.svc:5000/$PROJECT/watson-nlp_model_tfidf_emo_classification
            volumeMounts:
            - name: model-directory
              mountPath: \"/app/models\"
            env:
            - name: ACCEPT_LICENSE
              value: 'true'
            resources:
              requests:
                memory: \"100Mi\"
                cpu: \"100m\"
              limits:
                memory: \"200Mi\"
                cpu: \"200m\"" > /tmp/patchFile.yaml
            
    oc patch deployment watson-nlp-runtime --patch-file /tmp/patchFile.yaml

上記コマンドで、事前学習モデルとカスタムモデルのPodが起き変わりました。
確認します。

![スクリーンショット 2023-06-07 0.46.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/ed29cbb2-5b15-5a1f-dcd1-1dbeebe09c09.png)

## 2.12 Test the Custom Model
ここでもやはり「procrasting is fun until im an hour away from the time its due and i still havent finished so i have a panic attack」という文章を使って、カスタムモデルのNLPを実行

    curl -X POST "http://watson-nlp-runtime-service:8080/v1/watson.runtime.nlp.v1/NlpService/ClassificationPredict" -H  "accept: application/json" -H  "grpc-metadata-mm-model-id: model_tfidf_emo_classification" -H  "content-type: application/json" -d "{  \"rawDocument\": {    \"text\": \"procrasting is fun until im an hour away from the time its due and i still havent finished so i have a panic attack\"  }}" | jq

![スクリーンショット 2023-06-07 0.48.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/f0e1e230-47bd-55d0-f7a7-e97da5f2d156.png)


## 結果
事前学習モデルの結果とカスタムモデルの結果を見比べると各感情の確率が違いますね。


## 最後
Swagger GUI を使って Watson NLP API を見てみます。
２．７’ @ローカルホストの所でも記載したのですが、OpenShiftのサービスを外部に公開するため、以下のコマンドを使います。

    oc port-forward svc/watson-nlp-runtime-service 8080：８０８０

![スクリーンショット 2023-06-07 0.57.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/2ccc847e-6544-5f0b-59db-50e6e7380e77.png)


その後、ローカルホストのブラウザを使って以下のURLにアクセス

    http://localhost:8080/swagger/

![スクリーンショット 2023-06-07 1.08.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/aba75196-a701-dc7e-2fa6-8713a9daea21.png)


## 参考

[Watson NLP Hands-On Lab: Deploy Model](https://github.com/ibm-build-lab/Watson-NLP/blob/main/hands-on-lab/deploy-model/README.md)