
Quantization concepts
핵심 포인트
- 1Quantization은 float32 대신 int8과 같은 저정밀도 데이터 타입을 사용하여 모델 크기를 줄이고, 추론 속도를 높이며, 에너지 소비를 줄이는 기술이지만, 정확도 손실이 발생할 수 있습니다.
- 2Quantization은 주로 scale(S) 및 zero-point(Z) 파라미터를 사용하는 affine quantization 방식을 통해 float32 값을 int8 범위로 매핑하며, int4 및 FP8과 같은 다양한 데이터 타입으로도 적용됩니다.
- 3Quantization은 모델 훈련 후에 적용하는 PTQ와 훈련 중에 시뮬레이션하는 QAT 기술로 나뉘며, Hugging Face Transformers 라이브러리는 `BitsAndBytesConfig`를 포함한 다양한 백엔드를 통해 이를 통합 지원합니다.
본 문서는 트랜스포머 모델과 같은 대규모 머신러닝 모델의 메모리 사용량과 연산 비용을 줄이기 위한 양자화(Quantization) 개념을 설명합니다. 양자화는 모델의 가중치(weights)와 활성화(activations)를 float32와 같은 표준 부동 소수점(floating-point) 대신 8비트 정수(int8)와 같은 낮은 정밀도의 데이터 타입으로 표현하여 이를 달성합니다.
양자화의 주요 이점은 다음과 같습니다:
- 모델 크기 감소: int8 모델은 float32 모델에 비해 약 4배 작습니다.
- 추론 속도 향상: 낮은 정밀도 데이터 타입, 특히 정수 연산은 호환 가능한 하드웨어(CPU 및 GPU)에서 훨씬 빠르며, 이는 대기 시간(latency)을 줄입니다.
- 에너지 소비 감소: 빠른 연산과 작은 메모리 전송은 전력 소모를 줄입니다.
주요 절충점은 *효율성* 대 *정확도*입니다. 정밀도 감소는 필연적으로 작은 오류(quantization noise)를 도입하므로, 목표는 적절한 스킴(scheme), 세분성(granularity), 및 기법(technique)을 사용하여 오류를 최소화하는 것입니다.
1. 양자화 스킴 (Quantization schemes)
핵심 아이디어는 float32 값의 범위를 int8(일반적으로 )로 매핑하는 것입니다.
- 아핀 양자화 (Affine Quantization):
- 대칭 양자화 (Symmetric Quantization):
scale ()만 필요로 하며, 연산을 단순화할 수 있지만 데이터 분포가 0을 중심으로 하지 않으면 정확도가 떨어질 수 있습니다. 양자화 및 역양자화는 다음과 같습니다:- 비대칭 양자화 (Asymmetric Quantization / Affine Quantization):
scale ()과 zero-point ()가 필요합니다.scale ()은 float32와 int8 범위 간의 비율을 나타내는 양수 float32 값입니다.zero-point ()는 float32 값 에 해당하는 int8 값입니다.float32 값 를 int8 로 양자화하는 공식은 다음과 같습니다:
int8 값 를 근사적인 float32로 역양자화하는 공식은 다음과 같습니다:
추론 중에는 int8 값 를 사용하여 행렬 곱셈과 같은 연산을 수행하며, 결과는 다음 레이어로 전달되기 전에 float32로 역양자화됩니다(종종 int32와 같은 더 높은 정밀도 축적 타입을 내부적으로 사용).
- int4 및 가중치 패킹 (int4 and weight packing):
- FP8 (8-bit floating-point):
- E4M3: 1비트 부호, 4비트 지수, 3비트 가수. 높은 정밀도를 제공하지만 동적 범위가 작습니다.
- E5M2: 1비트 부호, 5비트 지수, 2비트 가수. 더 넓은 동적 범위를 제공하지만 정밀도가 낮습니다.
2. 세분성 (Granularity)
양자화 파라미터( 및 )는 두 가지 방식으로 계산될 수 있습니다:
- 텐서별 (Per-Tensor): 전체 텐서에 대해 하나의 와 세트를 사용합니다. 단순하지만 텐서 내에서 데이터 값이 크게 다를 경우 정확도가 떨어질 수 있습니다.
- 채널별/그룹별 (Per-Channel / Per-Group/Block): 각 채널 또는 그룹에 대해 별도의 와 를 사용합니다. 약간 더 복잡하고 메모리를 더 사용하지만 더 정확하고 성능이 좋습니다.
3. 양자화 기법 (Quantization techniques)
주요 양자화 기법은 두 가지입니다:
- 학습 후 양자화 (Post-Training Quantization, PTQ): 모델이 완전히 학습된 *후*에 양자화를 적용합니다.
- 양자화 인지 학습 (Quantization-Aware Training, QAT): "가짜 양자화(fake quantization)" 연산을 삽입하여 학습 *중에* 양자화의 반올림 오류를 시뮬레이션합니다. 이를 통해 모델이 양자화에 적응할 수 있게 하며, 특히 낮은 비트폭에서 더 나은 정확도를 얻는 경우가 많습니다.
4. Transformers에서의 양자화 (Quantization in Transformers)
Transformers 라이브러리는 bitsandbytes, torchao, compressed-tensors와 같은 여러 양자화 백엔드를 통합합니다. 모든 백엔드는 HfQuantizer API와 관련 QuantizationConfig 클래스 아래에서 통일됩니다. 일반적인 워크플로우는 하드웨어와 사용 사례에 적합한 양자화 방법을 선택한 다음, Hugging Face Hub에서 사전 양자화된 모델을 로드하거나 float32/float16/bfloat16 모델을 로드하고 QuantizationConfig로 특정 양자화 방법을 적용하는 것입니다.
예시 코드는 BitsAndBytesConfig를 사용하여 8B 파라미터 모델을 4비트로 양자화하는 방법을 보여줍니다.
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
model_id = "meta-llama/Llama-3.1-8B-Instruct"
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.bfloat16
)
model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=quantization_config,
dtype=torch.bfloat16,
device_map="auto"
)이 코드는
meta-llama/Llama-3.1-8B-Instruct 모델을 4비트 양자화로 로드하며, 계산 데이터 타입으로는 torch.bfloat16을 사용하도록 설정합니다.