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

기울기 클리핑

~14 min · clipping, stability

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

한 줄짜리 보험

기울기 클리핑은 옵티마이저가 갱신하기 전에 기울기의 전체 노름 또는 개별 값을 제한해. 클리핑 전 노름이 max_norm을 넘으면, 노름이 max_norm과 같아지도록 기울기 크기를 줄여. 덕분에 옵티마이저는 일정한 범위 안의 갱신값만 받아 갑작스럽게 크게 움직이지 않아.

표준 기본값은 Transformer와 RNN에서 max_norm=1.0, 학습이 매우 불안정할 때 max_norm=0.5다. 안정적인 CNN 학습에는 클리핑을 쓰지 않아. 단계마다 작은 연산만 추가되므로 비용은 거의 들지 않아.

팁: 별다른 경고 없이 손실이 NaN으로 바뀐다면, 가장 먼저 기울기 클리핑을 추가해 봐. 그다음에는 클리핑 전 기울기 노름을 기록해서 클리핑이 얼마나 자주 학습을 살리는지 확인해.

노름 클리핑과 값 클리핑

노름 클리핑 (clip_grad_norm_) — 기울기 방향은 보존하고 크기만 조절해. 거의 언제나 필요한 방식이야.

값 클리핑 (clip_grad_value_) — 각 좌표의 값을 따로 제한해. 기울기 방향을 왜곡하므로, 강화학습의 PPO처럼 특별한 목적이 있는 경우가 아니라면 거의 쓸 일이 없어.

어디에서 호출할까

loss.backward()opt.step() 사이에서 호출해. 혼합 정밀도를 사용할 때는 scaler.unscale_(opt)scaler.step(opt) 사이에 둬. 클리핑은 실제 기울기 값에 적용되므로 호출 순서가 중요해.

원칙: 기울기 클리핑은 값싼 보험이야. 모든 학습 루프에서 기본으로 사용하고, 뚜렷한 이유가 있을 때만 제거해. 단계 50,000에서 NaN이 발생하는 비용은 코드 한 줄을 추가하는 비용보다 훨씬 커.

Code

혼합 정밀도 학습의 기울기 클리핑·python
import torch
from torch.cuda.amp import autocast, GradScaler
from torch.nn.utils import clip_grad_norm_

scaler = GradScaler()

opt.zero_grad()
with autocast():
    loss = loss_fn(model(xb), yb)

scaler.scale(loss).backward()
scaler.unscale_(opt)                # bring grads back to FP32 scale
clip_grad_norm_(model.parameters(), max_norm=1.0)
scaler.step(opt)
scaler.update()

External links

Exercise

합성 긴 시퀀스 과제에서 LSTM을 기울기 클리핑을 적용한 경우와 적용하지 않은 경우로 나눠 학습해. 단계마다 클리핑 전 기울기 노름을 기록해. 클리핑하지 않은 실행이 언제 발산하고, 클리핑한 실행은 언제 살아남는지 확인해.

Progress

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

댓글 0

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

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