> EulerForge > 튜토리얼 > 12. 하이퍼파라미터 탐색 (Grid / Random / Bayes)

12. 하이퍼파라미터 탐색 (Grid / Random / Bayes)

eulerforge grid 명령으로 학습률, LoRA rank, 적용 레이어, attention 대상 등 하이퍼파라미터를 체계적으로 탐색합니다.


준비

Optuna 설치:

pip install eulerforge[hpo]

빠른 시작

# 1. 예시 spec으로 dry-run (검증만)
eulerforge grid configs/grid/sft_random_search.yml --dry-run

# 2. 실제 실행
eulerforge grid configs/grid/sft_random_search.yml

완료 후 outputs/grid/sft_random/summary.json에 결과가 저장됩니다.


YAML Spec 구조

version: 1
base_preset: "configs/presets/qwen3.5_0.8b_dense_lora_sft.yml"  # 기반 설정

run:
  output_root: "outputs/grid"       # 결과 저장 디렉토리
  max_trials: 10                    # 최대 trial 횟수
  max_train_steps: 500              # 각 trial의 학습 스텝 수

  data:                             # 선택사항 (없으면 base_preset 데이터 사용)
    format: "raw"
    task: "sft"
    path: "data/sft_10k_raw.jsonl"

  objective:
    direction: "minimize"           # "minimize" | "maximize"
    metric: "train/total_loss"      # metrics.jsonl의 키
    step_agg: "last"                # "last" | "min" | "mean"

search:
  method: "random"                  # "grid" | "random" | "bayes"
  sampler:
    seed: 42
  space:
    - name: "training.lr"
      type: "float"
      low: 1e-6
      high: 3e-4
      log: true

    - name: "injection.lora_r"
      type: "int"
      low: 8
      high: 64
      step: 8

    - name: "injection.lora_dropout"
      type: "categorical"
      choices: [0.0, 0.05, 0.1]

탐색 가능한 파라미터 (Space 레퍼런스)

space에는 base_preset의 어떤 설정이든 dot-path로 지정할 수 있습니다. 아래는 실전에서 탐색 효과가 큰 파라미터를 카테고리별로 정리한 것입니다.

학습 파라미터 (training.*)

파라미터 설명 추천 탐색 범위 비고
training.lr 학습률 1e-6 ~ 3e-4 (log) 가장 중요, 반드시 탐색
training.weight_decay L2 정규화 0.0 ~ 0.1
training.warmup_steps warmup 스텝 수 50 ~ 500
training.batch_size 배치 크기 [2, 4, 8] GPU 메모리에 따라
training.grad_accum_steps 그래디언트 누적 [1, 2, 4, 8] effective batch = batch × accum
training.max_grad_norm 그래디언트 클리핑 [0.5, 1.0, 2.0]

훈련 타입별 파라미터

파라미터 훈련 타입 추천 탐색 범위 비고
training.orpo_lambda ORPO 0.1 ~ 2.0 SFT vs 선호 loss 비율
training.dpo_beta DPO [0.05, 0.1, 0.2, 0.5] 선호 강도
training.ppo.clip_range PPO [0.1, 0.2, 0.3] PPO 클리핑 ε
training.ppo.kl_coef PPO [0.05, 0.1, 0.2] KL 페널티 계수

LoRA 구조 파라미터 (injection.*)

파라미터 설명 추천 탐색 범위 비고
injection.lora_r LoRA rank 8 ~ 64 (step 8) 클수록 표현력 ↑ / 메모리 ↑
injection.lora_alpha LoRA 스케일링 16 ~ 128 (step 16) 보통 lora_r × 2
injection.lora_dropout LoRA dropout [0.0, 0.05, 0.1]

LoRA 적용 범위 (injection.*)

파라미터 설명 추천 탐색 범위 비고
injection.start_layer 적용 시작 레이어 0 ~ 20 (step 4) 뒤쪽 = task-specific
injection.num_layers 적용 레이어 수 [0, 4, 8, 12, 16] 0 = 전체
injection.target_keywords FFN LoRA 대상 (아래 표 참조) 리스트 값
injection.attn_lora.enabled Attention LoRA 활성화 [true, false]
injection.attn_lora.keywords Attention LoRA 대상 (아래 표 참조) 리스트 값

