GPTQ

GPTQ (포스트 트레이닝 양자화)

GPTQ는 포스트 트레이닝 양자화(post-training quantization) 기법이에요. 즉 학습이 끝난 모델을 대상으로, 가중치 행렬의 각 행을 독립적으로 양자화해 오차를 최소화하는 버전을 찾는 방식이죠. 가중치는 int4로 양자화되지만 추론 중에는 fp16으로 복원됩니다. 이 가이드에서는 Transformers에서 GPT-QModel로 GPTQ 양자화를 적용하고 쓰는 법을 정리해요.

출처: GPTQ - Hugging Face Transformers 공식문서

개요

GPT-QModel 프로젝트(Python 패키지 gptqmodel)는 GPTQ 알고리즘을 구현합니다. 가중치 행렬의 각 행을 독립적으로 양자화해 오차를 최소화하는 가중치 버전을 찾는 기법이에요. 가중치는 int4로 양자화되지만 추론 중에 fp16으로 온더플라이 복원됩니다. int4 가중치가 GPU의 전역 메모리가 아니라 융합 커널(fused kernel)에서 디양자화되므로 메모리 사용을 4배 아낄 수 있어요. 또한 더 낮은 비트 폭은 통신 시간이 짧아져 추론도 더 빨라집니다.

AutoGPTQ는 Transformers에서 더 이상 지원되지 않아요. 대신 GPT-QModel을 설치하세요.

먼저 Accelerate, Transformers, Optimum을 설치합니다.

pip install --upgrade accelerate optimum transformers

그다음 아래 명령으로 GPT-QModel을 설치합니다.

pip install gptqmodel --no-build-isolation

GPTQConfig 클래스를 만들고 양자화할 비트 수, 양자화를 위한 가중치 캘리브레이션 데이터셋, 데이터셋 준비용 토크나이저를 설정합니다.

from transformers import AutoModelForCausalLM, AutoTokenizer, GPTQConfig

tokenizer = AutoTokenizer.from_pretrained("facebook/opt-125m")
gptq_config = GPTQConfig(bits=4, dataset="c4", tokenizer=tokenizer)

문자열 리스트로 자신만의 데이터셋을 넘길 수도 있지만, GPTQ 논문과 같은 데이터셋을 쓰는 걸 강력히 권장합니다.

dataset = ["gptqmodel is an easy-to-use model quantization library with user-friendly apis, based on the GPTQ algorithm."]
gptq_config = GPTQConfig(bits=4, dataset=dataset, tokenizer=tokenizer)

양자화할 모델을 로딩하고 GPTQConfigfrom_pretrained()에 넘깁니다. device_map="auto"로 설정하면 모델을 CPU로 자동 오프로드해 메모리에 맞추고, 양자화 중 CPU-GPU 간 모듈 이동을 허용합니다.

quantized_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m", device_map="auto", quantization_config=gptq_config)

데이터셋이 너무 커 메모리가 부족하다면(디스크 오프로딩은 미지원), max_memory 파라미터로 장치(GPU·CPU)에 사용할 메모리량을 할당해 보세요.

quantized_model = AutoModelForCausalLM.from_pretrained(
    "facebook/opt-125m",
    device_map="auto",
    max_memory={0: "30GiB", 1: "46GiB", "cpu": "30GiB"},
    quantization_config=gptq_config
)

[!WARNING] 하드웨어에 따라 모델을 처음부터 양자화하는 데 시간이 걸릴 수 있어요. facebook/opt-350m 모델은 무료 티어 Google Colab GPU에서 약 5분, 175B 파라미터 모델은 NVIDIA A100에서 약 4시간이 걸립니다. 양자화 전에 Hub에 해당 모델의 GPTQ 양자화 버전이 이미 있는지 확인하는 게 좋아요.

양자화가 끝나면 push_to_hub()로 모델과 토크나이저를 Hub에 올려 쉽게 공유·접근할 수 있습니다. 이때 GPTQConfig도 저장돼요.

quantized_model.push_to_hub("opt-125m-gptq")
tokenizer.push_to_hub("opt-125m-gptq")

save_pretrained()는 양자화된 모델을 로컬에 저장합니다. device_map 파라미터로 양자화했다면 저장 전에 전체 모델을 GPU 또는 CPU로 옮겨야 해요. 아래 예시는 CPU에 저장합니다.

quantized_model.save_pretrained("opt-125m-gptq")
tokenizer.save_pretrained("opt-125m-gptq")

# if quantized with device_map set
quantized_model.to("cpu")
quantized_model.save_pretrained("opt-125m-gptq")

양자화된 모델은 from_pretrained()로 다시 로딩하고, device_map="auto"를 설정하면 필요한 메모리 이상을 쓰지 않으면서 모든 GPU에 자동 분산되어 더 빨리 로딩됩니다.

from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("{your_username}/opt-125m-gptq", device_map="auto")

Marlin

Marlin은 NVIDIA A100 GPU(Ampere) 아키텍처에 최적화된 4-bit 전용 CUDA GPTQ 커널이에요. 로딩, 디양자화, 디양자화 이후 가중치 실행이 고도로 병렬화되어 원래 CUDA GPTQ 커널보다 추론이 크게 개선됩니다. Marlin은 양자화된 추론에서만 사용 가능하며 모델 양자화는 지원하지 않아요.

Marlin 추론은 GPTQConfigbackend 파라미터로 켤 수 있습니다.


from transformers import AutoModelForCausalLM, GPTQConfig

model = AutoModelForCausalLM.from_pretrained("{your_username}/opt-125m-gptq", device_map="auto", quantization_config=GPTQConfig(bits=4, backend="marlin"))

GPT-QModel

GPT-QModel은 Transformers에서 GPTQ의 활발히 유지되는 백엔드예요. 원래 AutoGPTQ에서 포크됐지만, 이후 더 빠른 양자화, 더 낮은 메모리 사용, 더 정확한 기본값 같은 상당한 개선으로 분기했습니다.

GPT-QModel은 비대칭 양자화(asymmetric quantization)를 제공해서 대칭 양자화에 비해 양자화 오차를 낮출 수 있어요. 레거시 AutoGPTQ 체크포인트와는 하위 호환되지 않으며, 모든 커널(Marlin)이 비대칭 양자화를 지원하는 건 아닙니다.

GPT-QModel은 또한 최신 LLM 모델, 멀티모달 모델(Qwen2-VL, Ovis1.6-VL), 플랫폼(Linux, macOS, Windows 11), 하드웨어(AMD ROCm, Apple Silicon, Intel/AMD CPU, Intel Datacenter Max/Arc GPU 등)를 더 폭넓게 지원해요.

Marlin 커널은 A100 GPU용으로 업데이트됐고, 다른 커널들은 레거시 모델과 비균일 in/out-feature를 가진 모델을 위한 자동 패딩을 포함하도록 업데이트됐습니다.

리소스

PEFT와 함께 GPTQ 양자화를 실행하는 노트북으로 실습해 보세요.

더 알아보기 (Learn more)