Minimal MLOps Checklist

概要

  • 自分用のメモ
  • 1人や少人数で機械学習を用いた事業を立ち上げるときに、MLOpsに最低限必要な設計・実装タスクを並べたチェックリスト
    • コストを下げるため、全自動ではなく手動の操作を許して、MLOpsを必要最低限回すのに必要なものだけ構築する
    • 自動運転とかLLMのサービスとかだとエンジニア何十人で構築するだけの投資ができるけど、そうではない分野の方が多数。そういった事業で足りないところが無いかのチェックリスト
    • 0から構築する場合は上から順に構築すれば良い
  • 結局ドメインごとの工夫は必ず必要
    • このチェックリストはあくまで共通の部分のみ
  • 時間とれたら一個一個ちゃんと解説書いて、技術同人誌にする(多分)

1. 目的

  • MLOpsが大事なのはわかるが、MLOpsエンジニアではない人が組むにはコストがかかりすぎる

MLflow、Kubeflowといった名前は聞いたことあるものの、それらを使いこなすまでの時間が取りにくい 勉強するコストの大きい技術は導入したくない、ある新しい技術を導入した時にはその技術を文化として根付かせるコストが発生する 「MLOps人材を雇用するほど余裕が無いが、事業がスケールできるようなソフトウェア基盤は作りたい」という需要があるはず

  • MLOpsで扱われる話題が大規模AIプロダクトの話なことが多く、minimalにスタートしたい時の情報が中々探しにくい

MLOpsを調べるとgoogleが発表しているものがよく検索にひっかかるが、MLOpsのフェーズが レベル0: 手動プロセス、レベル1: MLパイプラインの自動化、レベル2: CI/CDパイプラインの自動化 と分類されていたりする 多くの機械学習を使ったプロダクトを作成している時に起きている課題において、これらの自動化はオーバーエンジニアリングであることが多い、「頑張ってMLOpsのソフトウェア基盤を構築したが、結局MLエンジニアに使われなかった」というケースも多い もともとMLOpsはDevOpsにおける Dev vs Ops の対立を防ぐ活動をMLに広げるものだったけど、結果として MLエンジニア「Opsのために作られたソフトウェアが使いにくくて、MLのアルゴリズム開発が全く捗らない」 vs Ops「せっかくMLOpsが回るようにソフトウェアを構築したのに、MLエンジニアがMLOpsの重要性を理解していないから使おうとしない」という ML vs Opsの構図になったりする

2. アプリケーションを作成する

  • 基盤を作る前に「そもそも作るアプリケーションが本当に必要なのか?」を検証する必要がある
    • = プロトタイピング
  • ビジネスを行うドメインからのフィードバックをもらう
    • ML関係なく、ビジネスを行うドメインのやり方に合わせる
    • ここでは機械学習側の意見は考えなくて良い

3. ML 基盤ソフトウェアを構築する

3.1. ML基盤ソフトウェアの構築

  • まず手始めに「学習 -> 学習済モデルをupdate」のパイプラインを構築
    • ML 基盤ソフトウェアの構築を通じて、「ローカルで良い実験結果が出る->本番環境への適用、に時間がかかる」という問題の解消を目指す
    • データサイエンティストや各種アルゴリズムを考えるリサーチャーが作るソフトウェアと、実際にプロダクトとして運用されるソフトウェアにはギャップがあるので、基盤ソフトウェアの構築を行ってそのギャップをなるべく小さくする
  • 公開されている github リポジトリを確認
  • 再現性ある状態にするためにまずはdocker環境に載せる
  • READMEを整備して、どのエンジニアが作業しても再現する状態にする
  • configを1つにまとめる
    • 「学習済モデルと1つにまとまったconfig fileを他のエンジニアに渡したら、 python eval.py <config file> <checkpoint file> で全く同じ結果が得られる」という状態にする
  • 学習のlogを保存する
    • ML 基盤ソフトウェアのコミット情報、どのGPU、GPUの並列度、で学習したか、などの情報もlogに保存しておく
  • この地点で以下のファイルを管理すれば、「再現する」状況になる
    • 学習 model(pytorchのcheckpoint)
    • config file
    • 学習時のlog(評価結果が書いてある)
  • testを構築する

