Skip to the content.

[WIP]Data model versioning pattern

Usecase

Architecture

機械学習モデルのバージョニングは難しい。モデルを一つ作成し本番環境にデプロイするだけでも、その過程でバージョン管理される様々なコンポーネントが存在する。

再現性のある学習および推論を行うためには、これらをバージョン管理し、常に同じバージョンで再現実行できる必要がある。各コンポーネントは別々のレポジトリやDWHで管理されるため、それらの間で一意性のあるバージョニングを行うことが望ましい。
バージョニングとして以下を推奨する。
model-name x.y.z-data.split

モデル名(MODEL-NAME x.y.z-data.split

モデルには名称を付けるべきだ。チーム内外でモデルの有無や特定ができない状態を避けるためにも、名前がない状態は避けるべきだ。また、名前があるほうが愛着もわきやすい。名称には価値(株価予測、違反検知、顔認証等)や機能(画像分類、回帰、リランキング等)を使うとわかりやすいが、チームで独自の命名基準があるのであれば、その基準で命名すれば良い。

リリースバージョン(model-name X.y.z-data.split

モデルのバージョンにはリリース前とリリース済みがある。リリース前はmodel-name X.y.z-data.splitXを0としておき、リリース時に1以上の値を入れる。

インターフェイスバージョン(model-name x.Y.z-data.split

機械学習のモデルは入力データに対して推論結果を出力する。用途や内部のアルゴリズムに違いがあるとしても、入力データに対して推論結果を出力する方式は普遍的である。入出力の形式が変わると外部インターフェイスも同時に変更が必要になるため、インターフェイスをバージョン管理し、外部システムとバージョンを一致させると良いだろう。各インターフェイスの型や形式はコードレポジトリで管理される。外部向けにはSwaggerやProtocol BufferでAPI定義を公開すると良いだろう。インターフェイスバージョンでは入出力の方式のみを定義し、内部のアルゴリズムやライブラリ、モデルの評価値は管理しない。アルゴリズムやライブラリはロジックバージョンで管理される。モデルの評価値はモデルのバージョン管理とともにモデルレポジトリ等で管理すると良い。インターフェイスバージョンは0から始まり、入力または出力を変えるごとに数値をインクリメントし、インターフェイス定義を一意のバージョンに一致させると良い。

ロジックバージョン(model-name x.y.Z-data.split

機械学習の学習や推論ロジックには各種前処理やアルゴリズム(線形回帰、ロジスティック回帰、SVM、CNN等)、最適化手法や損失が用意されているが、その実行方法は各種言語やライブラリによって異なり、チューニング可能なパラメータも多様である。ロジックバージョンはインターフェイスの変更を伴わない前処理、アルゴリズム、ライブラリ、パラメータの選択を司る。これらの変更は多くの場合、コードレポジトリのブランチとして管理される。アルゴリズムやライブラリ、パラメータの選択はモデル開発の実験段階で多種多様に検証されるが、その全てをバージョン管理する必要はない(全てをバージョン管理するとなると、数十以上のバージョンができあがるだろう)。モデルの評価がチームレビュー可能になった時や、レビュー済みモデルを改善できた時にバージョニングすれば良いだろう。
同じアルゴリズムやパラメータでも、学習によってモデルの評価値(損失)にばらつきが発生する場合がある。その場合はモデルレポジトリで学習をバージョニングする。学習によるばらつきはアンコントローラブルであるため、モデルとしてバージョン管理するのではなく、学習とその評価値として管理する。

データ取得バージョン(model-name x.y.z-DATA.split)、データ格納バージョン(model-name x.y.z-data.SPLIT

データは一般的にDWHで管理される。学習で使用するデータは学習時に確定するため、データを学習データ、検証データ(とテストデータ)を分割した状態で記録しておくと良いだろう。データのバージョン管理で重要なのは、同じデータを取得できることと、学習データと検証データが混在しないこと(つまり、正常にモデルを評価できること)である。データは取得方法と分割された状態の両方をバージョン管理し、再取得可能にしておくことを推奨する。同時に、取得したデータは任意の環境に保存しておくことで、同じデータでの学習や評価を再現可能にしておくと良いだろう(構造化データであればテーブル形式で保存し、非構造化データであればzip等で固めてオブジェクトストレージやファイルストレージに格納しておくと良いだろう)。
データのバージョン管理には取得方法のバージョン(model-name x.y.z-DATA.split)と分割データのバージョン(model-name x.y.z-data.SPLIT)が必要である。それぞれは数値バージョンではなく、文字や数値、記号を用いた名称にすると良いだろう。取得日時を用いても良い。取得方法(SELECT文やData pipeline定義)はGithub等コードレポジトリで管理するが、分割データは格納場所で管理する。


インターフェイスやロジック、データ取得はプログラムに定義されるものになるため、コードレポジトリ(GithubやGitlab等)で管理される。ブランチによってバージョニングすれば、コードレポジトリのワークフローとモデルのバージョンを一致して管理することができる。
出力されたモデルファイルとその評価(および学習)はモデルレポジトリで管理すると良いだろう。モデルレポジトリのサービスやソフトウェアは存在するが、現状ではスタンダードなものは存在しないため、バージョニングのワークフローは利用するソフトウェアの仕様に合わせることになる。
取得し分割したデータは各種DWHやストレージに格納する。バージョンはデータ名(テーブル名やストレージのバケット名)で管理すると汎用性が高い。

Diagram

Versioning

diagram0

Version control in each stage

diagram1

Pros

Cons

Needs consideration