본문 바로가기
C.W.K.
Stream
Lesson 02 of 08 · published

학습 루프 뜯어보기

~18 min · training-loop, scaffold

Level 0호기심
0 XP0/73 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

진지한 학습 루프에 꼭 들어가는 6가지

  1. 설정: 모든 하이퍼파라미터를 담는 dataclass 또는 YAML/TOML. 체크포인트를 저장할 때마다 함께 저장해.
  2. 시드: 코드 맨 위에서 설정하고 모든 곳에 적용해.
  3. 혼합 정밀도: autocast + GradScaler를 사용해. BF16이라면 GradScaler는 필요 없어.
  4. 기울기 클리핑: 역전파가 끝난 뒤, 옵티마이저 단계 전에 적용해.
  5. 학습률 스케줄: Transformer에는 워밍업 + 코사인 감소, 미세 조정에는 OneCycle, 전통적인 CNN에는 단계별 감소를 사용해.
  6. 검증 + 최적 체크포인트 저장: 매 에폭 또는 N 단계마다 별도 검증 세트로 평가하고, 검증 지표가 개선되면 저장해.
팁: 이 6가지가 이미 들어 있는 빈 학습 루프 템플릿으로 모든 프로젝트를 시작하면, 프로젝트마다 같은 문제를 디버깅하느라 보내는 한 주를 아낄 수 있어.

기울기 누적 패턴

원하는 배치 크기를 VRAM에 올릴 수 없을 만큼 모델이 크다면, 여러 번 순전파와 역전파를 수행하는 동안 opt.zero_grad()를 건너뛴 뒤 옵티마이저 단계를 실행하고 기울기를 초기화해. 수학적으로는 더 큰 배치 하나를 사용하는 것과 같아. 손실값의 크기를 일정하게 유지하려면 scaler.scale(loss / accum_steps).backward()처럼 조정해.

프레임워크가 도움이 되는 지점

PyTorch Lightning, Hugging Face Trainer, Accelerate는 혼합 정밀도, 분산 학습, 체크포인트 저장, 로깅 같은 반복 코드를 처리해 줘서 모델과 데이터에 집중할 수 있게 해. 대신 코드는 줄어들지만 내부 동작은 덜 보여. 프레임워크를 도입하기 전에 적어도 한 번은 학습 루프를 직접 작성해 봐.

원칙: 첫 학습 루프는 직접 작성해. 10번째쯤에는 아마 프레임워크를 쓰게 될 거야. 그 사이 과정에서 가장 많이 배워.

Code

운영 환경 수준의 전체 학습 루프·python
import torch, json
from torch import nn, optim
from torch.cuda.amp import autocast, GradScaler
from torch.nn.utils import clip_grad_norm_

def train(model, train_loader, val_loader, cfg, device):
    model = model.to(device)
    opt = optim.AdamW(model.parameters(), lr=cfg.lr, weight_decay=cfg.wd)
    sch = warmup_cosine(opt, cfg.warmup_steps, cfg.total_steps)
    scaler = GradScaler()
    loss_fn = nn.CrossEntropyLoss()

    best_val = 0.0
    step = 0
    for epoch in range(cfg.epochs):
        model.train()
        for xb, yb in train_loader:
            xb, yb = xb.to(device), yb.to(device)
            opt.zero_grad()
            with autocast(dtype=torch.bfloat16):
                logits = model(xb)
                loss = loss_fn(logits, yb)
            scaler.scale(loss).backward()
            scaler.unscale_(opt)
            clip_grad_norm_(model.parameters(), max_norm=cfg.clip)
            scaler.step(opt); scaler.update(); sch.step()
            step += 1

        val_acc = evaluate(model, val_loader, device)
        if val_acc > best_val:
            best_val = val_acc
            torch.save({"model": model.state_dict(), "config": cfg.__dict__,
                        "val_acc": val_acc, "step": step}, "best.pt")
        print(f"epoch={epoch} step={step} val={val_acc:.4f}")
    return best_val

External links

Exercise

설정 dataclass와 단일 함수로 학습 루프를 작성해. 작은 과제에 실행해 본 다음, Hugging Face Accelerate를 사용하도록 리팩터링해. 두 버전의 코드 줄 수와 가독성을 비교해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.