target_keywords 조합 예시

조합 설명
[gate_proj, up_proj, down_proj] FFN 전체 (기본값)
[gate_proj, down_proj] gate+down만 (up 제외)
[up_proj, down_proj] up+down만

attn_lora.keywords 조합 예시

조합 설명
[q_proj, v_proj] Q+V만 (기본값, 가장 일반적)
[q_proj, k_proj, v_proj, o_proj] 전체 attention (표현력 극대화)
[q_proj] Q만 (최소 구성)

리스트 값 지원: target_keywords, attn_lora.keywords 등 리스트 파라미터도 탐색 가능합니다. categorical 타입으로 여러 리스트 조합을 지정하세요.


탐색 방법 선택

method: "random" — 랜덤 서치

연속 범위와 이산 선택 모두 지원. 빠르게 전체 공간을 탐색할 때 적합.

search:
  method: "random"
  space:
    - name: "training.lr"
      type: "float"
      low: 1e-6
      high: 1e-4
      log: true

method: "grid" — 그리드 서치

주의: choices 또는 categorical 타입만 사용 가능. 연속 범위(low/high)는 오류.

search:
  method: "grid"
  space:
    - name: "injection.lora_r"
      type: "categorical"
      choices: [8, 16, 32]          # ✅ grid 허용
    - name: "training.lr"
      type: "float"
      choices: [1e-5, 5e-5, 1e-4]  # ✅ choices 형식은 허용
    # - name: "training.lr"
    #   type: "float"
    #   low: 1e-6
    #   high: 1e-4                   # ❌ grid에서 불가 — 오류

method: "bayes" — 베이지안 최적화 (TPE)

이전 trial 결과를 학습하여 유망한 공간을 집중 탐색. trial 수가 적을 때 효율적.

search:
  method: "bayes"
  sampler:
    seed: 42
  space:
    - name: "training.lr"
      type: "float"
      low: 1e-6
      high: 1e-4
      log: true
    - name: "training.orpo_lambda"
      type: "float"
      low: 0.1
      high: 2.0

파라미터 타입

타입 설명 필수 필드
float 연속 실수 low + high 또는 choices
int 정수 low + high 또는 choices
categorical 이산 선택 choices

공통 선택 필드: - log: true — 로그 스케일 (float/int) - step: N — 스텝 간격 (int)


실전 탐색 전략

1단계: 핵심 HP 먼저

처음에는 lr + lora_r + lora_dropout 3개만 탐색합니다 (기본 예시와 동일).

2단계: 구조 탐색 추가

1단계 최적값을 고정한 뒤 레이어 범위를 탐색합니다:

space:
  - name: "training.lr"
    type: "float"
    choices: [5e-5]                    # 1단계에서 찾은 최적 lr 고정
  - name: "injection.start_layer"
    type: "categorical"
    choices: [0, 8, 12, 16]
  - name: "injection.num_layers"
    type: "categorical"
    choices: [0, 4, 8, 12]

3단계: 적용 대상 탐색

어떤 모듈에 LoRA를 적용하는 것이 효과적인지 탐색합니다:

space:
  - name: "injection.target_keywords"
    type: "categorical"
    choices:
      - [gate_proj, up_proj, down_proj]   # 전체
      - [gate_proj, down_proj]            # 축소
  - name: "injection.attn_lora.keywords"
    type: "categorical"
    choices:
      - [q_proj, v_proj]                  # Q+V (기본)
      - [q_proj, k_proj, v_proj, o_proj]  # 전체
  - name: "injection.attn_lora.enabled"
    type: "categorical"
    choices: [true, false]                # attn LoRA 유무 비교

: 탐색 차원이 많으면 max_trials을 충분히 늘리세요. random/bayes에서는 차원 수 × 5~10회 이상이 권장됩니다.


Bench 평가 (bench_eval)

각 trial 훈련 후 bench judge로 품질을 평가할 수 있습니다. Loss 최소화와 judge 점수를 동시에 추적하여, 각 기준별 최적 trial을 별도로 보고합니다.

