ハイパラ設定だけじゃない!hydraで始めるconfig管理

こんにちは。機械学習エンジニアのwasatingです。

皆さんはhydra使っていますか?
コマンドラインでハイパラの設定ができることから、機械学習の実験を回す際に重宝するため、私も今更ながら活用し始めました。

活用していく中で、細かいconfigの設定にも便利であることに気づいたため、ハイパラ設定以外の用法でもhydraはいいぞ。といった話をしていきたいと思います。

hydraについて

hydraはmeta(旧facebook)が公開しているOSSで、configファイルの書き換え等をせずに設定値をコマンドラインで上書きができるため、余計な手間を省けることを売りにしています。
そのため、上述したように機械学習の実験との相性がとても良いです。

使い方の説明として、まず以下のようなディレクトリ構成とファイルを想定します

.
├── conf
│   └── config.yaml
└── main.py
# main.py
import hydra
from omegaconf import DictConfig, OmegaConf

@hydra.main(version_base=None, config_path="conf", config_name="config")
def main(cfg : DictConfig) -> None:
    print(OmegaConf.to_yaml(cfg)) # dict形式のconfigをyaml形式にして可読性を高めている

if __name__ == "__main__":
    main()
# config.yaml
output_conf:
  output_dir: /path/to/output/dir
  suffix: .pq
hparams:
  lr: 1e-4
  batch_size: 16
  epoch: 5
data_dir: /path/to/data/dir


この時、main.pyを実行時に、以下のようにコマンドラインで指定した設定値を変更することが可能になります。

$ python main.py

output_conf:
  output_dir: /path/to/output/dir
  suffix: .pq
hparams:
  lr: 0.0001
  batch_size: 16
  epoch: 5
data_dir: /path/to/data/dir
$ python main.py hparams.lr=1e-3

output_conf:
  output_dir: /path/to/output/dir
  suffix: .pq
hparams:
  lr: 0.001 # コマンドラインでの変更箇所
  batch_size: 16
  epoch: 5
data_dir: /path/to/data/dir

hydraによるconfig管理

先ほどの例では単純な設定のみですが、実際は実験を回す前に、例えばデバッグ用にboolの追加やdata_dirを変更したりなど、複数の設定の変更が必要になってくると思います。
しかし、それらを全てコマンドラインで入力して変更するのはあまりにも手間がかかってしまいます。

そこで、ここからはhydraを用いて設定値を簡単に一括で変更する方法について紹介していきたいと思います

ディレクトリ構成とyamlファイル群

例として、DEBUG用に設定を変えるシチュエーションを想定します。

先ほど示したディレクトリ構成、config.yamlの変更、および追加でDEBUG時を想定したyamlファイルの作成をし、以下のようにします。

.
├── conf
│   ├── config.yaml
│   ├── env
│   │   └── debug.yaml
│   ├── hparams
│   │   └── hparams.yaml
│   └── output_conf
│       ├── default_output_conf.yaml
│       └── for_debug.yaml
└── main.py
# config.yaml
defaults:
  - _self_
  - hparams: hparams
  - output_conf: default_output_conf

data_dir: /path/to/data/dir
DEBUG: false
# env/debug.yaml
# @package _global_
defaults:
  - override /output_conf: for_debug

hparams:
  epoch: 1

data_dir: /path/to/debug/data/dir
DEBUG: true
# hparams/hparams.yaml
lr: 1e-4
batch_size: 16
epoch: 5
# output_conf/default_output_conf.yaml
output_dir: /path/to/output/dir
suffix: .pq
# output_conf/for_debug.yaml
output_dir: /path/to/debug/output/dir
suffix: .csv

コマンドラインでのconfigの一括書き換え

この状態でまず普通にmain.pyを実行すると以下のようになります。

$ python main.py
 
data_dir: /path/to/data/dir
DEBUG: false
hparams:
  lr: 0.0001
  batch_size: 16
  epoch: 5
output_conf:
  output_dir: /path/to/output/dir
  suffix: .pq

config.yaml内でdefalutsに含まれているものは、keyをディレクトリ、valueをyamlファイル名として対象のyamlを読み込み、反映しています。
またdefaults外のものは、最初の例と同様の扱いとなっています。

これをDEBUG時の設定に変更するのはとても簡単で、以下のようにコマンドラインに追加するだけです。

$ python main.py +env=debug

data_dir: /path/to/debug/data/dir
DEBUG: true
hparams:
  lr: 0.0001
  batch_size: 16
  epoch: 1
output_conf:
  output_dir: /path/to/debug/output/dir
  suffix: .csv

これにより、config.yamlで設定した値がenvディレクトリ下のdebug.yamlで設定した値によって上書きが行われています。

また、まとめて設定値を変更したうえで、最初の例同様、特定の設定値を追加で変更することも可能です。

$ python main.py +env=debug hparams.batch_size=8
data_dir: /path/to/debug/data/dir
DEBUG: true
hparams:
  lr: 0.0001
  batch_size: 8 # コマンドラインでの変更箇所
  epoch: 1
output_conf:
  output_dir: /path/to/debug/output/dir
  suffix: .csv

おわりに

以上hydraはハイパラ設定以外にも便利という話でした。
正直まだ使いこなせている感じはしないですが、こういったツールとうまく付き合っていきたいものですね

公式に、将来的にAWSとのつなぎこみもうまいことやる予定といった記述もあるので今後の動向にも期待したいです。*1