[영상] LLM 파인튜닝 배포 -- QLoRA/QDoRA
평가 & 배포
[영상] LLM 파인튜닝 배포 -- QLoRA/QDoRA
QLoRA 파인튜닝 > 평가 & 배포
- 파인튜닝 모델을 평가하는 축(Perplexity·ROUGE·도메인 벤치마크)이 각각 무엇을 재는지 설명할 수 있다 (이 주에서 코드로 구현하는 것은 ROUGE·BLEU·도메인 지표이고 Perplexity는 개념까지만 다룬다)
- QLoRA 어댑터를 기반 모델에 merge해 단독 배포 가능한 모델을 생성하는 코드를 작성할 수 있다
- GGUF와 GPTQ의 쓰임새 차이를 설명할 수 있다 (이 주의 실습은 GGUF만 다룬다)
- Ollama 또는 llama.cpp를 사용해 로컬 서버에 파인튜닝 모델을 배포하는 절차를 설명할 수 있다
영상 핵심 정리 — LLM 파인튜닝 배포: QLoRA/QDoRA
이 영상은 파인튜닝이 완료된 모델을 어떻게 평가하고, 프로덕션 환경에 배포 가능한 형태로 변환하는지를 다룬다. 어댑터 merge, 양자화 포맷 선택, 로컬/클라우드 배포 전략까지 실전 흐름을 따라간다.
1. 평가 지표 정리
| 지표 | 의미 | 목표값 (예시) |
|---|---|---|
| Perplexity | 모델 예측 확신도 (낮을수록 좋음) | 기반 모델과 같은 평가셋에서 비교 |
| ROUGE-L | 생성 텍스트와 정답의 최장 공통 부분열 | 파인튜닝 전 점수를 기준선으로 삼는다 |
| 도메인 정확도 | 알람 코드 정확 해석 비율 | 본인이 정한 합격선을 먼저 적는다 |
| 응답 속도 | 토큰 생성 속도 (tok/s) | 배포 하드웨어에서 측정 |
목표값 칸을 비워 둔 이유가 있다. 이 표에 남의 숫자를 적어 두면 그 숫자가 그대로 사내 보고서로 옮겨 간다. 기준선은 파인튜닝 전 본인 모델의 점수이고, 합격선은 본인이 정해 근거와 함께 적는다.
그리고 BLEU·ROUGE를 한국어에 그대로 쓸 때의 한계를 Day 4 평가 실습에서 다룬다. 공백으로 잘라 n-gram을 세면 조사와 어미 차이 때문에 잘 쓴 답변도 0점이 나온다.
2. 어댑터 Merge + 양자화 배포 흐름
from peft import PeftModel
from transformers import AutoModelForCausalLM
base_model = AutoModelForCausalLM.from_pretrained(
'meta-llama/Meta-Llama-3.1-8B-Instruct',
torch_dtype=torch.float16, device_map='cpu'
)
model = PeftModel.from_pretrained(base_model, './mfg-adapter')
merged_model = model.merge_and_unload()
merged_model.save_pretrained('./mfg-llama-merged')
# GGUF 변환은 두 단계다. 한 번에 Q4_K_M을 만들 수 없다.
# 1) HuggingFace -> GGUF (f16 등 무손실에 가까운 타입으로만)
python convert_hf_to_gguf.py ./mfg-llama-merged \
--outfile mfg-llama-f16.gguf --outtype f16
# 2) 양자화는 llama-quantize가 한다
./llama-quantize mfg-llama-f16.gguf mfg-llama-Q4_K_M.gguf Q4_K_M
# convert 스크립트의 --outtype에는 q4_K_M이 없다. 넣으면 거절당한다.
# Ollama로 서빙
ollama create mfg-assistant -f Modelfile
ollama run mfg-assistant "CNC-07 E204 알람 원인은?"
3. QDoRA vs QLoRA
LoRA: W' = W + B x A
가중치 갱신 전체를 저랭크 행렬 하나로 학습한다.
("크기만 학습한다"는 설명은 틀렸다. 방향을 안 배우는 것이 아니다.)
DoRA: W 를 크기(magnitude) m 과 방향(direction) V/||V|| 로 분해한 뒤
방향 쪽에만 LoRA 를 얹고 크기는 따로 학습한다.
-> 같은 rank 에서 Full Fine-Tuning 의 학습 양상에 더 가깝다고 논문은 보고한다.
QDoRA: 그 DoRA 를 4비트 베이스 위에서 돌리는 것.이 과정은 DoRA·QDoRA를 이름과 개념까지만 다루고 실습하지 않는다. "rank 4 DoRA가 rank 16 LoRA와 같다"처럼 배수로 외우지 않는다. 개선폭은 과제와 데이터에 따라 다르고, PEFT에서 LoraConfig(use_dora=True)로 켤 수 있으므로 궁금하면 본인 데이터로 직접 비교해 보는 것이 낫다.
함정 주의: merge 전 어댑터만으로 배포하면 기반 모델(8GB+)도 항상 같이 로드해야 해 메모리 낭비가 크다. 프로덕션 배포 전 반드시 merge + 양자화 단계를 거쳐 단일 경량 파일로 만들어야 한다. merge 후 품질 재검증도 필수다.
다음 task와의 연결
다음 reading '제조 sLLM 평가 프레임워크'에서 다섯 개의 평가 축을 정리하고, 그다음 실습에서 BLEU·ROUGE·안전 키워드·수치 정확도를 코드로 계산한다. Perplexity와 MMLU는 이 주에서 구현하지 않는다 — 개념만 알고 넘어간다.
AI 에이전트에게 QLoRA 어댑터를 기반 모델에 병합하고 GGUF/GPTQ 포맷으로 변환하는 코드를 작성하게 하고, 제조 현장 배포 환경에 맞는 포맷 선택 기준을 검토하세요.
QLoRA로 파인튜닝한 제조 도메인 LLM을 배포하는 코드를 작성해줘. model.merge_and_unload()로 LoRA 어댑터를 기반 모델에 병합하고, 현장 엣지 서버(CPU+소형 GPU) 배포용 GGUF와 RTX 3090 서버용 GPTQ 포맷으로 각각 변환하는 방법을 보여줘. Perplexity로 파인튜닝 전후를 비교해 도메인 제조 용어 이해도가 30~50% 향상됐는지 검증하는 코드도 포함해줘.
- • Perplexity(혼란도)는 모델이 다음 토큰을 얼마나 자신 있게 맞히는지를 나타낸다 — 값이 낮을수록 좋다. 다만 파인튜닝 전후를 비교할 때는 같은 평가셋·같은 토크나이저에서 재야 하고, 몇 퍼센트 내려가야 좋은지는 도메인과 데이터에 따라 다르므로 목표치를 미리 못 박지 않는다
- • 어댑터 merge: `model.merge_and_unload()` 한 줄로 LoRA 가중치를 기반 모델에 흡수해 추론 시 추가 오버헤드 없는 단일 모델로 만든다
- • GGUF 포맷(llama.cpp/Ollama용)은 CPU+소형 GPU 배포에 최적, GPTQ(GPU 전용)는 RTX 3090급 서버 배포에 적합하다
- • DoRA(Weight-Decomposed Low-Rank Adaptation)는 가중치 갱신을 크기(magnitude)와 방향(direction)으로 나눠 따로 학습한다. LoRA가 크기만 학습한다는 뜻이 아니라, LoRA는 갱신 전체를 한 덩어리로 학습하고 DoRA는 그것을 둘로 쪼갠다는 뜻이다. QDoRA는 그 DoRA를 4비트 위에서 돌리는 것이다. 이 과정에서는 이름만 다루고 실습하지 않는다
