이번 편에서는 간단한 예제로 살펴본 Hydra를 이용한 어플리케이션 구성 내용에 이어 lightning-transformers을 사례를 보면서 정리해보겠습니다.

conf/
┣ backbone/  # Configs defining the backbone of the model/pre-trained model if any
┣ dataset/ # Configs defining datasets
┣ optimizer/ # Configs for optimizers
┣ scheduler/ # Configs for schedulers
┣ task/ # Configs defining the task, and any task specific parameters
┣ tokenizer/ # Configs defining tokenizers, if any.
┣ trainer/ # Configs defining PyTorch Lightning Trainers, with different configurations
┣ training/ # Configs defining training specific parameters, such as batch size.
┗ config.yaml # The main entrypoint containing all our chosen config components

먼저 가장 기본이 되는 config.yaml을 정의합니다. 아래의 예시를 보면 lightning-transformers에서는 [conf/config.yaml](<https://github.com/PyTorchLightning/lightning-transformers/blob/master/conf/config.yaml>)에서 defaults로 task, optimizer, scheduler, training, trainer로 하위 계층 구조를 정의하고 있습니다.

defaults: # loads default configs
  - task: default
  - optimizer: adamw
  - scheduler: linear_schedule_with_warmup
  - training: default
  - trainer: default

experiment_name: ${now:%Y-%m-%d}_${now:%H-%M-%S}
log: False
ignore_warnings: True # todo: check warnings before release

주) now는 Hydra에서 미리 등록되어 사용할 수 있습니다. https://github.com/facebookresearch/hydra/blob/master/hydra/core/utils.py#L185

다음으로 [conf/task/default.yaml](<https://github.com/PyTorchLightning/lightning-transformers/blob/master/conf/task/default.yaml>)를 살펴보면, package와 _group_ 개념이 사용되고 있습니다.

conf/task/default.yaml

# @package task
defaults:
  - /dataset@_group_: default

# By default we turn off recursive instantiation, allowing the user to instantiate themselves at the appropriate times.
_recursive_: false

_target_: lightning_transformers.core.model.TaskTransformer
optimizer: ${optimizer}
scheduler: ${scheduler}

dataset의 config group을 default로 설정하였기 때문에, [conf/dataset/default.yaml](<https://github.com/PyTorchLightning/lightning-transformers/blob/master/conf/dataset/default.yaml>)을 로드합니다. 또한 optimizer와 scheduler는 각각 conf/config.yaml에서 앞서 정의된 optimizer와 scheduler를 변수로 받습니다. _recursive_ 는 해당 파일에 종속된 다른 config들을 instantiate 할 것인지를 나타냅니다.


대표적인 예로 LanguageModeling를 살펴봅니다.

python train.py task=nlp/language_modeling

train.py를 살펴보면 가장 기본이 되는 conf/config.yaml config_path와 config_name을 정의하고 있습니다.

"""The shell entry point `$ pl-transformers-train` is also available"""
import hydra
from omegaconf import DictConfig

from lightning_transformers.cli.train import main

@hydra.main(config_path="./conf", config_name="config")
def hydra_entry(cfg: DictConfig) -> None:
    main(cfg)

if __name__ == "__main__":
    hydra_entry()

conf/config.yaml

defaults: # loads default configs
  - task: default
  - optimizer: adamw
  - scheduler: linear_schedule_with_warmup
  - training: default
  - trainer: default

experiment_name: ${now:%Y-%m-%d}_${now:%H-%M-%S}
log: False
ignore_warnings: True # todo: check warnings before release

이전 편에서 배운 overrding을 살펴봅니다. 예를 들어 Q. batch 사이즈를 바꾸고 싶은데 어떻게 해야할까요? batch 사이즈는 training/default.yaml에 정의되어 있습니다. 따라서 CLI 명령어에 training.batch_size=8 등을 추가하면 변경이 됩니다.

conf/training/default.yaml

run_test_after_fit: True
lr: 5e-5
output_dir: '.'

# read in dataset
batch_size: 16
num_workers: 16

python train.py task=nlp/language_modeling training.batch_size=8