GGUF (Georgi Gerganov Unified Format)에 관하여
요즘 Hugging Face 저장소를 둘러보면 gguf 라는 포맷이 눈에 자주 들어온다.
기존 Pytorch 모델들은 .pt 라는 확장자를 사용하여 모델의 가중치를 저장하였다.
하지만 최근들어서 LLM 모델의 경우 gguf 포맷으로 넘어가고 있는 추세이다.
오늘은 이러한 gguf 포맷이 무엇인지 살펴보고 pt 포맷 보다 어떠한 장점이 있길래 인기를 얻고 있는지 살펴보려고한다.
PyTorch에서 GGML, 그리고 GGUF로의 진화
초기 LLM 모델 대부분은 PyTorch 와 같은 프레임워크의 기본 포맷인 .pt로 저장되었다.
이러한 포맷은 훈련 목적으로는 적합했지만, 모델을 추론하고 서빙하는데는 효율성과 접근성에 제한이 있었다.
1. 모델 아키텍처 의존성
- .pt 파일은 가중치만 저장하며 모델 클래스의 정의가 코드로 따로 필요하다
- 추론 환경에서 모델 코드 재구성이 불가능하면 로딩이 불가능하다.
2. 추론 최적화 부재
- 훈련용 메타데이터 (옵티마이저, 학습률 등) 등 추론에 필요 없는 불필요한 정보가 포함된다.
- 배치 정규화(BatchNorm)와 드롭아웃 레이어가 기본적으로 훈련 모드로 설정되어 있어, model.eval() 호출을 누락하면 추론 결과가 왜곡된다.
3. 하드웨어의 최적화가 없음
이러한 한계를 극복하기 위해서 GGML(Georgi Gerganov Machine Learning)이라는 텐서 라이브러리가 개발되었다. 이를 통해서 다양한 하드웨어에서 효율적으로 LLM 모델을 실행할 수 있게 해주었다.
그러난 GGML도 한계가 있었다.
- 유연성 부족 : 모델에 추가적인 정보를 포함시키기 어려움
- 호환성 문제 : 새로운 기능 추가시 기존 모델과 호환 문제 발생 및 재빌드 필요
- 수동 조정 필요 : 사용자가 설정을 자주 변경해야 하는 불편함
이러한 한계를 극복하기 위해서 2023년에 GGUF(Georgi Gerganov Unified Format)가 도입되었으며, GGML을 완전히 대체하게 되었다.
What is GGUF?
GGUF는 Georgi Gerganov가 개발한 딥러닝 모델 저장용 단일 파일 포맷이다.
이 포맷은 주로 LLM추론에 사용되며, GGML 라이브러리 기반의 런타임에 사용된다.
GGUF는 다음과 같은 특징을 가지고 있다.
- 단일 파일 구조 : 모델을 하나의 파일로 쉽게 공유할 수 있다.
- 메타데이터와 텐서 데이터 포함 : 모델의 가중치(weight) 텐서 값들과 메타데이터가 key-value 형식으로 저장된다.
- 다양한 양자화 지원 : 16-bit 부동 소수점 뿐만 아니라 8-bit, 6-bit, 5-bit, 4-bit, 3-bit, 2-bit까지 다양한 양자화된 텐서 타입을 지원한다.
- 호환성 : GGML 라이브러리 기반의 런타임에서 주로 사용되며 ,CPU에서도 실행 가능하다.
- 확장성 : 새로운 기능을 추가해도 기존 모델과의 호환성을 유지한다.
GGUF 파일 포맷의 구조
GGUF 파일은 체계적인 구조를 가지고 있으며, 주요 구성 요소는 다음과 같다.
1. 헤더 Header
모든 GGUF 파일은 다음과 같은 헤더로 시작된다.
uint32_t magic; // "GGUF" 문자열의 매직 넘버
uint32_t version; // 파일 포맷 버전
uint64_t n_tensors; // 텐서의 수
uint64_t n_kv; // 키-값 쌍의 수
2. 키-값 쌍 (key-value pairs)
헤더 다음에는 n_kv 개의 키-값 쌍이 온다. 이 메타데이터는 모델에 대한 정보를 제공한다.
struct gguf_kv {
struct gguf_str key; // 키(문자열)
enum gguf_type type; // 값의 타입
union gguf_value value; // 실제 값
};
키-값 쌍에는 다음과 같은 정보가 포함된다.
- 모델의 세부 정보(입력 토큰의 길이, 임베딩 크기, 피드 포워드 길이 등)
- 토크나이저 정보
- 추론에 필요한 기타 정보
3. 텐서 정보 (Tensor info)
n_tensors개의 텐서 정보가 이어진다.
struct gguf_tensor_info {
struct gguf_str name; // 텐서의 이름
uint32_t n_dims; // 차원 수
uint64_t ne[GGML_MAX_DIMS]; // 각 차원의 크기
enum ggml_type type; // 텐서의 타입
uint64_t offset; // 데이터 섹션에서의 오프셋
};
4. 텐서 데이터 (Tensor Contents)
마지막으로 n_tensors 개의 텐서 데이터가 포함된다. 각 텐서의 크기는 텐서의 타입과 차원에 따라 결정된다.
GGUF의 양자화 기법
GGUF의 주요 장점 중 하나는 다양한 양자화 방식을 지원한다는 것이다. 양자화란 모델의 가중치를 더 낮은 비트 정밀도로 변환하는 기술로, 모델의 크기는 줄이고 추론 속도를 높이고 비용을 낮추는데 유용하다.
이러한 방법을 통해서 자신의 하드웨어에 맞게 추론 비용을 조절 할 수 있다.
PyTorch 모델을 GGUF로 변환하는 방법
1. HuggingFace 모델 다운로드
from huggingface_hub import snapshot_download
model_id = "mistralai/Mistral-7B-v0.1" # 변환하려는 모델 ID
local_dir = model_id.split("/")[-1] + "-hf" # 로컬 저장 디렉토리
snapshot_download(repo_id=model_id, local_dir=local_dir)
2. llama.cpp 저장소 클론 및 의존성 설치
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
pip install -r requirements.txt
3. PyTorch 모델을 GGUF로 변환
python convert.py <모델_디렉토리_경로> --outtype f16 --outfile <출력_파일명>.gguf
모델을 양자화 하기위해서는 --outtype 옵션을 사용한다
python convert.py <모델_디렉토리_경로> --outtype q8_0 --outfile <출력_파일명>.gguf
이미 변환된 GGUF 파일을 더 낮은 비트로 양자화하려면 quantize 유틸리티를 사용한다.
./quantize <입력_gguf_파일> <출력_gguf_파일> q4_k_m
GGUF 모델 사용하기
GGUF 모델은 다양한 도구와 라이브러리를 통해 사용할 수 있다.
1. llama.cpp 사용하기
설치
brew install llama.cpp
모델 실행
llama-cli -hf <모델_저장소>:<양자화_버전>
예: llama-cli -hf bartowski/Llama-3.2-3B-Instruct-GGUF:Q8_0
2. 지원되는 라이브러리들
- llama.cpp: CLI 및 서버 옵션을 제공하는 원본 프로젝트
- text-generation-webui: 다양한 기능과 확장 기능을 갖춘 웹 UI
- KoboldCpp: 스토리텔링에 특화된 웹 UI
- LM Studio: Windows 및 macOS용 로컬 GUI
- LoLLMS Web UI: 모델 라이브러리를 포함한 웹 UI
- Faraday.dev: Windows 및 macOS용 캐릭터 기반 채팅 GUI
- ctransformers: LangChain 지원이 있는 Python 라이브러리
- llama-cpp-python: OpenAI 호환 API 서버를 제공하는 Python 라이브러리
- candle: GPU 지원이 있는 Rust ML 프레임워크
GGUF의 장점 및 한계
장점
- 효율성 : 모델의 크기를 크게 줄이면서도 품질을 유지할 수 있다
- 접근성 : CPU 만으로도 모델을 실행할 수 있어 더 많은 사용자가 접근 가능하다
- 확장성 : 새로운 기능을 추가해도 기존 모델과의 호환성이 유지된다.
- 다양한 지원 : 여러 클라아이언트 라이브러리에서 지원된다.
- 메타데이터 포함 : 모델 실행에 필요한 모든 정보를 단일 파일에 포함한다.
한계
- 지원되는 모델 아키텍처의 제한 : 모든 종류의 딥러닝 모델이 지원되지는 않는다. (특히 비전 모델들은 아직 지원되지 않는다)
- 보안 취약성 : 일부 보안 취약점이 있다.