
딥러닝 모델의 크기가 수십억 개의 파라미터를 넘어서는 거대 모델(Large Models) 시대에, 단순한 고정 학습률(Learning Rate)은 더 이상 유효하지 않습니다. 모델이 복잡한 Loss Landscape에서 Local Minima나 Saddle Point에 갇히지 않고 전역 최적점(Global Minimum)을 향해 나아가기 위해서는 정교한 스케줄링 전략이 필수적입니다. 본 포스팅에서는 가장 대중적인 Cosine Annealing과 최신 트렌드인 OneCycleLR의 구조적 차이를 분석하고, 거대 모델 학습 시 Local Minima 탈출에 미치는 영향을 7가지 실전 코드를 통해 상세히 살펴봅니다.
1. Cosine vs OneCycle: 메커니즘의 근본적 차이점
두 스케줄러 모두 학습률을 동적으로 변화시키지만, 변화의 '궤적'과 '목적'에서 뚜렷한 차이를 보입니다. Cosine Annealing은 부드러운 하강을 통한 미세 조정을 목표로 하며, OneCycle은 급격한 상승과 하강을 통해 최적화 경로를 탐색(Exploration)하는 데 집중합니다.
스케줄러별 핵심 특성 비교
| 항목 | Cosine Annealing Scheduler | OneCycle Learning Rate Policy |
|---|---|---|
| 핵심 아이디어 | 코사인 함수를 따른 점진적 감쇄 | Warmup - Peak - Cool down 3단계 |
| Local Minima 탈출 | 후반부 정밀 탐색에 유리 | 초중반 높은 LR로 불안정 지점 통과 |
| 하이퍼파라미터 의존도 | 상대적으로 낮음 (T_max 설정 위주) | 매우 높음 (max_lr 설정이 핵심) |
| 학습 속도(Convergence) | 안정적이나 다소 느림 | 매우 빠름 (Super-Convergence) |
| 거대 모델 적용성 | Fine-tuning 단계에서 선호 | Pre-training 및 대규모 배치 학습 |
특히 거대 모델에서 Local Minima 해결 방법으로 OneCycle이 주목받는 이유는 'Super-Convergence' 이론에 기반합니다. 학습 초기에 학습률을 비약적으로 높였다가 다시 낮춤으로써, 좁고 깊은 골짜기(Local Minima)에 빠지지 않고 넓고 평탄한(Flat) 영역으로 모델을 안내하는 역할을 합니다.
2. 실무 개발자를 위한 7가지 실전 Scheduler 구현 Example
PyTorch 프레임워크를 기반으로 거대 모델 학습 시 즉시 적용 가능한 7가지 스케줄링 사례를 소개합니다. 모든 코드는 복사하여 실무에 바로 활용할 수 있습니다.
Example 1: CosineAnnealingLR의 기본적인 적용
가장 표준적인 코사인 감쇄 방식입니다. 주기가 끝날 때 학습률이 최소치에 도달하도록 설계합니다.
import torch.optim as optim
from torch.optim.lr_scheduler import CosineAnnealingLR
optimizer = optim.AdamW(model.parameters(), lr=1e-3)
# T_max는 전체 에포크 수 또는 총 스텝 수로 설정
scheduler = CosineAnnealingLR(optimizer, T_max=100, eta_min=1e-6)
for epoch in range(100):
train(model, optimizer)
scheduler.step()
Example 2: OneCycleLR을 활용한 초고속 수렴(Super-Convergence)
학습 초기에 LR을 max_lr까지 끌어올려 Local Minima를 강제로 돌파합니다.
from torch.optim.lr_scheduler import OneCycleLR
optimizer = optim.AdamW(model.parameters(), lr=1e-4)
scheduler = OneCycleLR(optimizer, max_lr=1e-2,
steps_per_epoch=len(train_loader),
epochs=50,
pct_start=0.3) # 30% 구간까지 LR 상승
for epoch in range(50):
for batch in train_loader:
train_batch(model, optimizer, batch)
scheduler.step()
Example 3: CosineAnnealingWarmRestarts (WR) 해결 방법
학습 중간에 학습률을 다시 높여(Restart) 다른 Local Minima로 이동하며 앙상블 효과를 노립니다.
from torch.optim.lr_scheduler import CosineAnnealingWarmRestarts
# T_0: 첫 주기 길이, T_mult: 주기 배수
scheduler = CosineAnnealingWarmRestarts(optimizer, T_0=10, T_mult=2)
# 주기적으로 학습률이 튀면서 새로운 경로를 탐색함
Example 4: Warmup을 포함한 Cosine Schedule (Transformers 필수)
거대 모델(LLM 등) 학습 시 초반 불안정성을 잡기 위해 Linear Warmup과 Cosine을 결합합니다.
from transformers import get_cosine_schedule_with_warmup
scheduler = get_cosine_schedule_with_warmup(
optimizer,
num_warmup_steps=500,
num_training_steps=10000
)
Example 5: 특정 조건 시 스케줄러 수동 조정(Manual Override)
Loss가 특정 임계값 이하로 떨어지지 않을 때 OneCycle의 파라미터를 동적으로 변경합니다.
if current_loss > threshold:
for param_group in optimizer.param_groups:
param_group['lr'] *= 1.2 # 일시적으로 LR을 높여 정체 구간 탈출
Example 6: 대규모 배치 학습을 위한 LR Scaling 공식 적용
배치 크기가 커질 때 OneCycle의 max_lr을 선형적으로 조정하여 안정성을 확보합니다.
base_lr = 1e-3
batch_size = 1024
scaled_max_lr = base_lr * (batch_size / 256) # Linear Scaling Rule
scheduler = OneCycleLR(optimizer, max_lr=scaled_max_lr, ...)
Example 7: Custom Lambda를 활용한 하이브리드 스케줄링
Cosine과 OneCycle의 장점을 결합한 독자적인 감쇄 로직을 구현합니다.
import math
lambda_func = lambda epoch: 0.5 * (1 + math.cos(math.pi * epoch / 100)) if epoch > 10 else epoch / 10
scheduler = optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda_func)
3. Local Minima 탈출과 'Flat Minima'의 중요성
거대 모델의 손실 함수 지형(Loss Landscape)은 매우 복잡합니다. Cosine Annealing은 이미 좋은 영역에 들어왔을 때 정밀하게 바닥을 찾는 데 유리하지만, 초기에 나쁜 Local Minima에 갇히면 빠져나오기 어렵습니다.
반면 OneCycleLR은 높은 학습률 구간에서 가중치에 큰 변화를 주어 '뾰족한(Sharp) Minima'를 무시하고 지나갑니다. Sharp Minima는 훈련 데이터에만 과적합된 경우가 많으며, OneCycle이 지향하는 'Flat Minima'는 데이터의 미세한 변화에도 성능 변동이 적어 훨씬 우수한 일반화 성능을 보여줍니다.
4. 결론: 어떤 상황에 어떤 스케줄러를 써야 하는가?
최종적인 선택은 모델의 목적과 자원에 달려 있습니다.
- 사전 학습(Pre-training): 데이터가 방대하고 모델이 클수록 OneCycleLR이 안정적인 탈출과 빠른 학습을 보장합니다.
- 미세 조정(Fine-tuning): 이미 검증된 가중치에서 시작하므로 Cosine Annealing으로 점진적으로 접근하는 것이 안전합니다.
- 실험적 연구: WarmRestarts를 통해 여러 지역 최적점을 탐색해 보는 것을 권장합니다.