데이터 사이언스, 머신러닝 프로젝트를 수행하기 위해서는 다양한 파라미터를 실험하는 과정이 동반됩니다. 이번 글에서는 파라미터와 설정값을 간결하게 관리하고 사용할 수 있게 도와주는 Hydra에 대해 알아보도록 하겠습니다.

1. Hydra란

Hydra는 페이스북에서 오픈소스로 공개한 프레임워크로, 어플리케이션에서 사용하는 여러가지 설정값을 관리할 수 있는 기능을 제공합니다.

직접 사용해본 Hydra는 아주 명확한 특징을 가지고 있습니다.

  1. 모든 설정 및 파라미터 값은 config.yaml로 관리하고 계층적으로 설정
  2. 그러한 와중에 command-line을 통해서 오버라이딩(overriding) 가능
  3. 한번의 명령어로 각각 다른 값을 대입하여 다중 실행 가능

이렇게 설명해도 와닿지 않을 수가 있겠죠. 그럴 때 저는 이렇게 설명합니다.

“더 이상 실험 한번 돌릴 때마다 파라미터 값을 스프레드시트에 적어두지 않아도 돼”

2. Hydra 기본적인 사용 방법

2.1. 설치하기

pip install hydra-core --upgrade

2.2. Hydra로 Config 불러오기

2.2.1. Config 저장 형태

기본적으로 Hydra에서는 Yaml형태로 config값들을 저장합니다.

예를 들어, 아래와 같은 파일 구조를 가지고 있다고 할 때,

.
├── config
│   └── config.yaml
└── app.py

config.yaml 파일에 파라미터를 정의해보았습니다.

# ./config/config.yaml

train_params:
  epoch: 5
  batch_size: 10
  learning_rate: 1e-4

2.2.2. Config 불러오기

실제로 config를 불러올 어플리케이션에서는 경로와 파일명을 전달하여 config를 불러옵니다. 이렇게 불러온 config의 데이터타입은 DictConfig 입니다.

# ./app.py

import hydra

@hydra.main(config_path="config", config_name="config")
def func(config):

    # access elements of the config
    print(type(config))
    print(config)

if __name__ == "__main__":
    func()
$ python app.py

    <class 'omegaconf.dictconfig.DictConfig'>
    {'train_params': {'epoch': 5, 'batch_size': 10, 'learning_rate': 0.0001}}

Hydra는 ./output 디렉토리 아래 각 실행마다 결과 또는 로그의 출력을 저장합니다.

.
├── app.py
├── config
│   └── config.yaml
└── outputs
    └── 2021-11-07
        └── 22-11-07
            └── app.log

3. Config값 오버라이드 하기

앞서 예시의 config.yaml 파일에서는 epoch를 5, batch_size는 10으로 설정했습니다. 그렇다면 다음 실험은 epoch를 2, batch_size는 10로 설정하고 싶다면 config 파일을 내용을 수정해야 할 까요?

Hydra는 command line에서 config 값에 대한 파라미터 오버라이팅을 지원하기 때문에, 파일의 내용을 수정할 필요가 없습니다.

아래의 명령어를 보면 이해가 빠를 것 같은데요, command line에서 epoch값을 2로 오버라이드 한 실행 결과입니다.

$ python app.py train_params.epoch=2

    <class 'omegaconf.dictconfig.DictConfig'>
    {'train_params': {'epoch': 2, 'batch_size': 10, 'learning_rate': 0.0001}}

애초에 설정하지 않았던 값을 +를 통해 추가할 수도 있습니다.

$ python app.py train_params.epoch=2 +train_params.random_state=42

    <class 'omegaconf.dictconfig.DictConfig'>
    {'train_params': {'epoch': 2, 'batch_size': 10, 'learning_rate': 0.0001, 'random_state': 42}}

+) Config Group 을 적용하면 더욱 다양하고 복잡한 형태의 config 오버라이딩이 가능합니다.

4. Hydra를 통해 다중실행하기

Hydra에서는 --multiruns 인자를 통한 다중 수행을 할 수 있다는 것도 아주 유용합니다.

$ python app.py --multirun train_params.learning_rate=0.0001,0.001,0.01,0.1

        [2021-11-07 23:09:31,088][HYDRA] Launching 4 jobs locally
        [2021-11-07 23:09:31,088][HYDRA]        #0 : train_params.learning_rate=0.0001
        <class 'omegaconf.dictconfig.DictConfig'>
        {'train_params': {'epoch': 5, 'batch_size': 10, 'learning_rate': 0.0001}}
        [2021-11-07 23:09:31,156][HYDRA]        #1 : train_params.learning_rate=0.001
        <class 'omegaconf.dictconfig.DictConfig'>
        {'train_params': {'epoch': 5, 'batch_size': 10, 'learning_rate': 0.001}}
        [2021-11-07 23:09:31,230][HYDRA]        #2 : train_params.learning_rate=0.01
        <class 'omegaconf.dictconfig.DictConfig'>
        {'train_params': {'epoch': 5, 'batch_size': 10, 'learning_rate': 0.01}}
        [2021-11-07 23:09:31,297][HYDRA]        #3 : train_params.learning_rate=0.1
        <class 'omegaconf.dictconfig.DictConfig'>
        {'train_params': {'epoch': 5, 'batch_size': 10, 'learning_rate': 0.1}}

+) Hydra는 기본적으로 다중실행을 순차적으로 수행하지만, 병렬 실행을 하고자 한다면 Joblib Launcher가 동반되어야 합니다.

마무리하며

처음에는 데이터 모델을 실험할 때 config를 쉽게 관리할 수 있는 방법에 대해서 찾아보는 중에 Hydra를 발견하게 되었습니다. 하지만 사용법에 대해 알아보면서, 단순히 데이터사이언스와 머신러닝 뿐만 아니라 그 외 어플리케이션에도 다양하게 접목할 수 있는 유용한 프레임워크라는 생각이 드네요. 더욱 고도화해서 실제 프로젝트에 접목할 방법을 구상해봐야겠습니다.

Reference