機械学習システム開発における品質担保のための取り組み(PoCフェーズ編)

はじめに

MLプロジェクトのPoCフェーズにて、MLOpsエンジニアとして取り組んだことをまとめてみました。
「MLモデリング以外のことを全部やる」、位のくくりで取り組んだので、厳密には「それMLOpsか…?」ということもまぁまぁある気がしますが、ご容赦下さい。

意識していたこと

以下、MLプロジェクトのPoCフェーズにおける大小様々な課題とそれを解決するためにやったことを書いていますが、
 ・PoCフェーズでの成果が後続フェーズできちんと利用できるにすること、が最低限達成すべきことであり、一方で
 ・データサイエンティストのコストは極力最小化する(トレードオフな部分はある)、ということは意識していました。

前提

  • フェーズ
    • MLプロジェクトがPoCフェーズ→構築フェーズ→運用フェーズから構成されるとした場合の、PoCフェーズについて記載しています。
  • 案件の種類
    • 受託案件での取り組みについて記載しています。受託案件と自社開発案件との差分は大きくはないと思っていますが、強いて言うなら「顧客ごとの要件に合わせて環境や仕組みを個別にクイックに作ることになりがち」「PoCフェーズは自社環境で実施するが、構築フェーズ以降は顧客環境で実施する場合がある」あたりが違いかなと思っています。(ケースバイケースですが)
  • ロールの定義(便宜上)
    • データサイエンティスト: MLモデリングを担当する人
    • MLOpsエンジニア: MLモデリング以外のエンジニアリングを担当する人(以下のタスクを実施する人)

取り組んだこと

0. 導入提案

導入提案タスクの概要

  • MLOps導入の提案

導入提案タスクの目的

  • プロジェクトリーダー・データサイエンティストに対して、プロジェクト開始前or直後に、MLOps導入の目的(必要性)やスコープを明確に伝えておくことで、スムーズに連携することが目的でした。
    • データサイエンティストvsソフトウェアエンジニアの対立、とかはあるあるとしてよく聞くので、事前に必要性とスコープを明確に伝えておきました。

導入提案タスクの内容

※ 事前に認識合わせをした内容

  • 背景
    • 「MLプロジェクトを円滑に進めることを阻害する課題がある。特に、PoCフェーズを経て、構築運用フェーズ(プロダクション化)に進むに連れ、問題が顕在化しがちである。」
    • 「PoCにて、報告資料に乗せる良い数字がローカル環境で取れた」 ≠ 「MLモデルがプロダクション環境にデプロイされ、サービス(価値)を安定的に提供していく」
    • 「厄介なのは、前フェーズ(PoC担当者など)で対策をしなかった結果、困るのは後フェーズ(構築運用担当者)、となる課題も多いこと。」
  • 課題と対策案例
  • MLOps導入の目的
    • 「MLプロジェクトを円滑に進めることを阻害する課題を解決することで、MLを社会実装するスピード・品質を向上させる」
    • (補足)MLOpsとは: 「データ前処理、モデル開発、デプロイ、運用などを含む機械学習のライフサイクルを管理する技術/知見」(MLopsコミュニティ)
  • スケジュール概要

導入提案タスクのポイント

  • できるだけ具体的なケースを踏まえつつ、導入の必要性を正しく伝えるようにしました。
  • また、実施内容(→改善内容)の認識にズレが起きないようにしました。
  • 合わせて、MLOpsエンジニア側と、特にデータサイエンティスト側の追加工数について、工数感をざっくり伝えておきました。

1. 計画

計画タスクの概要

  • ヒアリング実施
  • WBS作成

計画タスクの目的

  • 案件の進め方を認識合わせし、実施する作業内容を詳細化し、WBSを作成して合意を取りました。

