왜 온디바이스에서 양자화가 필요한가
7B 모델을 FP16으로 올리면 가중치만 약 14GB다. 모바일 NPU나 엣지 보드의 메모리·대역폭으로는 감당하기 어렵고, 메모리 대역폭이 병목이 되어 토큰 생성 지연이 커진다. 양자화는 가중치를 INT8/INT4로 줄여 메모리 사용량과 대역폭 요구를 낮추고, 정수 연산 유닛을 활용해 지연을 개선한다. 핵심은 "얼마나 줄이면서 정확도를 얼마나 지킬 수 있는가"의 균형이다.
INT8과 INT4는 무엇이 다른가
INT8은 대체로 정확도 손실이 작아 안전한 기본값이다. 반면 INT4는 메모리를 절반 더 줄이지만, 표현 범위가 좁아 이상치(outlier)에 취약하다. 그래서 INT4는 보통 그룹 단위 스케일(group-wise scale, group_size 32~128)과 GPTQ/AWQ 같은 보정(calibration) 기법을 함께 쓴다. 활성값(activation)은 이상치가 많아 4비트로 내리기 어렵고, 대개 가중치만 INT4로 두고 활성은 FP16/INT8로 유지하는 W4A16 구성이 실전에서 안정적이다.
| 항목 | FP16 | INT8 (W8A8) | INT4 (W4A16) |
|---|---|---|---|
| 7B 가중치 크기 | ~14GB | ~7GB | ~3.5GB |
| 정확도 손실 | 기준 | 매우 작음 | 작음~중간 |
| 보정 필요성 | 없음 | PTQ면 권장 | 거의 필수 |
| 이상치 민감도 | 낮음 | 중간 | 높음 |
PTQ vs QAT: 언제 무엇을
PTQ(학습 후 양자화)는 소량의 보정 데이터만으로 빠르게 적용되어 대부분의 배포 상황에 적합하다. INT8은 PTQ만으로 충분한 경우가 많다. INT4에서 정확도가 무너지거나 특정 도메인 성능이 중요하면 QAT(양자화 인식 학습)로 회복을 노린다. QAT는 학습 비용이 크므로, 먼저 PTQ로 손실 폭을 측정한 뒤 필요할 때만 도입한다.
실전 예시: INT4 가중치 양자화
bitsandbytes로 4비트(NF4) 로딩을 구성하는 최소 예시다. 이중 양자화와 그룹 스케일이 정확도 유지에 기여한다.
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
import torch
cfg = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4", # 정규분포 가중치에 유리
bnb_4bit_use_double_quant=True, # 스케일도 양자화해 추가 절감
bnb_4bit_compute_dtype=torch.float16,
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B",
quantization_config=cfg,
device_map="auto",
)
print(model.get_memory_footprint() / 1e9, "GB")
보정 데이터로 정확도 지키기
INT4 PTQ에서는 보정 데이터셋이 결과를 좌우한다. 실제 서비스 트래픽과 분포가 비슷한 128~512개 샘플을 쓰는 것이 무작정 개수를 늘리는 것보다 효과적이다. AWQ 계열은 중요 채널을 보호하는 스케일링을 적용한다.
# AutoAWQ 예시 (W4A16)
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer
model = AutoAWQForCausalLM.from_pretrained("meta-llama/Llama-3.1-8B")
tok = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B")
quant_config = {"w_bit": 4, "q_group_size": 128, "zero_point": True}
model.quantize(tok, quant_config=quant_config,
calib_data="mit-han-lab/pile-val-backup") # 도메인 유사 데이터 권장
model.save_quantized("./llama3-awq-int4")
측정: 무엇을 봐야 하는가
양자화 효과는 반드시 정량 지표로 확인한다. 정확도는 perplexity와 함께 실제 태스크 정확도(분류·추출 정답률)를 본다. perplexity만 좋고 태스크가 무너지는 경우가 있어서다. 성능은 첫 토큰 지연(TTFT), 초당 토큰 수, 그리고 최대 메모리 점유를 함께 기록한다. FP16 기준선과 항상 나란히 비교해야 판단이 선다.
주의점과 실전 권장
- 하드웨어 커널 지원을 먼저 확인한다. INT4 커널이 없으면 디양자화 오버헤드로 오히려 느려진다.
- 임베딩·정규화 레이어와 마지막 출력 레이어는 양자화에서 제외하거나 높은 비트를 유지하는 편이 안전하다.
- KV 캐시도 메모리를 크게 차지한다. 긴 컨텍스트에서는 KV 캐시 양자화(INT8)를 별도로 검토한다.
- 기본 전략은 INT8부터 적용해 안전 마진을 확인하고, 메모리가 더 필요할 때 INT4(W4A16, group_size 128)로 내려가며 태스크 정확도를 게이트로 삼는 것이다.