Stage 4 · Ray Tune 튜닝 — 하이퍼파라미터 자동화

Ray Tune — 탐색 공간에서 트라이얼을 병렬 생성하고 ASHA로 조기 종료(가지치기) 탐색 공간 lr: loguniform depth: choice batch: grid_search Tuner 트라이얼 생성 Trial A · 코어 1 Trial B · 코어 2 Trial C · 코어 3 Trial D · 코어 ⅓ ASHA 조기 종료 성능 낮은 트라이얼 가지치기 → 최고 1개만 Best Trial get_best_result
Ray Tune — 탐색 공간에서 **Tuner**가 여러 **트라이얼**을 생성해 노트북 코어에 병렬로 배분하고, `with_resources`로 한 코어에 여러 트라이얼(오버서브스크라이브)을 얹을 수도 있습니다. **ASHA 조기 종료**가 성능 낮은 트라이얼을 일찍 가지치기해, 마지막에 최고 트라이얼 1개가 남습니다.

한눈에 보기

머신러닝을 하다 보면 “learning_rate를 몇으로, 깊이는 얼마로” 하는 하이퍼파라미터를 만지게 됩니다. 이걸 하나하나 손으로 돌리면 시간 낭비가 큽니다. Ray Tune은 이 탐색을 코어 수만큼 병렬로 자동화하고, 좋은 조합을 일찍 남기고 나쁜 조합은 일찍 끊는 도구입니다. 단독 함수도, Stage 5Trainer도 모두 Objective로 감쌀 수 있습니다.

이번 포스트에서 다루는 핵심 질문은 세 가지입니다.

  1. Tuner로 탐색 공간을 정의하고 학습 함수를 최적화하는 기본 흐름은?
  2. ASHA/HyperBand 같은 조기 종료와 탐색 알고리즘은 어떻게 쓰나?
  3. 한 대의 노트북에서 코어를 오버서브스크라이브해 트라이얼을 병렬화하는 전략은?

Tuner 기본

목표는 단순한 함수(Objective) 입니다. config(딕셔너리)를 받아 메트릭을 tune.report로 보고합니다.

import ray
from ray import tune
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score

ray.init(num_cpus=4)

def train_rf(config):
    X, y = load_iris(return_X_y=True)
    model = RandomForestClassifier(
        n_estimators=config["n_estimators"],
        max_depth=config["max_depth"],
    )
    score = cross_val_score(model, X, y, cv=3).mean()
    tune.report({"mean_accuracy": score})   # 메트릭 보고

search_space = {
    "n_estimators": tune.grid_search([50, 100, 200]),
    "max_depth": tune.choice([2, 4, 8]),
}

tuner = tune.Tuner(
    train_rf,
    param_space=search_space,
    tune_config=tune.TuneConfig(metric="mean_accuracy", mode="max"),
)
results = tuner.fit()

best = results.get_best_result(metric="mean_accuracy", mode="max")
print("최고 점수:", best.metrics["mean_accuracy"])
print("최고 config:", best.config)
  • param_space: 탐색 공간. tune.grid_search([...])(모두 시도), tune.choice/uniform/loguniform 등.
  • tune.report: 각 트라이얼이 학습 중 메트릭을 보고.
  • TuneConfig(metric, mode): 최적화 대상과 방향(max/min).
  • get_best_result: 최고 트라이얼.

탐색 공간은 loguniform처럼 로그 스케일도 지정할 수 있습니다 — 넓은 값 범위를 효율적으로 탐색합니다.

search_space = {
    "lr": tune.loguniform(1e-4, 1e-2),   # 로그 스케일
    "dropout": tune.uniform(0.0, 0.5),
}

조기 종료와 탐색 알고리즘

조기 종료 — ASHA / HyperBand

성능이 나쁜 트라이얼을 일찍 멈추면, 자원을 유망한 트라이얼에 집중할 수 있습니다. ASHA(Async Successive Halving)와 HyperBand가 대표적입니다.

from ray.tune.schedulers import ASHAScheduler, HyperBandScheduler

tuner = tune.Tuner(
    train_rf,
    param_space=search_space,
    tune_config=tune.TuneConfig(
        metric="mean_accuracy",
        mode="max",
        scheduler=ASHAScheduler(time_attr="training_iteration", max_t=100),
    ),
)
results = tuner.fit()

탐색 알고리즘 — Optuna 등

무작위·그리드 대신 지능형 탐색을 쓰려면 ray.tune.search의 알고리즘을 연결합니다.

from ray.tune.search.optuna import OptunaSearch

tuner = tune.Tuner(
    train_rf,
    param_space=search_space,
    tune_config=tune.TuneConfig(
        metric="mean_accuracy",
        mode="max",
        search_alg=OptunaSearch(),
    ),
)

지원 목록: Optuna, Hyperopt, BayesOpt, BOHB, Nevergrad, Ax 등.

로컬 리소스 제어 — 코어 오버서브스크라이빙

한 대 노트북의 코어 수는 한정적입니다. 트라이얼당 1 CPU가 기본이므로 4코어면 4개만 동시에 돕니다. 더 빨리 많이 돌리고 싶다면:

  • max_concurrent_trials: 동시 트라이얼 수 상한을 정합니다.
  • tune.with_resources(trainable, {"cpu": 0.5}): 트라이얼당 소수 CPU를 줘서 한 코어에 여러 트라이얼을 올립니다(오버서브스크라이빙).
from ray import tune

# 각 트라이얼이 0.5 CPU → 4코어에 최대 8개 트라이얼을 병렬
tuner = tune.Tuner(
    tune.with_resources(train_rf, {"cpu": 0.5}),
    param_space=search_space,
    tune_config=tune.TuneConfig(
        metric="mean_accuracy",
        mode="max",
        max_concurrent_trials=8,
    ),
)
results = tuner.fit()

실무 요령: 각 트라이얼이 순수 Python/사이킷런이라면 GIL 때문에 소수 CPU 오버서브스크라이빙이 이득입니다. 반면 NumPy/Torch처럼 GIL을 풀어 코어를 다 쓰는 트라이얼이라면 1 CPU당 1 트라이얼이 맞습니다. 트라이얼의 성격에 따라 with_resources를 조절하세요.

GPU 참고: gpu 자원을 지정하면 트라이얼에 CUDA_VISIBLE_DEVICES가 설정됩니다. 지정하지 않으면 CUDA가 비활성화됩니다.

로컬 활용 전략 — 실전 요약

  1. 코어 수만큼 병렬 탐색: 기본값만으로도 코어 수 트라이얼이 동시에 돕니다.
  2. 조기 종료로 낭비 줄이기: ASHA를 붙이면 나쁜 하이퍼파라미터 조합을 일찍 끊습니다.
  3. 소수 CPU 오버서브스크라이빙: GIL-bound(사이킷런 등) 트라이얼이면 {"cpu": 0.5}로 8개까지 병렬.
  4. Train과 연결: Stage 5Trainer를 Objective로 감싸 하이퍼파라미터 탐색 + 분산 학습을 동시에.

Summary

  • Ray Tune은 탐색 공간(param_space)에서 여러 트라이얼을 병렬 생성해 Objective 함수를 최적화합니다.
  • grid_search/loguniform/choice 등으로 공간을 정의하고, tune.report로 메트릭을 보고합니다.
  • ASHA/HyperBand 조기 종료와 Optuna 등 탐색 알고리즘으로 효율을 올립니다.
  • 로컬에선 with_resources(소수 CPU) + max_concurrent_trials로 한 코어에 여러 트라이얼을 얹는 오버서브스크라이빙이 핵심 전략입니다.

다음 학습 (Next Learning)