計画タスクの内容

  • ヒアリング事項
    • 背景
      • プロジェクト発足の経緯
    • 目的とゴール
      • 一般的なPoCフェーズの目的: フィジビリティのチェック、デプロイする価値があるかの確認
      • 「〇〇のために、××する」(目的と解き方のセット)
      • ビジネス視点でのKPIと技術的視点でのKPI
        • フェルミ推定で、技術的KPI(精度など)とビジネス的KPIを紐付ける
      • 精度目標
        • MVA(Minimum Viable Accuracy)、AVC(Accuracy Value Cureve)
        • 人の精度
    • 成果物
      • コード、モデルを顧客に提出するか、など
      • 各成果物のアウトプットイメージ
    • スケジュールとマイルストーン
      • 要件定義、モデル開発・精度検証・最終報告、システム化計画・構築フェーズ提案 → 要件定義、設計、構築、テスト、リリース、etc
    • 体制
      • チーム体制、ステークホルダー
    • データソース
      • データソースごとに整理する
      • 取得元(BQ、S3、etc)
      • データ種(テーブルデータ、csv、画像、etc)
      • カラム
      • 個人情報有無
      • ライセンス
      • データサイズ
      • データ受領方法
      • 取得するまでにかかる時間
      • 本番データとの違い
        • 分布、取得条件、更新頻度、etc
      • ラベリング
    • ソリューション
      • ブレストで洗い出し
      • ベースライン(シンプルで解釈容易なもの)
    • ラベリング
      • ラベリング方法
        • 質、一貫性の担保
    • 前処理
      • Scaling, Normalization, Standarization, Bucketing / Binning, 次元削減,,,
      • Development Data(Training, Validation), Test Data
    • 評価指標
      • 定量評価と定性評価
      • オンライン検証とオフライン検証
      • 撤退ライン
      • 許容されるエラー(優先度)
      • カテゴリごとにも上記を検討(優先度)
    • 環境
      • 外部サービス利用予定有無
        • バージョン(GAかβかαか)
        • 制約(リミット、対応リージョンなど)
      • GPU利用予定有無
      • インフラ費用見積もり
    • その他懸念事項
      • ブレスト
      • 倫理上の問題(Bias、平等性、etc)
    • プロダクション化する際の要件
      • 「システム化計画タスクの内容」参照

計画タスクのポイント

  • WBS作成では、作業内容・優先度を明細レベルで確定させ、作業ごとの完成イメージを共有し、完了条件を合意しました。
    • 予定外タスクを拾いにいくことも多いので、タスクの組み替えを相談しやすいように、優先度を明確にしておきました。
  • 計画から漏れがちなタスク
    • 整備したルール・ツール定着のためのタスク
    • メンバ追加・実験数増加(並列化)に伴うリソース拡張

2. 実験環境構築

実験環境構築タスクの概要

  • 実験規約作成(サンプルコード開発含む)
  • 学習環境構築(サンプルコード開発、利用ルール整備含む)
  • 実験管理環境構築(サンプルコード開発、利用ルール整備含む)
  • ベースライン開発フォロー

実験環境構築タスクの目的

  • データサイエンティストが実験に着手できるよう、ルールを整備・共有した上で、環境を構築・提供します。
    • 各種自動化については、「4. CI環境構築」で対応しました。
  • 下記のようなことが起こらないようにしました。(想定される課題)
    • ディレクトリ構成が直感的でない/PJ間で異なり、新規参画・引き継ぎのキャッチアップコストがかかった
    • 急遽実験回数を増やす/メンバーをアサインすることになったが、学習リソースが足りない(、既存メンバと同じ環境が作れない)
    • 後になって実験の詳細を聞かれたが、条件を辿ることができない。ノートブックを漁って探すしかない。(検索性が低い)
    • スクリプト/ノートブックが量産されるが、実行方法が不明
    • 実験の経緯や考察が残されておらず、後から説明ができない
    • 実験結果の検索が比較検討がし辛い。他メンバーと実験結果や利用したリソースを共有し、コラボレーションすることが難しい。

