短期の機械学習プロジェクトにおけるconfig管理の最適解について

概要
hydraを使ってる人が多いように見えるが、自分はメリットがあまり理解できなかった。
そもそも何が欲しいんだっけ?を整理する意味で自分が現状行なっているコンフィグ管理のメリットとデメリットを整理する。
なお、この運用方法は自分で思いついたものではなく、過去のKaggleコンペの入賞コード[1]で使われたものをアレンジしたもの。以降の記述はこれを1年程度運用して得た所感を反映したものになっている。
前提
実務での運用のようにある長期間の運用フェーズにあるプロジェクトではなく、Kaggleのようなプロジェクトを想定している。具体的には、管理中にコードがfixしておらず、実験を進めながら試行錯誤しながら管理するもので、かつ短期間(1〜3ヶ月)でコードベースを凍結するようなプロジェクト。
現状の運用
SimpleNamespace
を使っている。運用方法としては、conf
配下にv0001.py
というファイルを追加していく。
conf/
- v0001.py
- v0002.py
- ...
中身は以下のような感じ:
from types import SimpleNamespace
cfg = SimpleNamespace()
cfg.batch_size = 32
cfg.lr = 1e-4
...
メリット
- dictだと
conf["hoge"]
のように[""]
をいちいち打ち込むのが面倒だが、SimpleNamespaceはオブジェクトの参照conf.hoge
で書けるのでタイピング量が少なく可読性も高い。 - pythonのプログラムが書けるのでadaptiveに決まる設定をカジュアルに書ける(例:
cfg.lr = cfg.base_lr / cfg.batch_size * 128
)。特に、Albumentationsのaugmentationの設定など、シリアライズが面倒な設定もconfigでオブジェクト定義すれば特に悩む必要なく書ける。 - wandbのような実験管理ツールにコンフィグの値をまとめて渡すのがしやすい(
cfg.__dict__
で渡せる)。自前のクラスを定義する場合はオブジェクトの元からある属性とコンフィグパラメータを明確に区別するのが難しく、「アンダースコアで始まらない属性をgetattr
で取得する」といったややロバストさに欠けるコードが必要になる(まぁ「アンダースコアから始まるパラメータは使用しない」と決めておけばそこまで問題ではない)。
class Config:
batch_size = 32
lr = 1e-4
...
デメリット
- ロードのコードは少し冗長になる(後述)が、utilとかで関数定義定義すればそんなに問題にはならない。
- 階層的な記述ができない。ただし、addictのように階層的記述ができるものもある。また、そもそも階層的に管理しないといけないほど複雑化するんだっけ?というのもある。
- pythonコードが書けるのはメリットでもある反面、コンフィグが定義順序に依存する、というデメリットもある。
1について、以下のコードをスクリプトの最初に1度だけ記述する。
from importlib import import_module
# CONFIG_VERSIONはスクリプトの引数などで渡す
cfg = import_module(f"config.v{CONFIG_VERSION:04d}").cfg
さらにあると良い機能
- スクリプトの引数でconfigを上書きするコードを書くのが面倒なので、両者を透過的に扱えると良い(hydraにこの機能あるのだったか?)
- Pylanceなどの静的解析ツールでコード補完できると便利なのでスキーマが定義できるとよい(hydraでできるはず)。ただし、スキーマとconfig自身と同期しながら管理する必要があり、管理コストは増加する。特に、試行錯誤段階ではスキーマの変更が頻発するので管理コストの方が得られるメリットより大きくなるかもしれない。
参考

現状の運用に関する補足: コンフィグのdefault値を指定する
毎回コンフィグするのがコピペ面倒な場合は、default.py
みたいなのを定義しておいて各configから呼べば良い。
cfg = SimpleNamespace()
cfg.batch_size = 32
cfg.lr = 1e-4
...
from conf.default import cfg
cfg.batch_size = 64
...

後方互換性の担保について
スキーマや格納している値の意味を変更する際、後方互換性を保持するためのリファクタリングが都度発生するが、これはどの実験管理ツールにもつきまとうものだと思う。

試行錯誤段階の実験パラメータを全部再現できる必要あるのか?問題
パラメータを少し変えるだけでコンフィグファイルのコピペが発生するのは面倒といえば面倒。カジュアルに実験を繰り返していくと数百ファイルくらいは軽く到達する。それぞれのconfigは何が違うのか?が分かりにくくなる(現状はexcelシートでconfigごとの違いを一覧できるようにしてある)。
Optunaのようにパラメータ探索する場合の相性
あまり試したことがないが、Optunaなどのパラメータ探索ツールとの相性が良いのか?という観点もある。

Hydraが少し複雑な研究プロジェクトでのコンフィグ管理のために生まれたことを考えると、要件は自分のケースと合ってそうに見える。
This addresses challenges that can arise when modifying a config, such as having to maintain many slightly different copies of a configuration, or adding custom logic to override individual configuration values.
Dynamic command-line tab completion, which helps with discoverability of complex configurations and reduces user errors
Hydra is already in use at Facebook to prototype complex research projects.