인공지능/직접 해보기

대규모 언어 모델(LLM) 양자화해보기

원담 2025. 6. 27. 17:56
728x90

오늘은 거대한 언어 모델을 나의 PC(CPU든 GPU든!)에서 효율적으로 돌리고 싶을 때 반드시 알아야 할 기술, 바로 '양자화(Quantization)'를 직접 해보았다. 

GGUF: LLM의 새로운 표준 컨테이너

GGUF는 llama.cpp 프로젝트에서 개발한 LLM을 위한 새로운 파일 형식이다. 이 형식은 CPU, NVIDIA GPU, AMD GPU 등 다양한 하드웨어에서 LLM을 효율적으로 로드하고 실행할 수 있도록 설계된 범용적인 컨테이너 형식이다. GGUF는 양자화된 가중치를 담는 데 최적화되어 있다. GGUF는 llama.cpp 생태계의 전용 형식이면서 마치 .exe 파일이 윈도우 운영체제에서 실행되는 것처럼, GGUF 파일은 llama.cpp (또는 GGUF를 지원하는 다른 특수 클라이언트)에서만 직접 로드되고 실행될 수 있도록 설계되었다. GGUF 형식 자체가 llama.cpp가 효율적으로 모델을 로드하고 GPU/CPU에서 최적화된 성능으로 추론을 수행할 수 있도록 만들어졌다.

https://github.com/ggml-org/llama.cpp

 

GitHub - ggml-org/llama.cpp: LLM inference in C/C++

LLM inference in C/C++. Contribute to ggml-org/llama.cpp development by creating an account on GitHub.

github.com

단계 1: llama.cpp 준비 

Llama.cpp는 LLM을 CPU 및 GPU에서 효율적으로 실행할 수 있도록 돕는 도구이다. 특히, 다양한 양자화 방식을 지원하여 모델 경량화에 매우 유용하다. 먼저, Llama.cpp 저장소를 클론하고 필요한 라이브러리를 설치한 후에 LLAMA_CUBLAS=1 옵션을 주어 CUBLAS를 활성화하였다.

# Llama.cpp 저장소 클론
!git clone https://github.com/ggerganov/llama.cpp

# CUBLAS를 활성화하여 컴파일 및 파이썬 요구사항 설치
!cd llama.cpp && LLAMA_CUBLAS=1 make && pip install -r requirements.txt

# 빌드 디렉토리 생성 및 CUDA 활성화하여 CMake 구성
!cd /content/llama.cpp && cmake -B build -DGGML_CUDA=ON

# 빌드 실행 (최대 코어 활용)
!cd /content/llama.cpp && cmake --build build --config Release -j $(nproc)

위 명령어들을 실행하면 Llama.cpp가 성공적으로 빌드되고 빌드된 실행 파일은 llama.cpp/build 디렉토리에 위치하게 된다.

단계2: Hugging Face 모델 다운로드 및 GGUF 변환

이제 양자화할 모델을 Hugging Face에서 다운로드할 차례인데 Qwen/Qwen1.5-1.8B 모델을 선택하였다. snapshot_download 함수를 사용하여 모델 파일을 로컬 디렉토리(original_model/)에 저장하였다.

https://huggingface.co/Qwen/Qwen1.5-1.8B-Chat

 

Qwen/Qwen1.5-1.8B-Chat · Hugging Face

Qwen1.5-1.8B-Chat Introduction Qwen1.5 is the beta version of Qwen2, a transformer-based decoder-only language model pretrained on a large amount of data. In comparison with the previous released Qwen, the improvements include: 8 model sizes, including 0.5

huggingface.co

from huggingface_hub import snapshot_download

model_name = "Qwen/Qwen1.5-1.8B"
base_model = "./original_model/"
quantized_path = "./quantized_model/"

# 베이스 모델 다운로드
snapshot_download(
    repo_id = model_name,
    local_dir = base_model,
    local_dir_use_symlinks = False
)

# quantized_model 디렉토리 생성
!mkdir -p ./quantized_model/

# Hugging Face 모델을 FP16 GGUF 형식으로 변환
# 변환된 파일은 ./quantized_model/FP16.gguf로 저장됩니다.
!python llama.cpp/convert_hf_to_gguf.py ./original_model/ --outtype f16 --outfile ./quantized_model/FP16.gguf

다운로드한 모델은 Hugging Face 형식인데, Llama.cpp에서 사용하려면 GGUF(GPT-Generated Unified Format) 형식으로 변환해야 한다. convert_hf_to_gguf.py 스크립트를 사용하여 모델을 FP16(16비트 부동소수점) GGUF 파일로 변환하였다.

단계3: 모델 양자화 적용하기

GGUF 형식으로 변환된 FP16 모델을 이제 원하는 양자화 방식으로 변환한다. Llama.cpp는 다양한 양자화 방식을 지원하는데, 나는 q4_k_m 방식을 사용하였다. 이것은 4비트 양자화의 한 종류로, 성능 저하를 최소화하면서 모델 크기를 효과적으로 줄여준다.

