llama.cpp 양자화
llama.cpp 양자화
양자화는 LLM 로컬 추론의 주요 주제예요. 메모리 사용량을 줄여주기 때문이죠. 소문자 그대로 llama.cpp는 LLM 양자화를 네이티브로 지원하며, 언제나처럼 유연함을 갖추고 있어요.
출처: 문서
본문
높은 수준에서 보면 llama.cpp가 지원하는 모든 양자화는 가중치 양자화예요. 모델 파라미터를 더 낮은 비트로 양자화하고, 추론 시에는 이를 역양자화(dequantize)해서 계산에 사용해요.
또한 단일 양자화 모델 안에서 서로 다른 양자화 데이터 타입을 섞을 수 있어요. 예를 들어 임베딩 가중치는 한 양자화 데이터 타입으로, 다른 가중치는 다른 타입으로 양자화할 수 있죠. 양자화 타입을 적절히 혼합하면 비트·가중치당 약간의 증가만으로 훨씬 낮은 양자화 오차를 얻을 수 있어요. 예시 프로그램 llama-quantize는 Q4_K_M, Q8_0 같은 많은 양자화 프리셋을 지원해요.
양자화 오차가 여전히 예상보다 크다면, AWQ로 계산한 것 같은 나만의 스케일을 가져오거나 llama-imatrix로 캘리브레이션 데이터를 사용해 중요도 행렬(importance matrix)을 계산할 수 있어요. 이 행렬은 양자화 중에 사용해 양자화 모델의 품질을 높일 수 있어요.
이 문서에서는 모델을 양자화하고 양자화 모델의 성능을 평가하는 일반적인 방법을 보여드려요. llama.cpp의 예시 프로그램이 있다고 가정할게요. 없다면 여기 가이드를 확인하세요.
GGUF 얻기
이제 Qwen3-8B를 양자화한다고 가정해 볼게요. 먼저 아래처럼 GGUF 파일을 만들어야 해요:
python convert-hf-to-gguf.py Qwen/Qwen3-8B --outfile Qwen3-8B-F16.gguf
Qwen3는 bfloat16 정밀도로 훈련되었기 때문에, 아래 명령이 지원되는 머신에서 대부분의 정보를 보존할 거예요:
python convert-hf-to-gguf.py Qwen/Qwen3-8B --outtype bf16 --outfile Qwen3-8B-BF16.gguf
때로는 양자화의 시작점으로 fp32를 사용하는 것이 더 나을 수도 있어요. 그런 경우:
python convert-hf-to-gguf.py Qwen/Qwen3-8B --outtype f32 --outfile Qwen3-8B-F32.gguf
캘리브레이션 없이 GGUF 양자화
가장 간단한 방법으로, 요구 사항에 따라 모델을 바로 더 낮은 비트로 양자화할 수 있어요. 모델을 8비트로 양자화하는 예시는 아래와 같아요:
./llama-quantize Qwen3-8B-F16.gguf Qwen3-8B-Q8_0.gguf Q8_0
Q8_0은 양자화 프리셋의 코드예요. 모든 프리셋은 llama-quantize의 소스 코드에서 찾을 수 있어요. QUANT_OPTIONS 변수를 찾아보세요. 8B 모델에 흔히 쓰이는 것은 Q8_0, Q5_K_M, Q4_K_M이에요. 대소문자는 상관없어서 q8_0이나 q4_K_m도 완벽히 괜찮아요.
이제 llama.cpp 기반 애플리케이션에서 양자화 모델의 GGUF 파일을 사용할 수 있어요. 정말 간단하죠.
하지만 특히 낮은 비트 양자화에서는 양자화 모델의 정확도가 때때로 예상보다 낮을 수 있어요. 프로그램이 아예 진행을 막을 수도 있고요.
양자화 모델의 품질을 높이는 방법은 여러 가지가 있어요. 일반적인 방법은 대상 도메인의 캘리브레이션 데이터셋을 사용해 진짜 중요한 가중치를 식별하고, 그 가중치가 더 낮은 양자화 오차를 갖도록 모델을 양자화하는 거예요. 이건 다음 두 방법에서 소개할게요.
AWQ 스케일로 GGUF 양자화
⚠️ 주의: 이 부분은 Qwen3 기준으로 업데이트 예정이에요.
양자화 모델의 품질을 높이려면 이 스크립트를 따라 AWQ 스케일을 적용하는 방법이 있답니다.
먼저 autoawq로 model.quantize()를 실행할 때 아래처럼 export_compatible=True를 추가하는 것을 기억하세요:
...
model.quantize(
tokenizer,
quant_config=quant_config,
export_compatible=True
)
model.save_pretrained(quant_path)
...
위 코드는 실제로 가중치를 양자화하지 않아요. 대신 데이터셋을 바탕으로 가중치를 조정해서 양자화하기 "더 쉬워지게" 만들어요.[1]
그 다음 convert-hf-to-gguf.py를 실행할 때 모델 경로를 새 모델 경로로 바꾸는 것을 기억하세요:
python convert-hf-to-gguf.py <quant_path> --outfile qwen2.5-7b-instruct-f16-awq.gguf
마지막으로 지난 예시처럼 모델을 양자화할 수 있어요:
./llama-quantize qwen2.5-7b-instruct-f16-awq.gguf qwen2.5-7b-instruct-q8_0.gguf Q8_0
이렇게 하면 더 낮은 비트·가중치로 비슷한 품질을 달성할 수 있을 거예요.
중요도 행렬로 GGUF 양자화
또 다른 해결책은 "중요도 행렬"[2]을 사용하는 거예요. 이 방법을 따라 진행하세요.
먼저 캘리브레이션 데이터셋(-f)을 사용해 모델(-m) 가중치의 중요도 행렬 데이터를 계산해야 해요:
./llama-imatrix -m Qwen3-8B-F16.gguf -f calibration-text.txt --chunk 512 -o Qwen3-8B-imatrix.dat -ngl 80
텍스트는 계산을 위해 --chunk 길이의 청크로 잘라요. 가급적이면 텍스트가 대상 도메인을 대표해야 해요. 최종 결과는 Qwen3-8B-imatrix.dat(-o)라는 파일에 저장되며, 이를 다음과 같이 사용할 수 있어요:
./llama-quantize --imatrix Qwen3-8B-imatrix.dat \
Qwen3-8B-F16.gguf Qwen3-8B-Q4_K_M.gguf Q4_K_M
1비트나 2비트용의 낮은 비트 양자화 혼합의 경우 --imatrix를 제공하지 않으면 llama-quantize가 도움말 경고를 출력할 거예요.
Perplexity(혼란도) 평가
llama.cpp는 perplexity를 계산하는 예시 프로그램을 제공해요. perplexity는 주어진 텍스트가 모델에 얼마나 "예상 밖"인지 평가하는 지표예요. 주로 비교용으로 사용되며, perplexity가 낮을수록 모델이 주어진 텍스트를 더 잘 기억한다는 뜻이에요.
이를 위해서는 "wiki test" 같은 데이터셋을 준비해야 해요.[3] 다음 명령으로 데이터셋을 다운로드할 수 있어요:
wget https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-2-raw-v1.zip?ref=salesforce-research -O wikitext-2-raw-v1.zip
unzip wikitext-2-raw-v1.zip
그 다음 다음 명령으로 테스트를 실행할 수 있어요:
./llama-perplexity -m Qwen3-8B-Q8_0.gguf -f wiki.test.raw -ngl 80
잠시 기다리면 모델의 perplexity를 얻을 수 있어요. 여기 다양한 종류의 양자화 혼합에 대한 수치들이 있어요. 그 차이를 살펴보고 해당 양자화가 어떤 성능을 낼지 감을 잡는 데 도움이 될 거예요.
마지막으로
이 가이드에서는 llama.cpp로 양자화를 수행하고 perplexity를 평가하는 방법을 보여드렸어요. 더 자세한 내용은 llama.cpp GitHub 저장소를 방문하세요.
우리는 대개 fp16 모델을 다양한 양자화 혼합으로 4, 5, 6, 8비트 모델로 양자화하지만, 때로 특정 혼합이 잘 동작하지 않아서 Hugging Face Hub에 제공하지 않을 때도 있어요. 하지만 커뮤니티의 다른 사람들은 성공할 수도 있으니, 우리 저장소에서 원하는 것을 찾지 못했다면 주변을 둘러보세요.
갓 양자화한 모델을 즐기세요!
[1] 이 의미가 궁금하다면 AWQ 논문을 참고하세요. 기본적으로 데이터 예시 전반의 활성화 값(activations)을 기반으로 중요한 가중치(논문에서는 salient weights)가 식별돼요. 가중치는 그에 따라 스케일되어 양자화 후에도 salient weights가 보호돼요.
[2] 여기서 중요도 행렬은 가중치가 출력에 얼마나 영향을 주는지 기록해요. 값의 작은 변화가 결과에 큰 차이를 만드는 가중치가 중요한 가중치이고, 이는 GPTQ 알고리즘과 유사해요.
[3] 이는 instruct 모델의 좋은 평가 데이터셋은 아니지만 매우 흔하고 쉽게 접근할 수 있어요. 여러분의 대상 도메인과 비슷한 데이터셋을 사용하는 것이 좋을 거예요.