実験環境構築タスクの内容

  • 実験規約(wiki)の目次例
    • 0. プロジェクト概要
      • 計画タスクの内容を転記しておく(新規参画者のためにも)
    • 1. 受領データの取り扱い
      • 中間成果物含め、どのデータをどこに置いてどう権限管理するか
      • 案件終了後の削除のためにも、置き場所を管理しておく
    • 2. ドキュメント管理方針
    • 3. チケット運用ルール
      • タスク指示者がIssueを起票する
        • 完了条件を明記する
      • Issueごとにブランチを作成する
      • 中間報告などの顧客報告断面でIssueにマイルストーン、ブランチにタグを打つ
    • 4. ブランチ運用ルール
    • 5. ディレクトリ構成
      • Coockie Cutter など
    • 6. コーディング規約
      • コミットルール、READMEアジェンダ(実行手順を書くようにする)、Python開発環境、実験管理ルールなど
    • 7. 会議運営、コミュニケーション
      • 定例で、Issueとコードベースで各担当者から進捗報告する
  • 学習環境構築
    • 環境を揃えるため、Dockerで構築しました。
    • READMEに、環境構築手順だけでなく、実験の再現に必要な手順をきちんと載せるようにしました。
    • メンバ追加・実験数増加(並列化)に伴うリソース拡張に備えておくようにしました。
    • スタート時点のディレクトリ構成・Dockerファイルは、下記を参考にすることが多いです。
  • 実験管理シート作成
    • 最初はスプレッドシートなどで管理して、固まってきたらMLflowなどに移行するようにしました。
    • 詳細はこちら
    • 管理項目
      • 1. データセット(raw)管理
        • データセット正式名称,①データセット名(raw),ライセンス,ライセンス証跡URL,データ数,取得日,取得方法,保存先,担当者,備考
      • 2. データセット(加工後)管理
        • ②データセット名(前処理後),保存先,データ数,①データセット名(raw),前処理スクリプト,担当者,備考
      • 3. 実験結果管理
        • モデル名,モデル保存先,②Inputデータ,学習スクリプト,変更点サマリ,評価スクリプト,評価サマリ,顧客報告,関連IssueNo,担当者,備考
  • ベースライン開発フォロー
    • パイプラインのガワを予め作成してからデータサイエンティストに渡しました。
      • Input→スクリプト→Output→…
      • 命名規則、ディレクトリ構成を伝える意味もありました。

実験環境構築タスクのポイント

  • 後から修正するのが大変なやつは、ここで最初決めておくようにしました。一方で、データサイエンティストの手が止まらないように注意しました。
  • 上記に記載したことが定着するまでしっかりフォローしました。
  • PoCとはいえ、Issue/ブランチは0レビューだと際限なく品質が低下し、まずいことになることがあるので、どこかでチェックポイントを設ける仕組みを作りを意識しました。

3. データ基盤構築

データ基盤構築タスクの概要

  • データ基盤構築、利用ルール整備
    • ※データ基盤構築と書いていますが、ここでは広く、PoCで使うデータの置き場の整備、という意味で書いています。

データ基盤構築タスクの目的

  • 普通のシステム開発との違いとして、コードだけでなくデータもバージョン管理する必要があります。
    • 学習データが違えば、出来上がるモデルが変わってくるので、再現のためにはデータの管理も必須です。
  • 下記のようなことが起こらないようにしました。(想定される課題)
    • このモデルはどのデータで作ったかが分からないので(ローカルにしかなかったデータで今は消えてしまったので)、もう再現ができない

データ基盤構築タスクの内容

  • 今回は画像系の案件だったのですが、とにかくS3にあげるようにしました。
    • 画像データは、追加で受領したり収集したりする度に、(一応ディレクトリを分けて)S3にどんどん追加しつつ、学習やテストに利用したデータが記載されているCSVは、ファイルを分けてバージョン管理するようにしていました。
  • AWSを使う場合は、下記を参考にストレージ系のサービスを使い分けています。(EBS, EFS, S3)

データ基盤構築タスクのポイント

  • 一連の処理の中で出てくるInput/Outputを(中間生成物含めて)どこにどう管理するか考えました。(権限回り含めて)
    • データの実体とメタデータ
    • データレイク、特徴量ストア、モデルレジストリ、など
  • データ種、データ量、アクセス元、アクセス頻度、許容処理時間、インフラ費用、拡張性、可用性、などなどから考えました。

4. CI環境構築

CI環境構築タスクの概要

  • CI+実験管理パイプラインの構築(Automated pipeline)

CI環境構築タスクの目的

  • データサイエンティストのpushのタイミングで、CI+実験管理パイプラインが自動で動くようにしました。
  • 下記のようなことが起こらないようにしました。(想定される課題)
    • 後続フェーズになってから、PoC時の特定のモデルが再現できない
      • Masterブランチのスクリプトが動かない
      • 最終的に使ってなさそうなスクリプトも大量にあり、どのスクリプトをどの順序で実行すれば良いか分からない
      • モデルを再現するためにはソースだけでなくデータも必要だが、どこのどの断面のデータを使ったかが分からない

CI環境構築タスクの内容

  • CI部分は過去にここにまとめています。追加で、MLflowとも連携させるようにしました。
  • (参考)構成例 

CI環境構築タスクのポイント

  • 通常の開発におけるCIと比べて、前処理や学習で処理時間が長くなりがちです。
    • データのキャッシュ、途中実行
  • データサイエンティスト側のタスクを減らす工夫
    • pushすればいいだけで、裏側の仕組みは意識しなくて良い、を目指しました。
    • どうしても修正してもらいたい箇所も、寄せて分かりやすくしました。

