GGUF 모델 포맷
llama.cpp 기반 로컬 LLM 모델 포맷의 구조, 양자화, 변환 워크플로 상세 가이드
개요
Ollama는 GGUF (Georgi Gerganov Unified Format) 파일 형식을 사용합니다. GGUF는 Georgi Gerganov가 개발한 llama.cpp 프로젝트의 핵심 모델 포맷으로, 로컬 환경에서 LLM을 효율적으로 실행하기 위해 설계되었습니다. 현재 Ollama, LM Studio, llama.cpp, GPT4All 등 대부분의 로컬 LLM 런타임이 GGUF를 표준 포맷으로 채택하고 있습니다.
초기 llama.cpp는 GGML (Georgi Gerganov Machine Learning) 포맷을 사용했습니다. GGML은 모델 가중치만 저장하고, 토크나이저와 메타데이터는 별도 파일로 관리해야 했습니다. 2023년 8월, 이러한 한계를 극복하기 위해 GGUF가 등장했습니다. GGUF는 모델 가중치, 토크나이저, 하이퍼파라미터, 아키텍처 정보를 단일 파일에 모두 포함하여 모델 배포와 관리를 획기적으로 단순화했습니다.
GGML에서 GGUF로의 진화: 분산된 파일 → 단일 자기 완결적 파일
포맷 구조와 양자화
GGUF 버전 히스토리
GGUF는 출시 이후 지속적으로 발전해왔습니다. 각 버전은 하위 호환성을 유지하면서 새로운 기능을 추가합니다.
GGUF 포맷 버전 타임라인: GGML → v1 → v2 → v3 (현재 표준)
GGUF 파일 내부 구조
GGUF 파일은 바이너리 포맷으로, 정해진 구조에 따라 순차적으로 데이터를 배치합니다. 모든 정보가 하나의 파일에 포함되므로 별도의 설정 파일 없이 모델을 로드할 수 있습니다.
GGUF 파일 바이너리 레이아웃: Magic → Header → Metadata → Tensor Info → Tensor Data
GGUF의 핵심 설계 원칙은 자기 설명적(self-describing) 구조입니다. 파일 자체에 모델을 로드하는 데 필요한 모든 정보가 담겨 있으므로, 외부 설정 파일이나 코드 없이도 모델의 아키텍처, 양자화 방식, 토크나이저 종류를 파악할 수 있습니다.
# GGUF 파일 정보 확인 (llama.cpp 도구)
# gguf-dump: 메타데이터와 텐서 구조를 출력
$ python3 -c "
from gguf import GGUFReader
reader = GGUFReader('model.gguf')
print(f'GGUF Version: {reader.header.version}')
print(f'Tensor Count: {reader.header.tensor_count}')
print(f'Metadata KV Count: {reader.header.metadata_kv_count}')
for kv in reader.fields.values():
print(f' {kv.name}: {kv.data}')
"
# 출력 예시
GGUF Version: 3
Tensor Count: 291
Metadata KV Count: 23
general.architecture: llama
general.name: Llama 3.2 3B Instruct
llama.context_length: 131072
llama.embedding_length: 3072
llama.block_count: 28
llama.attention.head_count: 24
tokenizer.ggml.model: gpt2
general.quantization_version: 2
바이너리 헤더 Hex Dump
실제 GGUF 파일의 첫 바이트를 살펴보면 포맷의 구조를 직접 확인할 수 있습니다.
아래는 hexdump 명령으로 확인한 GGUF v3 파일의 헤더 영역입니다.
# GGUF 파일 헤더 Hex Dump 확인
$ hexdump -C model.gguf | head -n 4
00000000 47 47 55 46 03 00 00 00 17 00 00 00 00 00 00 00 |GGUF............|
00000010 23 01 00 00 00 00 00 00 14 00 00 00 00 00 00 00 |#...............|
╰─┬────────╯ ╰─┬────────╯ ╰─┬────────────────────╯ ╰─┬────────────────────╯
Magic Number Version=3 tensor_count=23(0x17) metadata_kv_count=291(0x123)
# 상세 구조 해설
Offset 0x00-0x03: 47 47 55 46 → "GGUF" (ASCII, Little-Endian)
Offset 0x04-0x07: 03 00 00 00 → version = 3 (uint32_t LE)
Offset 0x08-0x0F: 17 00 00 00 00 00 00 00 → tensor_count = 23 (uint64_t LE)
Offset 0x10-0x17: 23 01 00 00 00 00 00 00 → metadata_kv_count = 291 (uint64_t LE)
# 파일 전체 구조 오프셋 확인
$ python3 -c "
import struct
with open('model.gguf', 'rb') as f:
magic = f.read(4)
version = struct.unpack('<I', f.read(4))[0]
n_tensors = struct.unpack('<Q', f.read(8))[0]
n_kv = struct.unpack('<Q', f.read(8))[0]
print(f'Magic: {magic}')
print(f'Version: {version}')
print(f'Tensors: {n_tensors}')
print(f'KV pairs: {n_kv}')
"
Magic: b'GGUF'
Version: 3
Tensors: 23
KV pairs: 291
GGUF 파일은 반드시 0x47475546 ("GGUF"의 ASCII) 매직 넘버로 시작합니다.
빅 엔디안 시스템에서는 0x47475546이 그대로, 리틀 엔디안에서도 0x46554747이 아닌
동일한 바이트 순서(47 47 55 46)를 사용합니다. 이를 통해 파일의 엔디안을 감지합니다.
만약 첫 4바이트가 46 55 47 47이면 빅 엔디안 GGUF로 판별합니다.
메타데이터 KV 상세
GGUF 메타데이터는 Key-Value 쌍으로 구성됩니다.
키는 네임스페이스 규칙(general.*, {arch}.*, tokenizer.*)을 따릅니다.
| 네임스페이스 | 주요 키 | 설명 |
|---|---|---|
| general.* | architecture, name, author, license, description | 모델 기본 정보 (아키텍처 종류, 이름, 라이선스 등) |
| {arch}.* | context_length, embedding_length, block_count, attention.head_count | 아키텍처별 하이퍼파라미터 (llama.*, mistral.*, phi.* 등) |
| tokenizer.* | ggml.model, ggml.tokens, ggml.scores, ggml.bos_token_id | 토크나이저 종류, 어휘, 특수 토큰 ID |
| quantize.* | imatrix.file, imatrix.dataset | 양자화에 사용된 중요도 행렬(importance matrix) 정보 |
메타데이터 값 타입
GGUF 메타데이터의 각 Key-Value 쌍에서 Value는 다음 타입 중 하나를 가집니다. 이 타입 시스템 덕분에 메타데이터를 파싱할 때 별도의 스키마 파일이 필요 없습니다.
| 타입 ID | 타입명 | 크기 | 사용 예 |
|---|---|---|---|
| 0 | UINT8 | 1B | 불리언 플래그 |
| 1 | INT8 | 1B | - |
| 2 | UINT16 | 2B | - |
| 3 | INT16 | 2B | - |
| 4 | UINT32 | 4B | context_length, head_count |
| 5 | INT32 | 4B | - |
| 6 | FLOAT32 | 4B | rope_freq_base, layer_norm_eps |
| 7 | BOOL | 1B | - |
| 8 | STRING | 가변 | architecture, name, license |
| 9 | ARRAY | 가변 | tokenizer.ggml.tokens (어휘 목록) |
| 10 | UINT64 | 8B | - |
| 11 | INT64 | 8B | - |
| 12 | FLOAT64 | 8B | - |
지원 아키텍처
general.architecture 키는 모델의 아키텍처 종류를 지정합니다.
GGUF는 현재 다양한 Transformer 변형 아키텍처를 지원하며, 지속적으로 확장되고 있습니다.
| 아키텍처 ID | 대표 모델 | 설명 |
|---|---|---|
llama | Llama 2/3, Mistral, Yi, Qwen2 | 가장 보편적. RoPE + GQA/MHA 기반 디코더 |
falcon | Falcon 7B/40B/180B | Multi-query attention 기반 |
gpt2 | GPT-2 | 원조 GPT 아키텍처 |
gptj | GPT-J 6B | Rotary embedding + parallel attention |
gptneox | GPT-NeoX, Pythia | EleutherAI 계열 |
mpt | MPT 7B/30B | ALiBi attention, FlashAttention |
baichuan | Baichuan 7B/13B | 중국어 특화 |
starcoder | StarCoder, StarCoder2 | 코드 생성 특화 |
phi2 | Phi-2, Phi-3 | Microsoft 소형 고효율 모델 |
gemma | Gemma, Gemma 2 | Google 오픈 웨이트 모델 |
command-r | Command R/R+ | Cohere RAG 특화 모델 |
qwen2 | Qwen2, Qwen2.5 | Alibaba 다국어 모델 |
deepseek2 | DeepSeek-V2/V3 | MoE (Mixture of Experts) 아키텍처 |
GGUF가 지원하는 다양한 아키텍처: 하나의 포맷으로 수십 종의 모델을 통합
GGUF 지원 데이터 타입
GGUF는 원본 부동소수점부터 극도로 압축된 양자화 타입까지 다양한 데이터 타입을 지원합니다. 각 타입은 메모리 효율과 추론 품질 사이의 트레이드오프를 제공합니다.
| 타입 | 비트/가중치 | 블록 크기 | 설명 |
|---|---|---|---|
| F32 | 32-bit | - | 원본 정밀도. 학습/변환 중간 단계에서 사용 |
| F16 | 16-bit | - | 반정밀도. 원본에 가까운 품질, GPU 추론 최적 |
| BF16 | 16-bit | - | Brain Float16. 넓은 지수 범위, 학습에 유리 |
| Q8_0 | 8-bit | 32 | 8비트 양자화. 품질 손실 최소, 크기 50% 감소 |
| Q5_K_M | 5-bit | 32 | K-quant (중요도 기반). 품질/크기 균형 우수 |
| Q4_K_M | 4-bit | 32 | 가장 널리 사용. 실용적 품질, 크기 75% 감소 |
| Q4_0 | 4-bit | 32 | 기본 4비트. K-quant보다 단순하지만 빠름 |
| Q3_K_M | 3-bit | 32 | 3비트. 리소스 제한 환경에서 사용 |
| Q2_K | 2-bit | 32 | 2비트. 극한 압축, 품질 저하 주의 |
| IQ4_XS | ~4-bit | 256 | i-quant (중요도 행렬). 같은 비트에서 더 높은 품질 |
| IQ3_XXS | ~3-bit | 256 | i-quant 극압축. 연구/실험용 |
- Q{n}_0: 기본(legacy) 양자화 — 단순하고 빠르지만 품질 낮음
- Q{n}_K_S / Q{n}_K_M / Q{n}_K_L: K-quant — 레이어별 중요도 기반 양자화 (S=Small, M=Medium, L=Large).
_M이 가장 일반적 - IQ{n}_*: i-quant — 중요도 행렬(imatrix)을 사용하여 더 정교한 양자화. 같은 비트에서 Q보다 높은 품질
블록 양자화 동작 원리
GGUF의 양자화는 블록 단위로 작동합니다. 가중치를 작은 블록(보통 32개씩)으로 나누고, 각 블록마다 스케일 팩터와 양자화된 정수 값을 저장합니다. 추론 시에는 역양자화(dequantization)하여 부동소수점으로 복원합니다.
Q4_0 블록 양자화: 32개 FP16 가중치(64B) → 스케일+양자화값(18B)으로 72% 압축
양자화 기법 심화 비교
GGUF는 세 가지 주요 양자화 패밀리를 지원합니다. 각 기법은 정밀도와 성능의 트레이드오프가 다릅니다.
세 가지 양자화 기법 비교: Legacy(속도) vs K-Quant(균형, 추천) vs i-Quant(품질)
모델 크기별 양자화 벤치마크
실제 모델에 양자화를 적용했을 때의 파일 크기와 품질(Perplexity) 변화입니다. Perplexity(PPL)는 낮을수록 좋으며, 언어 모델이 텍스트를 얼마나 잘 예측하는지를 나타냅니다.
| 양자화 | 7B 크기 | 7B PPL | 13B 크기 | 13B PPL | 70B 크기 | 70B PPL |
|---|---|---|---|---|---|---|
| F16 | 13.5 GB | 5.59 | 25.0 GB | 5.09 | 131 GB | 3.32 |
| Q8_0 | 7.2 GB | 5.60 | 13.3 GB | 5.09 | 69.4 GB | 3.32 |
| Q6_K | 5.5 GB | 5.60 | 10.3 GB | 5.10 | 53.7 GB | 3.33 |
| Q5_K_M | 4.8 GB | 5.63 | 9.0 GB | 5.11 | 46.7 GB | 3.34 |
| Q4_K_M | 4.1 GB | 5.68 | 7.6 GB | 5.14 | 39.6 GB | 3.36 |
| Q4_0 | 3.8 GB | 5.77 | 7.0 GB | 5.20 | 36.2 GB | 3.39 |
| IQ4_XS | 3.7 GB | 5.66 | 6.8 GB | 5.12 | 35.0 GB | 3.35 |
| Q3_K_M | 3.3 GB | 5.93 | 6.1 GB | 5.30 | 31.7 GB | 3.45 |
| IQ3_XXS | 2.7 GB | 5.85 | 4.9 GB | 5.24 | 25.6 GB | 3.41 |
| Q2_K | 2.5 GB | 6.79 | 4.7 GB | 5.79 | 24.6 GB | 3.72 |
7B 모델 양자화 트레이드오프: Q4_K_M이 크기 대비 품질의 최적점(Sweet Spot)
- 품질 최우선: Q8_0 — PPL 손실 거의 없음, F16 대비 47% 크기 절감
- 최적 균형 (추천): Q4_K_M — PPL 약 1.6% 증가, 크기 70% 절감. 대부분의 작업에서 체감 차이 없음
- 극한 압축: IQ4_XS — Q4_K_M보다 작으면서 비슷한 품질 (imatrix 필요)
- RAM 극히 부족: IQ3_XXS 또는 Q2_K — 품질 저하 감수. 테스트 후 사용 권장
- 모델이 클수록 양자화 영향 작음 — 70B Q4_K_M은 7B F16보다 품질이 높음
다른 모델 포맷과의 비교
주요 모델 포맷 비교: GGUF는 로컬 CPU/GPU 추론에 최적화된 포맷
| 비교 항목 | GGUF | SafeTensors | PyTorch (.pt) | ONNX |
|---|---|---|---|---|
| 주요 용도 | 로컬 추론 | 학습/배포 | 연구/학습 | 프로덕션 배포 |
| 양자화 | 2~8비트 내장 | 미지원 | 미지원 | 제한적 |
| CPU 추론 | 최적화됨 | 비효율적 | 비효율적 | 보통 |
| GPU 추론 | 지원 (부분 오프로드) | 최적 | 최적 | 지원 |
| 메모리 매핑 | ✅ mmap | ✅ mmap | ❌ | ✅ |
| 보안 | 안전 (바이너리) | 안전 | ⚠️ pickle 위험 | 안전 |
| 메타데이터 | 풍부 (KV 쌍) | 제한적 | 없음 | 연산 그래프 |
| 단일 파일 | ✅ | ⚠️ (분할 가능) | ⚠️ (분할 가능) | ✅ |
| 변환 난이도 | 쉬움 (llama.cpp) | 쉬움 | 기본 포맷 | 보통 |
메모리 매핑(mmap)과 GGUF
GGUF가 빠르게 모델을 로드할 수 있는 핵심 비결은 메모리 매핑(mmap)입니다. 일반적인 파일 로딩은 디스크→RAM 전체 복사가 필요하지만, mmap은 운영체제의 가상 메모리 시스템을 활용하여 파일을 직접 메모리 공간에 매핑합니다.
일반 파일 로딩 vs mmap: GGUF는 mmap을 통해 즉시 로딩과 메모리 공유를 실현
GPU 오프로딩 (Partial Offload)
GGUF 기반 추론 엔진(llama.cpp, Ollama)은 모델의 레이어를 GPU와 CPU에 분산하여 배치할 수 있습니다.
이를 GPU 오프로딩이라 하며, VRAM이 모델 전체를 수용하지 못할 때 핵심적인 기능입니다.
--n-gpu-layers (줄여서 -ngl) 파라미터로 GPU에 올릴 레이어 수를 지정합니다.
GPU 오프로딩 시나리오: CPU Only → Partial → Full GPU (속도 10~20배 차이)
# Ollama에서 GPU 레이어 수 지정
OLLAMA_NUM_GPU_LAYERS=20 ollama run llama3.2:3b
# llama.cpp 직접 사용 시
./llama-cli -m model.gguf -ngl 99 # 전체 GPU 오프로드
./llama-cli -m model.gguf -ngl 20 # 20개 레이어만 GPU
./llama-cli -m model.gguf -ngl 0 # CPU 전용 (GPU 미사용)
# VRAM 사용량 실시간 모니터링
watch -n 1 nvidia-smi # NVIDIA GPU
# macOS: 활성 상태 보기 → GPU 히스토리
GGUF 변환 워크플로
Hugging Face의 SafeTensors/PyTorch 모델을 GGUF로 변환하는 과정입니다.
llama.cpp 프로젝트의 convert_hf_to_gguf.py 스크립트를 사용합니다.
# 1. llama.cpp 클론 및 빌드
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
pip install -r requirements.txt
# 2. Hugging Face 모델을 GGUF F16으로 변환
python convert_hf_to_gguf.py \
/path/to/hf-model \
--outfile model-f16.gguf \
--outtype f16
# 3. 양자화 적용 (F16 → Q4_K_M)
./llama-quantize model-f16.gguf model-q4km.gguf Q4_K_M
# 중요도 행렬(imatrix) 기반 양자화 (더 높은 품질)
# 먼저 imatrix 생성
./llama-imatrix \
-m model-f16.gguf \
-f calibration-data.txt \
-o imatrix.dat
# imatrix를 사용한 양자화
./llama-quantize \
--imatrix imatrix.dat \
model-f16.gguf \
model-iq4xs.gguf IQ4_XS
GGUF 변환 파이프라인: HuggingFace 모델 → F16 → 양자화 → Ollama 실행
GGUF 핵심 특징 요약
| 특징 | 설명 |
|---|---|
| 단일 파일 | 모델 가중치, 토크나이저, 하이퍼파라미터, 아키텍처 메타데이터를 하나의 .gguf 파일로 패키징. 파일 하나만 옮기면 모델 이동 완료 |
| 다양한 양자화 | Q2_K ~ Q8_0, IQ 시리즈 등 10가지 이상의 양자화 레벨 내장 지원. K-quant, i-quant 등 고급 양자화 기법 포함 |
| 메모리 매핑 | mmap을 통한 즉시 로딩, 멀티 프로세스 메모리 공유, OS 레벨 캐싱 자동 활용 |
| 자기 설명적 | 확장 가능한 KV 메타데이터로 모델의 모든 정보를 파일 자체에서 확인 가능. 외부 설정 파일 불필요 |
| 크로스 플랫폼 | Windows, Linux, macOS (ARM/x86) 모두 지원. 엔디안 표준화로 플랫폼 간 바이너리 호환 |
| 확장성 | 버전 관리 시스템으로 하위 호환성 유지. 새로운 양자화 타입이나 메타데이터 추가 시 기존 파일과 호환 |
| 광범위한 지원 | Ollama, LM Studio, llama.cpp, GPT4All, KoboldCpp, text-generation-webui 등 대부분의 로컬 LLM 도구가 지원 |
GGUF Split — 대용량 모델 분할
70B 이상의 대형 모델은 단일 GGUF 파일이 수십 GB에 달합니다. 일부 파일 시스템(FAT32 등)은 4GB 제한이 있고, 대용량 파일 전송 시 문제가 될 수 있습니다. GGUF v3부터 파일 분할(Split)을 공식 지원합니다.
# GGUF 파일 분할 (llama.cpp 도구)
./llama-gguf-split --split-max-size 8G model-70b-q4km.gguf model-70b-q4km
# 결과: 분할된 파일들
model-70b-q4km-00001-of-00005.gguf # 8GB
model-70b-q4km-00002-of-00005.gguf # 8GB
model-70b-q4km-00003-of-00005.gguf # 8GB
model-70b-q4km-00004-of-00005.gguf # 8GB
model-70b-q4km-00005-of-00005.gguf # 나머지
# 분할된 파일 다시 병합
./llama-gguf-split --merge model-70b-q4km-00001-of-00005.gguf merged-model.gguf
# Ollama는 분할 파일도 직접 사용 가능
# Modelfile에서 첫 번째 파일만 지정하면 나머지를 자동 탐지
FROM ./model-70b-q4km-00001-of-00005.gguf
Transformer 블록과 GGUF 텐서 매핑
GGUF 파일 내부의 텐서 이름은 Transformer 아키텍처의 각 구성 요소에 직접 매핑됩니다. 텐서 이름을 이해하면 모델의 구조를 파일 레벨에서 파악할 수 있습니다.
Llama 아키텍처의 GGUF 텐서 이름: blk.{i}.attn_q/k/v, ffn_gate/up/down 등
# GGUF 파일의 텐서 목록 확인
$ python3 -c "
from gguf import GGUFReader
reader = GGUFReader('llama-3.2-3b-q4km.gguf')
for tensor in reader.tensors:
dims = ' × '.join(str(d) for d in tensor.shape)
print(f'{tensor.name:40s} [{dims}] {tensor.tensor_type.name}')
"
# 출력 예시 (Llama 3.2 3B)
token_embd.weight [128256 × 3072] Q4_K
blk.0.attn_norm.weight [3072] F32
blk.0.attn_q.weight [3072 × 3072] Q4_K
blk.0.attn_k.weight [3072 × 1024] Q4_K
blk.0.attn_v.weight [3072 × 1024] Q6_K
blk.0.attn_output.weight [3072 × 3072] Q4_K
blk.0.ffn_norm.weight [3072] F32
blk.0.ffn_gate.weight [3072 × 8192] Q4_K
blk.0.ffn_up.weight [3072 × 8192] Q4_K
blk.0.ffn_down.weight [8192 × 3072] Q6_K
... (blk.1 ~ blk.27 동일 패턴 반복)
output_norm.weight [3072] F32
output.weight [128256 × 3072] Q6_K
위 출력에서 attn_v.weight와 ffn_down.weight는 Q6_K(6비트)로,
나머지는 Q4_K(4비트)로 양자화된 것을 볼 수 있습니다.
이것이 K-quant의 핵심 — 모델 품질에 민감한 텐서는 높은 정밀도를,
덜 민감한 텐서는 낮은 정밀도를 적용하여 전체 품질을 유지하면서 크기를 줄입니다.
_norm.weight는 항상 F32로 유지되는데, 정규화 파라미터는 극히 작은 크기이면서
품질에 큰 영향을 주기 때문입니다.
HuggingFace에서 GGUF 모델 찾기
HuggingFace Hub에서 GGUF 모델을 효율적으로 찾고 올바른 양자화 버전을 선택하는 방법입니다.
# HuggingFace Hub에서 GGUF 모델 검색
# https://huggingface.co/models?library=gguf
# 주요 GGUF 양자화 제공자
# ① bartowski — 가장 활발한 GGUF 변환자, imatrix 적용
# ② unsloth — Llama/Mistral 계열 최적화 변환
# ③ mmnga — 일본어/다국어 모델 GGUF 변환
# huggingface-cli로 직접 다운로드
pip install huggingface-hub
huggingface-cli download \
bartowski/Llama-3.2-3B-Instruct-GGUF \
--include "*Q4_K_M.gguf" \
--local-dir ./models
# 특정 양자화만 골라서 다운로드 (와일드카드)
huggingface-cli download \
bartowski/Qwen2.5-7B-Instruct-GGUF \
--include "*Q5_K_M.gguf" \
--local-dir ./models
# Ollama에서 직접 Hugging Face GGUF 사용 (v0.4+)
ollama run hf.co/bartowski/Llama-3.2-3B-Instruct-GGUF:Q4_K_M
- 모델 이름에 "-GGUF"가 붙은 리포지토리를 찾으세요 (예:
Llama-3.2-3B-Instruct-GGUF) - imatrix 적용 여부 확인 — README에 "importance matrix" 언급이 있으면 더 높은 품질
- 양자화 선택 기준: VRAM/RAM 여유에 맞는 파일 크기 확인 후,
Q4_K_M부터 시작 - 파일명 규칙:
모델명-Q{비트}_{방식}_{크기}.gguf(예:model-Q4_K_M.gguf) - 최신 변환자 선호: bartowski, unsloth 등 활발히 활동하는 변환자의 모델이 최신 llama.cpp와 호환될 가능성이 높음
GGUF 생태계 도구 모음
| 도구 | 설명 | 주요 명령/용도 |
|---|---|---|
| llama-quantize | F16/F32 GGUF를 양자화 | llama-quantize model-f16.gguf model-q4km.gguf Q4_K_M |
| llama-imatrix | 중요도 행렬(imatrix) 생성 | llama-imatrix -m model.gguf -f calib.txt -o imatrix.dat |
| llama-gguf-split | GGUF 파일 분할/병합 | llama-gguf-split --split-max-size 8G model.gguf out |
| convert_hf_to_gguf.py | HuggingFace → GGUF 변환 | python convert_hf_to_gguf.py /path/to/model --outtype f16 |
| gguf-py (Python) | GGUF 파일 읽기/쓰기 라이브러리 | pip install gguf → GGUFReader, GGUFWriter |
| llama-cli | GGUF 모델 CLI 추론 | llama-cli -m model.gguf -p "Hello" -ngl 99 |
| llama-server | GGUF 모델 HTTP 서버 (OpenAI 호환) | llama-server -m model.gguf --port 8080 -ngl 99 |
| llama-perplexity | 모델 품질 벤치마크 (PPL 측정) | llama-perplexity -m model.gguf -f wikitext-2-raw/wiki.test.raw |
GGUF 생태계: 소스 모델 → 변환 → .gguf → 다양한 런타임 → 외부 앱 통합
GGUF 자주 묻는 질문 (FAQ)
| 질문 | 답변 |
|---|---|
| GGUF와 GGML의 차이는? | GGML은 가중치만 저장하는 구 포맷. GGUF는 토크나이저, 메타데이터까지 단일 파일에 포함하는 후속 포맷. 2023년 8월 이후 GGML은 폐기되었으며 모든 도구가 GGUF로 전환 |
| Q4_K_M과 Q4_0의 차이는? | Q4_0은 모든 레이어를 동일하게 4비트로 양자화. Q4_K_M은 중요한 레이어(attention value, ffn_down 등)를 6비트로 유지하여 같은 비트에서 더 높은 품질 제공. 파일 크기는 Q4_K_M이 약 8% 큼 |
| 양자화하면 모델이 "멍청해"지나? | Q4_K_M 기준으로 Perplexity 증가는 약 1~2%에 불과. 대부분의 일상 작업(코드 생성, 대화, 요약)에서 체감 차이 거의 없음. 단, Q2_K 이하에서는 눈에 띄는 품질 저하 발생 |
| GPU가 없어도 되나? | 가능. GGUF의 핵심 장점이 CPU 추론 최적화. 양자화된 4비트 모델은 CPU에서도 충분히 사용 가능. 단, GPU를 사용하면 10~20배 빠름 |
| GGUF를 직접 파인튜닝할 수 있나? | 불가. GGUF는 추론 전용 포맷. 파인튜닝은 SafeTensors/PyTorch 형태로 수행 후 GGUF로 변환해야 함. LoRA 어댑터는 별도 적용 가능 |
| 최대 지원 모델 크기는? | 이론적 제한 없음 (64비트 오프셋). 실무적으로 405B (Llama 3.1 405B) 모델까지 GGUF로 변환·실행 사례 있음. 파일 분할(Split)로 대용량 처리 |
| SafeTensors와 GGUF 중 뭘 받아야? | 로컬에서 Ollama/LM Studio로 추론하려면 GGUF. HuggingFace Transformers로 학습/파인튜닝하려면 SafeTensors. 둘 다 필요하면 SafeTensors 받아서 GGUF로 변환 |
| imatrix(i-quant) 꼭 필요한가? | Q4_K_M 이상에서는 거의 차이 없음. IQ3_XXS, IQ2_XXS 등 극압축 양자화에서만 의미 있는 품질 차이 발생. 캘리브레이션 데이터셋이 필요하여 추가 작업 소요 |
실무 팁
- GGUF 모델은 Q4_K_M 양자화가 대부분의 용도에서 최적의 품질/크기 균형을 제공합니다.
- GPU VRAM이 부족하면
-ngl옵션으로 일부 레이어만 GPU에 올리세요. - HuggingFace에서 GGUF 모델을 받을 때는 bartowski, unsloth 등 활발한 변환자의 모델을 선택하세요.