모델을 경량화하여 학습시킬 경우, GPU resource, 메모리 등의 측면에서 이점이 있기 때문에 최근 많이 연구되고 있다.
모델 경량화에는 크게 세가지 방법이 있다.
Pruning(가지치기)
신경망 학습에서 중요도가 떨어지는 node를 제거하고 재학습하는 과정을 반복하여 모델의 크기를 줄여나가는 방식
이 방식을 통해, Deep Compression (2015) 논문에서는 VGG-16 model을 약 49배 경량화 하였으며, Clip-q (2018)에서는 ResNet-50 model을 약 15배 경량화하였다고 한다.
Knowledge Distillation(지식 증류)
학습이 잘된 큰 딥러닝 모델(Teacher model)의 지식을 학습되지 않은 작은 크기의 모델(student model)에게 가르쳐줄 수 있지 않을까? 에서 시작한 방법론
Quantization(양자화)
모델의 해상도를 낮춰 작게 만드는 방법
파라미터의 Precision을 적절히 줄여서 연산 효율성을 높임
Pytorch Pruning 이후 재학습하여 ONNX로 변환하여 양자화
PyTorch에서 Pruning 적용: 모델의 특정 레이어에 pruning을 적용하고, 중요한 가중치만 남겨두는 방식으로 수행
Pruning 후 재학습 (Fine-tuning): Pruning 후 모델의 성능을 회복시키기 위해 재학습을 진행
ONNX로 변환: Pruning이 적용된 모델을 ONNX 형식으로 변환
Quantization(양자화): ONNX 모델을 NPU 제조사 SDK를 이용하여 INT8 양자화 모델로 변환
Pruning 적용 예제 (PyTorch)
import torch
import torch.nn.utils.prune as prune
import torch.nn.functional as F
import torchvision.models as models
# 모델 불러오기
model = models.resnet18(pretrained=True)
# 프루닝 적용 예시 (conv1 레이어에 50% 프루닝 적용)
prune.l1_unstructured(model.conv1, name='weight', amount=0.5)
# 프루닝 적용 후의 모델 가중치
print(list(model.named_parameters()))
# 프루닝 후 fine-tuning을 위해 재학습
# 예제이므로 데이터로더와 학습 루프는 생략
for epoch in range(10): # 예제 학습 루프
for inputs, targets in train_loader:
outputs = model(inputs)
loss = F.cross_entropy(outputs, targets)
loss.backward()
optimizer.step()