Mixed Precision 학습
혼합 정밀도(Mixed Precision) 학습은 FP32와 FP16(또는 BF16)을 혼합 사용하여 학습 속도를 약 2배 가속하고 GPU 메모리를 절약하는 기법입니다.
핵심 아이디어
순전파와 역전파의 대부분의 연산을 FP16으로 수행하되, 가중치 업데이트와 손실 계산은 FP32로 유지합니다. NVIDIA의 Tensor Core를 활용하면 FP16 행렬 연산이 FP32보다 훨씬 빠릅니다.
import torch
import torch.nn as nn
from torch.amp import autocast, GradScaler
device = torch.device('cuda')
model = nn.Sequential(
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 10),
).to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()
scaler = GradScaler('cuda') # 기울기 스케일링 (FP16 언더플로 방지)
for epoch in range(10):
model.train()
for batch_data, batch_labels in train_loader:
batch_data = batch_data.to(device)
batch_labels = batch_labels.to(device)
optimizer.zero_grad()
# autocast: FP16으로 순전파
with autocast('cuda'):
outputs = model(batch_data)
loss = criterion(outputs, batch_labels)
# 스케일된 역전파
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
FP16 vs BF16
| 속성 | FP32 | FP16 | BF16 |
|---|
| 비트 수 | 32 | 16 | 16 |
| 지수 비트 | 8 | 5 | 8 |
| 가수 비트 | 23 | 10 | 7 |
| 범위 | 넓음 | 좁음 | FP32 동일 |
| 정밀도 | 높음 | 높음 | 낮음 |
| GradScaler 필요 | - | 필요 | 불필요 |
| 지원 GPU | 모든 GPU | Volta+ | Ampere+ |
# BF16 사용 (Ampere 이상 GPU, GradScaler 불필요)
with autocast('cuda', dtype=torch.bfloat16):
outputs = model(batch_data)
loss = criterion(outputs, batch_labels)
loss.backward()
optimizer.step()
NVIDIA A100, H100 등 Ampere 이상 GPU에서는 BF16을 사용하세요. GradScaler가 불필요하고 수치적으로 더 안정적입니다.
체크리스트
다음 문서