import os

# 양자화 메소드 정의
methods = ["q4_k_m"]

# 각 메소드에 따라 양자화 수행
for m in methods:
  qtype = f"{quantized_path}/{m.upper()}.gguf"
  # llama.cpp의 quantize 도구를 사용하여 양자화
  os.system(f"./llama.cpp/quantize {quantized_path}/FP16.gguf {qtype} {m}")

이 코드를 실행하면 Q4_K_M.gguf라는 이름의 양자화된 모델 파일이 quantized_model/ 디렉토리에 생성된다.

단계4: 양자화된 모델로 추론 테스트

양자화된 모델이 잘 작동하는지 확인하기 위해 Llama.cpp의 main 실행 파일을 사용하여 간단한 추론을 시도해볼 수 있다. chat-with-bob.txt 프롬프트 파일을 사용하여 모델과 상호작용할 수 있다.

# 양자화된 모델로 추론 실행
! ./llama.cpp/main -m ./quantized_model/Q4_K_M.gguf -n 90 --repeat_penalty 1.0 --color -i -r "User:" -f llama.cpp/prompts/chat-with-bob.txt

위 명령어를 실행하면 양자화된 모델(큐웬)이 프롬프트에 따라 응답하는 것을 볼 수 있다. 

단계5: Hugging Face에 양자화된 모델 업로드

마지막으로, 이렇게 양자화된 모델을 Hugging Face Hub에 업로드하여 다른 사람들과 공유할 수 있다. Hugging Face에 로그인하고, 새로운 저장소(Repository)를 생성한 뒤 파일을 업로드한다.

from huggingface_hub import notebook_login, HfApi, HfFolder, create_repo, upload_file

# Hugging Face 로그인 (토큰 입력 필요)
notebook_login()

# Hugging Face API 객체 생성
api = HfApi()

# 업로드할 모델 파일 경로
model_path = "./quantized_model/Q4_K_M.gguf"

# 모델을 Hugging Face Hub에 업로드
api.upload_file(
    path_or_fileobj=model_path,
    path_in_repo="Q4_K_M.gguf",
    repo_id = "wondam/quantized1-qwen1.5-1.88B-GGUF",
    repo_type="model"
)

마무리

llama.cpp는 모델을 효율적으로 로드하고, 다양한 양자화 옵션을 적용하며, 추론을 수행할 수 있도록 한다. 오늘은 이 과정을 통해 대규모 언어 모델을 다운로드하고, GGUF 형식으로 변환하며, 4비트로 양자화하여 로컬 환경에서 효율적으로 실행하는 과정을 직접 실행해 보았다.

  1. 모델 형식 변환 (Convert) Llama.cpp는 Hugging Face 등 다른 플랫폼에서 사용되는 모델 파일을 GGUF (GPT-Generated Unified Format)라는 전용 형식으로 변환하는 기능을 제공하고 convert_hf_to_gguf.py 스크립트를 사용한 부분이 바로 이 역할을 하였다.
  2. 모델 양자화 (Quantize) GGUF 형식으로 변환된 모델은 다양한 비트(bit) 수로 양자화할 수 있다. 양자화는 모델의 크기를 줄이고 추론 속도를 높이는 핵심 과정이고 이 코드에서는 quantize 도구를 사용하여 16비트 모델을 q4_k_m과 같은 4비트 양자화 모델로 만들었다. 이 과정을 통해 GPU 메모리나 CPU 자원을 훨씬 덜 사용하면서도 모델을 실행할 수 있게 된다.
  3. 모델 실행 마지막으로, 양자화된 GGUF 모델을 실행하여 실제 추론을 수행할 수 있다.

Llama.cpp는 다운로드된 모델을 Llama.cpp에서 사용할 수 있는 형식(GGUF)으로 변환하고, 모델을 양자화하여 경량화한 다음, 최적화된 환경에서 해당 모델을 실행할 수 있게 해주는 올인원(all-in-one) 도구이다. llama.cpp는 LLM(Large Language Model)에 특화되어 개발된 프로젝트이며, 다른 종류의 일반적인 머신러닝 모델(예: 이미지 분류 모델, 음성 인식 모델, 시계열 예측 모델 등)을 직접적으로 다루기 위한 범용적인 도구는 아니라고 한다 LLM의 특정 아키텍쳐와 연산 패턴에 최적화 되어있음을 기억하자. 특히 LLAMA, GPT-2, GPT-J, MPT, Falcon, Qwen 등 텍스트 생성에 사용되는 주요 LLM 모델의 아키텍처를 파싱하고 실행하도록 설계되어있다고 한다(다른 종류의 머신러닝 모델을 GGUF로 변환하지는 못함). 예를들면 ResNet, YOLO등의 모델은 llama.cpp 로 직접 로드하여 실행하기 어렵다.

728x90