5. システム化計画

システム化計画タスクの概要

  • プロダクション化する際の要件確認
  • 簡易性能テスト(処理時間、インフラコスト見積もりのため)

システム化計画タスクの目的

  • 構築フェーズが始まる前に、フィジビリティを確認しました。
  • 下記のようなことが起こらないようにしました。(想定される課題)
    • いざ構築フェーズに入ってから、ランニングコストが想定より高いことが発覚した。逆にマシンスペックを下げれば、サービスの許容処理時間を上回ってしまう
    • クラウドサービスのAPIを内部で一部利用しているが、スループット上限があり、性能要件を満たさなかった

システム化計画タスクの内容

  • チェックリスト
    • 要件概要
      • User, User Need, User Actions, ML System Iutput, ML System Learning
    • データソース
    • 処理フロー、DFD
      • 処理ごとに想定データ量と処理時間、処理頻度を整理
        • レイテンシ、バッチウィンドウ
    • アーキテクチャ構成
      • オンプレ/クラウド(AWS、GCP、etc)
        • 本番で利用しているクラウドサービス確認
      • 連携先システム、インターフェイス、調整先
      • 再学習は自動か手動か
      • オンライン/バッチ(全量・差分) × 学習/推論
        • バッチ学習+オンライン推論
          • Webアプリケーションで直接算出
          • API
        • バッチ学習+バッチ推論
          • DB参照
        • オンライン学習+オンライン推論
      • メタデータ管理(データ、モデル)
    • 機能一覧
    • コスト見積もり
      • 性能(レイテンシ、バッチウィンドウ)とのトレードオフも考えて整理する
      • 初期/ランニング × インフラ/開発工数
      • 再学習の頻度
        • 費用対効果の算出
    • 非機能要件・基本設計
      • 可用性
      • 性能・拡張性
        • 検討項目
          • レイテンシ、バッチウィンドウ、インフラコスト
        • 改善案
          • GPUのシェア、マルチモデルサービング、モデルの最適化など
          • NoSQLの利用(キャッシュ)
          • 水平スケール
      • 運用・保守性
        • → 運用作業一覧と役割分担
        • 問い合わせ、障害対応
        • 監視
          • 対象
            • 入力データ・推論結果
            • データの長さ・大きさ、欠損値、輝度、レスポンスタイム、CTR
          • 手法
            • 検知
              • 人を雇ってラベリングして予測結果と比較
            • アラート
            • 対応
              • 予測誤りをどこで吸収するか
                • human in the loop
        • 保守改修
        • デプロイ
          • ロールバック、シャドーモードデプロイ、カナリアデプロイ、BlueGreenデプロイ(A/B)、etc
        • データ分析
        • A/Bテスト
          • 継続的なA/Bテスト
    • 成果物
    • スケジュールとマイルストーン
    • 体制
      • ベンダ(構築、運用・保守)と役割分担
        • モジュール受け渡し方法
        • 本番環境への接続方法、申請
    • その他懸念事項
      • ブレストする
      • モデルの精度が下がる可能性のある要因を考える。データの傾向が変わるなど。

システム化計画タスクのポイント

  • フィジビリティはきっちり確認しつつ、後続の構築フェーズへスムーズに繋げられるように整理しました。

おわりに

  • 感想
    • 上記の通りルールやツールを整備することで、MLプロジェクトのPoCフェーズにおける品質をある程度向上・効率化させることができました。
    • 改めて、特にメンバは、毎週の顧客定例への進捗出しで必死だったりするので、「後から」「他の人が」参照できる(再現できる)かとかを考える余裕がないのはある程度仕方がない面もあるのかなと感じました。
      • → なので、それを前提として、基本的には仕組みで(自動化で)解決していく必要があると思いました。
    • MLOpsエンジニアとしては、どこまで実験の中身に踏み込むかは毎回悩んでいます。
      • 動かないノートブックがあったらこっちで直すか、とか。
      • 一つの案件に工数を割きすぎるとスケールしないが、一方でルールやツールを整備しても定着までやらないと意味がない、などなど。悩ましいです。
  • これからやりたいこと
    • 特徴量ストアの導入
      • 「ビッグデータと機械学習の世界を隔てる境界線」
    • MLパイプラインの導入
      • Kedroを実践投入したいです。
      • 特にやりたいことは、データ入出力処理の切り出しと共通化・処理の依存関係定義です。
      • 処理ごとにコンテナが別れるなら、Kubeflowなども検討しようと思います。

コメントする