本ブログは、CircleCI Advent Calendar 2023 の8日目の記事です。
はじめに
DevOps の実装において、ビルドやテスト、リリース、デプロイといったステップを自動化するには、設定ファイルにワークフローを記述します。ワークフローが実行されるのは、リポジトリにコードがコミット、プッシュされるタイミングです。
機械学習を自動化する MLOps に関しても同様に、ロジックを実装したコードが変更されるタイミングでワークフローが実行されます。
ただし、MLOps の場合、コードに変更がない場合であっても、トレーニングデータが更新され、モデルを作成し直したいといったような場合があります。モデルを作成し直したら、これまでのテストデータでテストし、結果を見たいと考えるでしょう。テストデータが追加されたので、既存のモデルでテストしてみたいということもあるでしょう。
本記事では、CircleCI を MLOps の「ハブ」として使い、Roboflow のデータをもとにモデルを作成したり(ここまでが前記事)、作成したモデルが Hugging Face に登録されたタイミングでテストを実行する方法(本記事)をご紹介します。
MLOps ワークフローの流れ
ここでは、Hugging Face 上のモデルが更新されたら、その更新されたモデルをもとに、テストセットを実行します。
なお、プロジェクトのリポジトリは、GitHub にあります。
このプロジェクト(cci-test-yolov8-mask-model)をご自身のGitHubプロジェクトとして fork します。
ご自身で動作を CircleCI 上で実際に試してみたい場合、CircleCI のアカウントを用意する必要があります。この際、(2023年9月以前の) GitHub や Bitbucket の認証で CircleCI にログインするのではなく、CircleCI のアカウント(メールアドレス、パスワード)を作成し、そのアカウントでログインしたうえで、GitHub 上のプロジェクトを CircleCI のプロジェクトとして登録する必要があります。具体的な方法は、私が Qiita に書いた次の2つの記事をご参照ください。
Hugging Face から CircleCI の呼び出し設定(Webhook)
次に、Hugging Face 上のモデルが更新されたら、CircleCI のワークフローを呼びだすための設定を行います。
前述の GitHub プロジェクトを CircleCI のプロジェクトとして登録しておきます。つぎに、CircleCI の Project Setting 画面の左側にある Triggers をクリックし、Add Trigger ボタンをクリックして、新規トリガーを追加します。
トリガー追加画面が出たら、接続先に Inbound Webhook を指定して、Next ボタンをクリックします。
次に、トリガー設定場面が出るので、Trigger Source に HuggingFace_ModelUpdate といった Webhook の発信元がわかるような名前を入力し、Save ボタンをクリックします。
すると、最終的に Webhook の呼び出し先が表示されます。Webhook URL、および、 を置き換えるのに必要な Secret (一部マスクされた状態で表示されています) をコピーして、ご自身で保持しておくようにします。
さて、呼び出し元の Hugging Face の設定に移ります。Hugging Face のユーザ設定(Settings)画面の左から Webhooks をクリックし、Add a new webhook をクリックします。
次に、Webhook の呼び出し方法の設定に移ります。Target repositories には Hugging Face 上で(更新を)監視するリポジトリを指定します。ここでは、mfunaki/cci-gpu-yolov8-maskdetection を指定していますが、ご自身のモデル格納先を指定します。また、Webhook URL には、先ほどの CircleCI のトリガー設定画面で表示されていた Webhook URL (を Secret の値で置換したもの)を指定します。
最後に、Triggers には Repo update (リポジトリの更新) をチェックしておけば、モデル更新時に CircleCI が呼び出されます。Create webhook ボタンをクリックしておきましょう。
動作環境の設定
トレーニングは CircleCI の Linux GPU 環境上で実行しましたが、テスト(画像認識)はトレーニングほどは負荷が高くないので、Linux CPU 環境上(コンテナ上)で実行します。
orbs:
python: circleci/python@2.1.1
jobs:
test_model:
executor: python/default
ジョブの定義
ここでは test_model というジョブを定義して、その中で、Hugging Face CLI のインストール、Hugging Face 上で更新されたモデルの取得、テストデータを使ったマスク着用/不着用の検出、検出結果(アーティファクト)のアップロードを行います。
Hugging Face CLI のインストール
前回もご紹介しましたが、Hugging Face CLI は pip パッケージが用意されているので、簡単にインストール可能です。
steps:
- checkout
- run:
name: Set up Hugging Face CLI
command: pip3 install -U "huggingface_hub[cli]"
Hugging Face 上のモデルをダウンロード
次に Hugging Face 上のモデルをダウンロードします。前回は huggingface-cli upload でアップロードしましたが、今回は huggingface-cli download でダウンロードします。前回と同様、CircleCI プロジェクトの環境変数として、HUGGINGFACE_TOKEN に API キーを設定しておきます。
- run:
name: Set up a model from Hugging Face
command: |
cd ~
mkdir datasets; cd datasets
huggingface-cli login --token $HUGGINGFACE_TOKEN
huggingface-cli download mfunaki/cci-gpu-yolov8-maskdetection \
mask_best.pt \
--local-dir ~/.pyenv/runs/detect/train/weights
モデルをテスト(マスク着用の有無を検出)
次に、YOLOv8を使ってモデルをテストします。YOLOv8 のインストールは前回の「モデルの構築」の際と同様です。
モデルの構築の際は、yolo task=detect mode=train でトレーニングを行いましたが、今回のモデルのテストでは、yolo task=detect mode=predict で検出を行います。また、ここでは、モデルがプロジェクトの image ディレクトリに格納してあるものとします。
- run:
name: Test the model
command: |
pip3 install ultralytics
yolo task=detect mode=predict \
model=~/.pyenv/runs/detect/train/weights/mask_best.pt \
source=~/project/images
アーティファクトの保存
検出結果を後で参照、取得できるようにアーティファクトとして保存しておきます。
- store_artifacts:
path: ~/.pyenv/runs/detect/predict
destination: predict
アーティファクトは CircleCI のウェブ画面から参照することができます。
個々のファイルを開くことで、元の画像からマスク着用(mask)、または非着用(no-mask)の検出結果を参照することが可能です。
おわりに
今回は、モデルの更新時に CircleCI がモデルテスト用のワークフローを自動実行する設定を行いましたが、教師データの追加、更新時にモデルを再更新する、テストデータが追加されたら追加されたデータに対してテストを行うなど、さまざまな用途が考えられます。
機械学習は PoC よりも、実際に利用されるデータをもとに学習を積み重ねていき、テストを実行していくことで、精度を担保していくことが重要です。更新したモデルが(現行のモデルと比較して)有意の精度が得られたら、実環境にデプロイするといったことも MLOps に組み込む必要があるでしょう。
CircleCI のインバウンド Webhook を活用することで、みなさんの MLOps が最適化されれば幸いです。