run:
  objective:
    direction: "minimize"
    metric: "train/total_loss"
    step_agg: "last"

  bench_eval:
    enabled: true
    bench_preset: "configs/bench/sft_judge.yml"  # bench YAML 경로
    metric: "avg_score"                          # judge 점수 기준
    checkpoint: "final"                          # 평가할 체크포인트

동작 방식

  1. 각 trial의 훈련이 완료된 후, bench_preset에 지정된 bench config로 bench 평가 실행
  2. Trial의 체크포인트(final/latest/best)가 target 모델로 자동 설정됨
  3. Bench의 judge가 추론 결과를 평가하여 점수를 매김
  4. summary에서 loss 기준 best와 bench 기준 best를 각각 보고

bench_eval 설정

필드 설명 기본값
enabled 활성화 여부 false
bench_preset bench YAML 경로 (judge 포함) (필수)
metric bench summary에서 추출할 점수 키 avg_score
checkpoint 평가할 trial 체크포인트 final

metric 유효값: avg_score, target_avg_score, baseline_avg_score

bench_preset 예시

bench_preset은 기존 bench YAML과 동일합니다. target 섹션은 grid engine이 자동으로 trial 체크포인트로 오버라이드합니다:

# configs/bench/sft_judge.yml (bench_eval용)
bench:
  task: sft
  data_path: data/sft_1k_raw.jsonl
  sample:
    k: 10
    seed: 42
  models:
    target:
      device: "cuda:0"
      dtype: "bfloat16"
    # baseline:                          # 선택: baseline 모델 비교
    #   enabled: true
    #   model_dir: "Qwen/Qwen3.5-0.8B-Base"
    #   device: "cuda:0"
    judge:
      enabled: true
      provider: ollama
      model: "gpt-oss:20b"
      mode: pointwise

출력 구조

outputs/grid/
├── trial_0000/
│   ├── metrics.jsonl          # 스텝별 지표
│   ├── resolved_config.json   # 적용된 설정
│   ├── checkpoint-latest/
│   └── bench_eval/            # bench_eval 결과 (활성화 시)
│       ├── results.jsonl
│       └── summary.json
├── trial_0001/
│   └── ...
├── summary.json               # 전체 결과 요약
└── summary.csv                # CSV 버전

summary.json 예시 (bench_eval 활성화 시):

{
  "best_trial": {
    "number": 3,
    "value": 1.2345,
    "params": {"training.lr": 5e-05, "injection.lora_r": 16}
  },
  "best_by_bench": {
    "number": 1,
    "bench_score": 7.5,
    "value": 1.8901,
    "params": {"training.lr": 1e-04, "injection.lora_r": 32}
  },
  "all_trials": [
    {"number": 0, "value": 2.456, "bench_score": 5.2, "params": {...}, "state": "COMPLETE"},
    {"number": 1, "value": 1.890, "bench_score": 7.5, "params": {...}, "state": "COMPLETE"},
    ...
  ],
  "bench_eval": {
    "metric": "avg_score",
    "checkpoint": "final",
    "bench_preset": "configs/bench/sft_judge.yml"
  }
}

metrics.jsonl

각 trial의 metrics.jsonl은 매 학습 스텝의 지표를 기록합니다:

{"step": 10, "train/total_loss": 2.345, "train/main_loss": 2.301, "train/learning_rate": 1e-05}
{"step": 20, "train/total_loss": 2.201, ...}

objective.metric에 이 키를 지정하면 trial의 목적 함수 값으로 사용됩니다.


제공 예시

파일 방법 학습 타입 기본 space
configs/grid/sft_random_search.yml random SFT lr, lora_r, dropout + 주석 처리된 확장 space
configs/grid/dpo_grid_search.yml grid DPO lora_r, dropout + 주석 처리된 beta, 레이어, 키워드
configs/grid/orpo_bayes_search.yml bayes ORPO lr, orpo_lambda, lora_r + 주석 처리된 확장 space

활용법: 각 예시의 주석 처리된 space 항목을 풀어서 탐색 범위를 확장하세요.


참고