3.2. モデルレジストリを構築する

  • 最小コストでモデル管理基盤を構築するために、GitLFS + Custom Transfer Agenetで構築する
    • 実際の置き場はS3など
  • 階層構造としては一例として、model-registry/{algorithm}-{option}/{model_scope}/{version}/ のように定義
    • model scopeとして、“base” は base model のことで、汎用的に使うモデルとする
    • https://github.com/open-mmlab/mmdetection ベースの2D object detectionを用いたときは以下のようにモデル管理基盤へ登録する
- model-registry/
  - YOLOX-l/
    - base/
      - README.md
      - 0.1/
        - config.yaml
        - checkpoint.pth
        - checkpoint.onnx
        - log.txt

4. アプリケーションのversioningを開始し、releaseプロセスを整備する

  • アプリケーションのreleaseプロセスを整備する
    • 「バグ報告・解析 -> 再学習してモデルをreleaseする -> アプリケーション側の修正 -> アプリケーションをrelease」というサイクルの構築を目指す

4.1. 運用に必要な model versioning 定義

  • {algorithm}-{option}/base/X.Y
  • X: application側にとっての major model version
    • 前処理後処理の変更に伴ってモデルの入力や出力が変更、層の種類を変更してアーキテクチャが変更、などからapplication側の変更も伴う場合には major versionを上げる
  • Y: Base model の minor version(学習設定のバージョン)
    • 学習パラメータ、使用データセットの変更が含まれる

4.2. アプリケーションのreleaseプロセスの整備

  • モデルインリリースを採用
    • config fileでモデルを指定できるようにする
model:
  detection2d:
    root_url: "{S3のURL}"
    version: "base/1.2"
  • Docker build の構築
    • modelを入れたdocker imageの構築
  • deployされたものを置く場所を作る
    • S3など
  • リリース用scriptを用意する
  • (option) Edge AI向けのreleaseを整備する
    • TensorRTなどの高速化
    • 量子化

4.3. releaseするための結合テストを構築する

  • アプリケーション側にCI/CDを構築する
    • 全てを自動化しようとはしない
      • 「可視化画像を自動で生成 -> 人力の確認をする」ぐらいのセミオートを目指す
    • バージョンの前後変化を確認できるようにして、MLモデルの品質が確認されてから本番投入されるような仕組みを整える
    • もし閾値のようなものを設定できる場合、検証セットで緩やかな閾値+前バージョンと比較する厳しめの閾値、のようなものが設定できるとbetter
    • 「アプリケーションとしてNGになるケースを弾く」をメインに結合テストを組む
      • NGになっていけない条件があれば、そのインテグレーションテストを実装する

4.4. 運用開始

  • 運用をしてみて改良をする

5. 自分たちのデータセットを構築する

5.1. datasetの定義

  • dataset schema を作成する
    • 今後みんなが参照するインターフェイスになるので、設計は慎重に
  • survey
    • デファクトスタンダードになっている dataset schema に沿うだけで、様々なOSSの恩恵を受けられる
  • schemaでは、想定する値についても定義
    • 例えば0にならない値であれば、そのような定義もschemaに定義
    • 監視システム側でこの値の定義から逸脱した時にはアラートを鳴らすようにできる

5.2. dataset schema versioning の定義

  • dataset schema の versioning を開始する
    • dataset_schema_version: X.Y.Z のように定義して、schemaの変更があるたびにversionを上げていく
  • X: スキーマの追加・削除・要素の破壊的変更(型の変更など)を行った時に X -> X+1
    • Xが上がった時はデータセットに破壊的変更が入っているので、すべてのデータセットを更新する必要がある
  • Y: 要素の非破壊的変更を行った時に Y -> Y+1
    • Yが上がった場合にはデータセットの更新はしなくても、ML 基盤ソフトウェアは稼働できる
    • 一方で学習モデルの性能に影響する変更もある場合は、できるだけ早めに対象のデータセットだけではなく、すべてのデータセットを新しいフォーマットに更新する必要がある
  • Z: アノテーションの仕方の仕様が変わった場合はZ -> Z+1
    • 例:2D detection のタスクにおいて、タブレットPCをlaptopでアノテーションしていたが、smartphone classでアノテーションに変更した
    • スキーマ自体は変わっていないものの、作られるデータセットの仕様が変わるものになる

