Python

[파이썬] YAML 설정 파일로 ML 실험 관리하기 - pyyaml 기본 패턴

weweGH 2026. 7. 16. 09:00
반응형

YAML 설정 파일로 ML 실험 관리
YAML 설정 파일로 ML 실험 관리


YAML 설정 파일로 ML 실험 관리하기 - pyyaml 기본 패턴


들어가며


머신러닝 프로젝트를 진행하다 보면 학습률, 배치 사이즈, Epoch 수 등 수많은 하이퍼파라미터를 반복적으로 수정하게 됩니다. 이 값들을 파이썬 코드 안에 직접 작성하면, 실험할 때마다 코드를 열고 수정해야 하는 문제가 생깁니다.

예를 들어, 학습률 0.001로 실험한 뒤 0.01로 바꿔보고 싶다면 어떻게 할까요? 코드를 직접 수정하면 이전 값을 기록해두지 않는 이상 어떤 조건에서 어떤 결과가 나왔는지 추적하기 어렵습니다.

YAML 파일을 활용하면 설정값을 코드와 분리하여 관리할 수 있습니다. 코드는 건드리지 않고 YAML 파일만 수정하는 것으로 실험 환경을 전환할 수 있으며, 파일별로 버전을 관리하면 실험 조건 추적도 용이합니다.

이 글에서는 pyyaml 라이브러리를 사용하여 ML 프로젝트의 하이퍼파라미터를 YAML 파일로 분리하는 기본 패턴을 소개합니다.



YAML이란?


YAML"YAML Ain't Markup Language"의 약자로, 사람이 읽고 쓰기 편한 데이터 직렬화 형식입니다. JSON과 유사하지만 들여 쓰기 기반의 계층 구조로 표현하여 가독성이 높습니다.

머신러닝 프레임워크(PyTorch, Hugging Face, MMDetection 등)에서 설정 파일 형식으로 널리 사용됩니다.

  • 가독성 | 들여쓰기 기반 구조로 직관적으로 읽힘
  • 계층 표현 | 중첩된 설정값을 명확하게 표현 가능
  • 주석 지원 | '#'으로 주석 작성 가능 (JSON은 불가)
  • 다양한 언어 지원 | Python, Java, Go 등 대부분의 언어에서 파싱 가능

[ 사전 준비 - pyyaml 설치 ]

파이썬에서 YAML 파일을 읽으려면 pyyaml 라이브러리가 필요합니다. 설치 시 이름(pyyaml)과 임포트 시 이름(yaml)이 다르다는 점에 주의합니다.

pip install pyyaml

설치 후 아래와 같이 import 합니다.

import yaml  # pyyaml 설치 후 yaml로 임포트
반응형

YAML을 활용한 파이썬 예제


[ 파일 구성 ]

프로젝트 루트에 아래 두 파일을 생성합니다.

project/
├── config.yaml   # 설정 파일
└── train.py      # 학습 코드

[ config.yaml - 설정 파일 ]

모델 구조, 학습 파라미터, 데이터 경로를 계층적으로 정의합니다.

※ YAML은 들여 쓰기로 계층 구조를 표현합니다. 탭(Tab) 대신 반드시 스페이스를 사용해야 하며, 일반적으로 2칸을 기준으로 합니다.

model:
  name: resnet50
  num_classes: 10

train:
  epochs: 50
  batch_size: 32
  learning_rate: 0.001
  optimizer: adam

data:
  train_path: ./data/train
  val_path: ./data/val
문법 예시 설명
키-값 쌍 name: resnet50 콜론(:) 뒤에 공백 필수
계층 구조 하위 키를 2칸 들여씀 중첩 딕셔너리로 파싱됨
주석 # 이 부분은 주석 # 이후 내용은 무시
정수/실수 epochs: 50, lr: 0.001 따옴표 없이 작성 시 숫자로 파싱
문자열 name: resnet50 일반 텍스트는 자동으로 문자열 처리

[ 파이썬 코드 ]

yaml.safe_load()로 설정 파일을 읽어 딕셔너리로 불러옵니다. 이후 키를 통해 각 값에 접근합니다. safe_load()의 반환값은 일반 Python 딕셔너리이므로, 익숙한 딕셔너리 접근 방식(config["키"])을 그대로 사용할 수 있습니다.

