한 줄짜리 보험
기울기 클리핑은 옵티마이저가 갱신하기 전에 기울기의 전체 노름 또는 개별 값을 제한해. 클리핑 전 노름이 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이 발생하는 비용은 코드 한 줄을 추가하는 비용보다 훨씬 커.