기본 구조
모든 PyTorch 학습 루프는 기본 구조가 같아. 에폭마다 학습 데이터 로더를 순회하면서 손실을 계산하고, 역전파를 수행한 뒤 옵티마이저를 업데이트해. 일정한 주기마다, 보통 에폭마다 또는 N단계마다 model.eval()로 전환해 검증 세트에서 평가하고 가장 좋은 체크포인트를 저장해. 검증 지표가 더 이상 좋아지지 않을 때까지 이 과정을 반복하면 돼.
이 구조는 어디서나 통하므로 한 번 직접 작성한 뒤 재사용할 수 있어. PyTorch Lightning, Hugging Face Trainer, Accelerate 같은 상위 수준 프레임워크에 맡기는 방법도 있고. 둘 다 합리적인 선택이야. 직접 작성하는 편이 학습에는 더 좋고, 프레임워크를 사용하는 편이 운영에는 더 좋아.
팁: 프레임워크를 도입하기 전에 적어도 한 번은 학습 루프를 직접 작성해 봐. 프레임워크는 타이핑을 줄여 주지만, 문제가 생겼을 때 디버깅에 필요한 단계까지 숨기거든.
초보자의 학습 루프에서 자주 생기는 문제
opt.zero_grad()를 잊음 — 이전 단계의 기울기가 계속 누적돼.- 검증할 때
model.eval()을 잊음 — 드롭아웃과 배치 정규화가 잘못 동작해 지표가 불안정해져. - GPU에서 손실을 계산한 뒤
.item()없이 CPU에서 출력하거나 기록함 — 눈에 보이지 않는 CUDA 동기화가 곳곳에서 발생해. - 확률의
argmax와 로짓의argmax를 일관성 없이 사용해 정확도를 계산함 — 우연히 같은 결과가 나오지만 소프트맥스가 달라지면 깨져. - 검증 성능이 가장 좋았던 단계가 아니라 학습이 끝난 시점의 모델 상태 사전을 저장함 — 잘못된 모델을 배포하게 돼.
반드시 추가할 요소
제대로 쓰는 학습 루프에는 기울기 클리핑과 학습률 스케줄링, GPU 혼합 정밀도 학습(autocast + GradScaler)이 더 필요해. 주기적인 체크포인트 저장과 별도 세트를 이용한 검증, 모니터링 도구에서 읽을 수 있는 기록도 갖춰야 해. 이어지는 트랙에서는 이 요소들을 하나씩 기계적으로 적용할 수 있게 만들어 줄 거야.
원칙: 진행 상황을 잃지 않고 학습을 중단했다가 다시 시작할 수 있기 전까지 학습 루프는 완성된 게 아니야. 저장하는 모든 체크포인트에는 모델, 옵티마이저, 스케줄러, 스케일러, 단계 번호가 들어 있어야 해.