양자화(Quantization)는 딥러닝 모델의 파라미터와 연산을 float32에서 int8 또는 uint8과 같은 저정밀도 정수형으로 바꾸는 기술입니다. 이를 통해 모델의 크기를 줄이고, 연산 속도를 높이며, 특히 모바일·엣지 디바이스에서 효율적인 추론을 가능하게 합니다.
int8
또는 uint8
형식으로 저장scale
, zero_point
정보도 함께 포함torch.quantized.Linear
, torch.nn.intrinsic.quantized.ConvReLU2d
등 quantized operator 사용torch._C.ScriptObject
형태로 저장되며, .state_dict()
로 확인 시 가중치가 uint8
/int8
로 표시됨예시 코드:
print(model.features[0].weight().dtype) # torch.qint8 또는 torch.uint8
int8
로 양자화, 활성값은 float32 유지예시 코드:
model = torch.quantization.quantize_dynamic(model, {torch.nn.Linear}, dtype=torch.qint8)
state_dict = model.state_dict()
for k, v in state_dict.items():
print(k, v.dtype) # 예: fc1._packed_params._packed_params torch.qint8
int8
연산 사용양자화 방식 | 가중치 저장 형식 | 활성값 처리 방식 |
---|---|---|
Static Quantization | int8 , uint8 | int8 또는 uint8 로 변환 |
Dynamic Quantization | int8 | float32 유지, 실행 시 양자화 |
QAT | int8 , uint8 | 훈련 시 float, 추론 시 int8 |
PyTorch에서 양자화된 모델은 float32로 복원하지 않고 그대로 int 연산을 수행합니다. 이는 연산 속도와 메모리 측면에서 큰 장점을 제공합니다.
양자화 종류 | 추론 시 가중치 | 연산 형식 | 비고 |
---|---|---|---|
Static Quantization | int8 /uint8 | 대부분 연산이 int8 또는 int32 (accumulate) | 출력만 float 변환 |
Dynamic Quantization | int8 | 실행 중 float 변환 후 연산 | 일부만 정수 연산 |
QAT | int8 | int8 연산 | 정밀도 손실 최소화 |
import torch
from torch.ao.quantization import quantize_static
model = torch.nn.Sequential(torch.nn.Linear(10, 5))
model.eval()
model.qconfig = torch.ao.quantization.get_default_qconfig("fbgemm")
torch.ao.quantization.prepare(model, inplace=True)
torch.ao.quantization.convert(model, inplace=True)
with torch.no_grad():
x = torch.randint(0, 255, (1, 10), dtype=torch.uint8)
output = model(x) # 대부분 int8 기반 연산
맞습니다! PyTorch에서는 모든 연산자(operator)가 양자화 가능한 것은 아니기 때문에, 일부 레이어는 float32
연산을 그대로 수행합니다.
연산자 유형 | 연산 방식 |
---|---|
nn.quantized.Linear , Conv2d | int8 기반 연산 |
일반 nn.ReLU , LayerNorm 등 | float32 연산 유지 |
for name, module in model.named_modules():
print(name, type(module))
출력 예시:
features.0 <class 'torch.nn.quantized.modules.conv.Conv2d'>
features.1 <class 'torch.nn.ReLU'> # float 연산
[int8 input]
↓
[Quantized Conv2d]
↓
[float32 LayerNorm] ← 여기서 float 변환
↓
[Quantized Linear]
↓
[float32 output]
양자화 효과를 극대화하려면 다음을 고려하세요:
torch.quantization.fuse_modules(model, [["conv", "relu"]], inplace=True)
Conv + ReLU
, Linear + ReLU
등의 연산을 fuse하여 양자화 가능한 연산자로 전환LayerNorm
, Softmax
는 아직 양자화 버전 없음fuse_modules()
를 적극 활용하세요.