import yaml

# YAML 파일 읽기
with open("config.yaml", "r") as f:
    config = yaml.safe_load(f)

# 설정값 불러오기
model_name = config["model"]["name"]
num_classes = config["model"]["num_classes"]
epochs      = config["train"]["epochs"]
batch_size  = config["train"]["batch_size"]
lr          = config["train"]["learning_rate"]
optimizer   = config["train"]["optimizer"]

print(f"모델: {model_name} (클래스 수: {num_classes})")
print(f"학습 시작 — epochs: {epochs}, batch_size: {batch_size}, lr: {lr}, optimizer: {optimizer}")
print()

# 실제 학습 루프 예시
for epoch in range(epochs):
    # 실제 프로젝트에서는 이 자리에 모델 학습 코드가 위치함
    print(f"Epoch {epoch+1}/{epochs} 학습 중... (lr={lr})")

[ 실행 결과 ]

위 코드를 실행하면 다음과 같이 출력됩니다.

모델: resnet50 (클래스 수: 10)
학습 시작 — epochs: 50, batch_size: 32, lr: 0.001, optimizer: adam

Epoch 1/50 학습 중... (lr=0.001)
Epoch 2/50 학습 중... (lr=0.001)
...
Epoch 50/50 학습 중... (lr=0.001)

YAML의 장점


코드 수정 없이 실험 전환 

학습률을 바꾸고 싶다면 train.py는 전혀 수정하지 않고, config.yaml의 한 줄만 바꾸면 됩니다.

# 변경 전
train:
  learning_rate: 0.001

# 변경 후
train:
  learning_rate: 0.01  # 0.001 → 0.01 로 변경

실험 버전 관리

실험마다 config_v1.yaml, config_v2.yaml과 같이 설정 파일을 별도로 저장하면 어떤 조건에서 어떤 결과가 나왔는지 추적할 수 있습니다.

project/
├── config_v1.yaml   # lr=0.001, epochs=50
├── config_v2.yaml   # lr=0.01,  epochs=100
└── train.py

train.py를 실행할 때 파일명을 인자로 받도록 작성하면, 같은 코드로 여러 설정을 실험할 수 있습니다.

## train.py

import yaml
import sys

# 실행 시 설정 파일을 인자로 받음
# 사용 예: python train.py config_v2.yaml
config_path = sys.argv[1] if len(sys.argv) > 1 else "config.yaml"

with open(config_path, "r") as f:
    config = yaml.safe_load(f)

print(f"설정 파일: {config_path}")
print(f"학습률: {config['train']['learning_rate']}")

YAML 주의사항


주의 1. safe_load를 사용해야 하는 이유

yaml.load()는 YAML 파일 안에 포함된 임의의 Python 객체를 실행할 수 있어 보안상 위험합니다. 외부에서 전달받은 파일이나 사용자 입력이 포함된 파일을 읽을 때는 반드시 yaml.safe_load()를 사용합니다.

  • (주의) yaml.load(f, Loader=yaml.FullLoader)
    : 전체 YAML 객체 파싱, 임의 코드 실행 가능
  • (권장) yaml.safe_load(f)
    : 안전한 기본 타입만 파싱 (dict, list, str, int, float 등)

주의 2. 들여 쓰기 오류

YAML 파싱 오류의 대부분은 들여쓰기 불일치에서 발생합니다. 탭과 스페이스를 혼용하면 yaml.scanner.ScannerError가 발생합니다. 에디터에서 탭을 스페이스로 자동 변환하는 설정을 활성화해 두는 것을 권장합니다.


마무리하며

YAML 설정 파일 분리는 ML 프로젝트에서 유용한 실험 관리 습관 중 하나입니다. pyyamlyaml.safe_load()만으로 하이퍼파라미터를 코드 밖으로 꺼낼 수 있으며, 반환값이 일반 Python 딕셔너리이므로 별도의 학습 없이 바로 적용할 수 있습니다. 설정 파일을 실험마다 별도 파일로 저장해 두면 어떤 조건에서 어떤 결과가 나왔는지 언제든 재현할 수 있습니다. 프로젝트 규모가 커지면 Hydra나 OmegaConf로 전환하는 것도 고려할 수 있지만, 시작은 이 패턴으로도 충분합니다.


반응형