5.3. Document作成

  • ML 基盤ソフトウェアにドキュメントを用意する
    • 「〜アノテーションの仕様はどうなっていますか?」に対して「ここを見てください」と返せるようにする
    • ドキュメントはgitで管理されるべきなのでgithub側で管理する

5.4. Dataset APIを作成する

5.5. データセットを構築する

  • データセットストレージを用意する
    • S3やクラウドストレージに保存
    • データベースを用意するだけの余力がエンジニアにある場合は構築する
  • アノテーションツールの選定
  • データセット構築パイプラインを作る

5.6. 自分たちのデータセットを使って学習をする

  • configの作成
  • 学習、評価
  • 新しい version の release

6. Data-drivenな開発によって性能を上げる

  • 簡易MLOpsシステムを用いて、運用する
    • 「バグ報告・解析 -> データセット化 -> 再学習してモデルをreleaseする -> アプリケーション側の修正 -> アプリケーションをrelease」というサイクルの構築を目指す

7. Projectへ提供するモデルの性能をあげるためのMLOps pipeline開発

7.1. Model versioning の構築

  • {algorithm}-{option}/{model_scope}/{version} とModelを定義し、一意に定まるようにする
    • {algorithm} アルゴリズムの名前、基本的に論文などで扱われる名前を指す
    • {option} アルゴリズムに付随する様々なオプションを表す
    • {model_scope}
      • base: Base model は、幅広いプロジェクトで利用可能な汎用モデル
      • {project_name}: Project model は、特定のprojectに用いるモデル
        • Project用のデータセットなどでfine-tuningを行うことで、projectにとって最高性能のモデルを得る
      • pretrained: (Option) Pre-trained modelは、base model の汎化性能を高めるために作られるモデル
    • {version}
      • semantic versionによって管理される
      • 各 model scopeごとにversioningは異なる
  • Pre-trained model
    • {algorithm}-{option}/pretrained/{date} で管理
  • Base model
    • {algorithm}-{option}/base/X.Y で管理
    • X: application側にとっての major model version
      • 前処理後処理の変更に伴ってモデルの入力や出力が変更、層の種類を変更してアーキテクチャが変更、などからapplication側の変更も伴う場合には major versionを上げる
    • Y: Base model の minor version(学習設定のバージョン)
      • 学習パラメータ、使用データセットの変更が含まれる
  • project model
    • {algorithm}-{option}/{project_name}/X.Y.Z で管理
    • X.Y:対応する base modelのバージョン
    • Z:Projectモデルのバージョン(同一 base modelに対する更新回数)

7.2. fine-tuning pipelineの構築

  • fine-tuning用のscriptやconfigをML基盤ソフトウェアに用意する

8. モデルの性能を上げる

  • 不必要なinputや不必要なレイヤーが無いか探索する
  • Auto labelingを用いてpre-trained modelの汎化性能を向上させる
  • Distillationを用いて性能を向上させる
  • 学習の自動パラメータチューニング
  • 新しいアルゴリズムの開発
    • 工数かかるわりに性能向上が少し、みたいなケースがよくあるので注意

9. 以降

  • チームの大規模化
    1. データ基盤を構築する
    • DBを構築する
    • データセット作成パイプライン
    • log 監視システム
    1. アプリケーション側の評価システムの構築
    • KPIの設定
    • 評価用データセットの構築
    • 評価libraryの構築
    1. Data drivenな開発でさらに性能を上げる
    • 低品質なデータを弾く仕組みの構築
    • データ品質の向上
    • Data-mining システム の構築
    • Data drivenな開発
    1. 自動学習パイプラインの構築
    1. 実験管理を始める