M2: 핵심 기능 MVP¶
| 항목 | 내용 |
|---|---|
| 기간 | 2026-03-31 -- 2026-04-25 (Week 5--8) |
| 상태 | 핵심 완료 (75%) |
| 핵심 목표 | EXAONE-Deep-7.8B QLoRA 파인튜닝, AWQ 양자화, HuggingFace 배포 |
개요¶
M2 단계에서는 EXAONE-Deep-7.8B 모델의 QLoRA 파인튜닝과 AWQ 양자화를 성공적으로 완료했다. 모델 크기를 14.56GB에서 4.94GB로 66% 압축하면서 GPU VRAM 4.95GB 수준의 온디바이스 배포 가능성을 검증했다. 백엔드 API(FastAPI)와 프론트엔드 구현은 M3 단계로 이월되었다.
모델 파이프라인¶
LGAI-EXAONE/EXAONE-Deep-7.8B (BF16, ~15GB)
|
v QLoRA 파인튜닝 (r=16, alpha=32, lr=2e-4)
umyunsang/civil-complaint-exaone-lora (~38MB)
|
v merge_and_unload() BF16 병합
umyunsang/civil-complaint-exaone-merged (14.56GB)
|
v AWQ W4A16g128 양자화 (512 캘리브레이션 샘플)
umyunsang/civil-complaint-exaone-awq (4.94GB)
실험 계획 및 결과¶
QLoRA 파인튜닝 설정¶
| 항목 | 값 |
|---|---|
| LoRA Rank (r) | 16 |
| LoRA Alpha | 32 |
| Target Modules | q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj |
| Learning Rate | 2e-4 |
| Batch Size | 2 (Gradient Accumulation 8 = Effective 16) |
| Max Seq Length | 2,048 |
| Epochs | 1 |
| Optimizer | paged_adamw_8bit |
| Scheduler | cosine |
| 실행 환경 | Google Colab A100 (80GB VRAM) |
데이터 포맷 (EXAONE Chat Template)¶
[|system|]
당신은 지자체 민원 담당 공무원을 돕는 AI 어시스턴트입니다.
[|user|]
{instruction}\n\n{input}
[|assistant|]
{output}
EXP-001 Baseline 결과¶
| 체크포인트 | Eval Loss |
|---|---|
| Step 100 | 1.1938 |
| Step 400 | 1.0443 |
| Step 700 (Best) | 1.0179 |
| Step 781 (Final) | Training Loss ~1.01 |
W&B 실험 추적: EXP-001-Baseline-EXAONE-7.8B
미실행 실험
EXP-002 (Rank 변화: r=8, r=32)와 EXP-003 (Learning Rate: lr=1e-4)은 M2에서 미실행되었으며, M3 고도화 이슈 #67에서 수행 예정이다.
KPI 달성 현황¶
| 지표 | 목표 | M2 측정값 | 상태 | 비고 |
|---|---|---|---|---|
| Perplexity | 최저 수렴 | 3.20 | 달성 | 도메인 적응 성공 |
| 분류 정확도 | >= 85% | 2.00% | 미달 | <thought> 태그 파싱 실패 |
| BLEU | >= 30 | 17.32 | 미달 | 참조-생성 스타일 불일치 |
| ROUGE-L | >= 40 | 18.28 | 미달 | 요약형 참조 vs 공식 답변 생성 |
| 추론 속도 (Avg) | < 2s | 9.291s | 미달 | HuggingFace generate() 직접 호출 |
| P95 Latency | < 5s | 3.651s | 달성 | -- |
| GPU VRAM | < 8GB | 4.95GB | 달성 | AWQ 4-bit 양자화 효과 |
| 모델 크기 | < 5GB | 4.94GB | 달성 | 온디바이스 배포 가능 |
모델 크기 압축 성과¶
| 모델 | 크기 | 압축률 |
|---|---|---|
| BF16 병합 모델 | 14.56GB | 기준 |
| AWQ 4-bit 양자화 | 4.94GB | 2.95x 압축 (66.1% 감소) |
기술적 이슈 및 해결¶
1. transformers 5.x 호환성 문제 (Critical)¶
증상: AttributeError: get_interface 오류로 EXAONE 모델 로드 실패
원인: transformers 5.0에서 ALL_ATTENTION_FUNCTIONS.get_interface() 메서드가 제거됨
해결: modeling_exaone.py 내 코드를 수동 패치
# 변경 전
attn_interface = ALL_ATTENTION_FUNCTIONS.get_interface(config.attn_implementation)
# 변경 후
attn_interface = ALL_ATTENTION_FUNCTIONS.get(config.attn_implementation)
교훈: Dynamic Module을 사용하는 모델은 라이브러리 버전 고정이 필수적이다.
2. 분류 정확도 0% 현상¶
증상: 모델이 분류 결과를 출력하지 않고 <thought> 블록만 생성
원인: 기존 단순 매칭 파서가 EXAONE의 추론 과정 출력(<thought> 태그)을 처리하지 못함
해결: 정규표현식으로 <thought> 블록을 분리하고, add_generation_prompt=True 설정 적용
3. 높은 추론 레이턴시¶
증상: 평균 추론 시간 9.29초로 목표(< 2초) 대비 4.6배 초과
원인: max_new_tokens 과도 설정, 모델의 '생각하는 과정'이 불필요하게 긴 출력 생성
해결: 분류 작업 시 max_tokens를 10 토큰 미만으로 제한, repetition_penalty=1.1 적용
BLEU/ROUGE 미달 원인 분석¶
M2에서 BLEU와 ROUGE-L이 목표에 미달한 근본 원인은 참조 답변과 생성 답변의 스타일 불일치이다.
참조 (요약형):
"출[NAME_MASKED] 때 할인[NAME_MASKED] [NAME_MASKED] 요금 2,000원을 내면 돼."
생성 (공식 답변형):
"귀[NAME_MASKED] 응답소(민원상담)를 통해 신청[NAME_MASKED] [NAME_MASKED] 대한
검토 결과를 다음과 같이 알려드립니다..."
모델이 실제로 공식적인 민원 답변 형식을 따르고 있어 실제 답변 품질은 수치보다 우수하지만, 단순 n-gram 기반 지표에서는 낮게 측정된다. M3에서 BERTScore를 도입하여 의미적 유사성을 평가하는 방향으로 전환했다.
HuggingFace 배포 모델¶
| 모델 | 크기 | 링크 |
|---|---|---|
| LoRA Adapter | ~38MB | umyunsang/civil-complaint-exaone-lora |
| Merged BF16 | 14.56GB | umyunsang/civil-complaint-exaone-merged |
| AWQ 4-bit | 4.94GB | umyunsang/civil-complaint-exaone-awq |
관련 GitHub 이력¶
| PR / Issue | 내용 |
|---|---|
| PR #10 | 모델 학습 환경 구축 |
| PR #11 | Fine-tuned EXAONE-Deep LoRA adapter |
| PR #19 | 평가 스크립트 수정 및 AWQ 모델 배포 |
| PR #24 | M2 MVP Final Report & M3 Optimization Complete |
| Issue #17 | MVP: QLoRA 파인튜닝 및 AWQ 최적화 진행 현황 |
| Issue #18 | AWQ 양자화 완료, 평가 스크립트 수정 |
M3 개선 연계¶
M2에서 미달된 지표는 M3 단계의 고도화 이슈로 연결된다.
| M2 미달 지표 | 갭 | M3 대응 이슈 |
|---|---|---|
| 분류 정확도 2% (목표 85%) | -83%p | #52 프롬프트/파서 최적화 |
| BLEU 17.32 (목표 30) | -12.68 | #67 QLoRA HP 최적화, #68 답변 품질 고도화 |
| ROUGE-L 18.28 (목표 40) | -21.72 | #68 답변 품질 고도화, #70 데이터 증강 |
| 추론 속도 9.29s (목표 2s) | -7.29s | #69 vLLM 도입으로 추론 속도 최적화 |