33장. 양자화·변환 직접 해보기
이 장의 목표 새 모델이 GGUF·MLX로 안 풀렸을 때, 또는 32장에서 학습한 모델을 배포할 때 직접 변환·양자화 할 수 있게 됩니다.
33.1 두 가지 흐름
[A] Safetensors → GGUF (Q4 등)
→ Ollama / LM Studio / llama.cpp 에서 사용
[B] Safetensors → MLX (4bit 등)
→ mlx-lm / LM Studio MLX 에서 사용
대부분 두 가지 흐름이 필요합니다.
33.2 변환에 필요한 것
- 원본 모델 (Safetensors) — Hugging Face에서 받음
- 충분한 디스크 — 원본 + 변환본 + 양자화본 합쳐 100GB+
- llama.cpp — GGUF 변환·양자화
- mlx-lm — MLX 변환·양자화
- Python 환경
33.3 흐름 A — Safetensors → GGUF
① 원본 다운로드
$ huggingface-cli download \
Qwen/Qwen3-8B-Instruct \
--local-dir ./Qwen3-8B-Instruct
② llama.cpp 의 변환 스크립트
$ git clone https://github.com/ggml-org/llama.cpp
$ cd llama.cpp
$ pip install -r requirements.txt
$ python convert_hf_to_gguf.py \
../Qwen3-8B-Instruct \
--outfile ../qwen3-8b-f16.gguf \
--outtype f16
이러면 f16 GGUF 가 만들어집니다.
양자화 안 한 상태 (약 16GB).
③ 양자화
이 f16 GGUF를 Q4_K_M으로 압축.
$ ./llama-quantize \
../qwen3-8b-f16.gguf \
../qwen3-8b-Q4_K_M.gguf \
Q4_K_M
| 양자화 타입 | 결과 크기 |
|---|---|
Q2_K | 약 25% |
Q3_K_M | 약 35% |
Q4_K_M | 약 45% ★ |
Q5_K_M | 약 55% |
Q6_K | 약 65% |
Q8_0 | 약 85% |
④ Ollama로 등록
# Modelfile
FROM ./qwen3-8b-Q4_K_M.gguf
$ ollama create my-qwen3-8b -f Modelfile
$ ollama run my-qwen3-8b
이제 평범한 Ollama 모델처럼 씁니다.
33.4 흐름 B — Safetensors → MLX
훨씬 단순합니다.
$ pip install -U mlx-lm
$ mlx_lm.convert \
--hf-path Qwen/Qwen3-8B-Instruct \
--mlx-path ./mlx-qwen3-8b-4bit \
-q --q-bits 4
-q 가 양자화 적용 옵션.
기본은 4bit, --q-bits 8 로 8bit도 가능.
결과는 폴더로 저장:
mlx-qwen3-8b-4bit/
├── config.json
├── model.safetensors
├── tokenizer.json
└── ...
바로 사용:
$ mlx_lm.generate \
--model ./mlx-qwen3-8b-4bit \
--prompt "안녕"
33.5 LoRA 합치고 변환 — 흐름 A 전체
32장에서 학습한 LoRA를 GGUF로 배포하려면:
1. mlx_lm.fuse 로 베이스 + LoRA 합치기
→ ./fused-model/ (Safetensors)
2. ./fused-model/ 을 HuggingFace 형식으로 변환
3. convert_hf_to_gguf.py 로 GGUF f16 변환
4. llama-quantize 로 Q4_K_M 양자화
5. Ollama Modelfile 로 등록
33.6 양자화 타입 선택 가이드
5장의 표 + 실전 권장:
| 모델 크기 | 64GB 맥 추천 |
|---|---|
| 3~4B | Q6_K 또는 Q8_0 |
| 7~8B | Q5_K_M 또는 Q6_K |
| 14B | Q5_K_M |
| 27~32B | Q4_K_M 또는 Q5_K_M |
| 70B+ | Q4_K_M (체험용) |
메모리 여유 있으면 한 단계 위.
33.7 변환 시 자주 만나는 문제
디스크 부족
f16 GGUF는 원본 Safetensors와 비슷한 크기. 원본 + f16 + 양자화 = 3배 필요.
해결: 외장 SSD 사용, 또는 단계마다 이전 파일 삭제.
Tokenizer 호환 오류
새 모델은 토크나이저가 기존 llama.cpp에서 미지원일 수 있음. → llama.cpp를 최신으로 업데이트:
$ cd llama.cpp
$ git pull
$ make clean && make
$ pip install -r requirements.txt --upgrade
Chat template 누락
GGUF 변환 시 chat template이 안 들어갔다면 Modelfile에 명시:
FROM ./model.gguf
TEMPLATE """{{ .Prompt }}"""
22장 참고.
MLX 변환 메모리 부족
--q-bits 4 --q-group-size 64 등 옵션 조정,
또는 swap 활성화.
33.8 imatrix 양자화 — 한 단계 위
품질을 더 높이는 고급 기법.
$ ./llama-imatrix \
-m ../qwen3-8b-f16.gguf \
-f calibration.txt \
-o imatrix.dat
$ ./llama-quantize \
--imatrix imatrix.dat \
../qwen3-8b-f16.gguf \
../qwen3-8b-Q4_K_M-imatrix.gguf \
Q4_K_M
calibration.txt 는 대표적인 텍스트 샘플 (영어/한국어 골고루).
저비트(Q2~Q3) 에서 품질 효과 큼.
bartowski 의 양자화가 인기 있는 이유 중 하나가
imatrix 사용입니다.
33.9 Hugging Face Hub 업로드
내가 만든 양자화를 공유하고 싶다면:
$ pip install -U huggingface_hub
$ huggingface-cli login
$ huggingface-cli upload \
내계정/qwen3-8b-custom-Q4_K_M \
qwen3-8b-Q4_K_M.gguf
라이선스(12장)와 출처 표기 잊지 마세요.
33.10 운영 팁
- 변환·양자화는 한 번이면 충분 — 결과를 백업
- f16 GGUF 보관: 나중에 다른 양자화 만들 때 다시 변환 안 해도 됨
- 사내 회사 공통 모델은 사내 모델 저장소(MinIO/S3 등)에 Modelfile과 함께 보관
이 장에서 기억할 한 가지
GGUF 흐름: convert_hf_to_gguf.py → llama-quantize MLX 흐름: mlx_lm.convert -q
LoRA 합쳐 GGUF 배포 =
mlx_lm.fuse→ 변환 → 양자화 → Modelfile.
손으로 해볼 것
1. 작은 모델로 전체 흐름 한 번
Qwen3-1.7B-Instruct 같은 작은 모델로
- Safetensors 다운로드
- f16 GGUF 변환
- Q4_K_M 양자화
- Ollama 등록
모두 30분 안에 가능.
2. MLX 변환과 속도 비교
같은 베이스를 MLX 4bit로도 만들어 LM Studio에서 두 버전을 토글하며 속도 비교.
다음 장에서는 환각·Alignment·거절 — 모델이 헛소리하는 이유와 어떻게 줄이는지를 봅니다.