본문으로 건너뛰기

© 2026 Molayo

HN분석2026. 06. 22. 15:53

질문 분류를 위한 로컬 LLM 미세 조정(Fine-tuning)의 좋은 결과

요약

가계 질문 답변 챗봇의 RAG 성능 향상을 위해 초소형 로컬 LLM을 질문 분류기로 미세 조정하는 실험을 다룹니다. Qwen 0.6B 모델을 Unsloth 프레임워크로 튜닝하여 메타데이터 기반의 검색 공간 최적화를 시도합니다.

핵심 포인트

  • RAG 성능 향상을 위해 질문을 메타데이터 카테고리로 사전 분류하는 전략 사용
  • Qwen 0.6B와 같은 초소형 모델의 분류기로서의 가능성 검증
  • Unsloth 프레임워크를 활용한 효율적인 로컬 LLM 미세 조정
  • 프롬프팅만 사용한 베이스라인 모델 대비 미세 조정의 필요성 확인

질문 분류를 위한 로컬 LLM 미세 조정 (Fine Tuning)

재미있는 개인 프로젝트로서, 저는 유지보수 질문부터 병원 예약에 이르기까지 가계의 일반적인 질문에 답하는 챗봇을 작업해 왔습니다.

기본적인 아이디어는 챗봇이 벡터 데이터베이스 (Vector Database) 쿼리를 통한 RAG (Retrieval-Augmented Generation)를 통해 가계 지식을 얻는 것이지만, 더 나은 결과를 위해 저는 벡터 검색이 메타데이터를 인식하도록 만들었습니다.

기본적으로, 저는 질문을 전처리 단계에 통과시켜 알려진 메타데이터 카테고리(예: 수영장(pool), 자동차(car), HVAC, 요리(cooking))로 분류합니다. 이 작업의 주요 목표는 벡터 랭킹 (Vector Ranking)을 위한 검색 공간을 질문의 카테고리와 일치하는 인덱싱된 항목으로만 좁히는 것입니다. 예를 들어, "우리 수영장 펌프를 언제 교체했지?"라는 질문은 인덱스 데이터베이스를 쿼리하기 전에 "pool"이라는 카테고리로 매핑됩니다.

이 실험에서 제가 테스트하고 싶은 가설은, 가계 관련 질문 데이터셋으로 학습했을 때 매우 작은 로컬 LLM (Large Language Model)이 신뢰할 수 있는 질문 분류를 수행하도록 미세 조정 (Fine-tuning)될 수 있는지 여부입니다.

LLMs

이 프로젝트에서 저는 두 가지 다른 로컬 LLM인 Qwen 3:4B와 Qwen 3:0.6B를 사용하고 있습니다. 4B 파라미터 버전은 일반적인 질문 답변에 사용되는 반면, 초소형 0.6B 버전은 질문을 분류하는 데 사용됩니다. 이 실험의 전체 전제는 단 600M 파라미터만을 가진 아주 작은 LLM이 가계 질문의 신뢰할 수 있는 분류기(Classifier)로 미세 조정될 수 있는지 확인하는 것입니다.

미세 조정 (Finetuning)

미세 조정을 위해 저는 Qwen 및 Llama와 같은 로컬 모델을 튜닝하는 데 적합해 보이는 Unsloth라는 인기 있는 오픈 소스 프레임워크를 사용하고 있습니다.

학습 목적으로 저의 초기 데이터셋은 약 ~850개의 데이터 항목으로 구성되어 있으며, 이를 학습 데이터(Training data), 평가 데이터(Eval data), 테스트 데이터(Test data)로 각각 70/15/15 비율로 분할했습니다. 학습 데이터와 평가 데이터는 학습 중에 사용되는 반면, 테스트 데이터셋은 따로 보관되어 학습 후 테스트를 실행하는 데 사용됩니다. 샘플 데이터는 아래 섹션을 참조하세요:

기본적인 아이디어는 LLM (Large Language Model)에 충분한 양의 가전제품 관련 질문 세트를 학습시켜, 모델이 신뢰할 수 있는 질문 분류기 (Question Classifier)가 되도록 만드는 것입니다.

Baseline (기준점)

미세 조정 (Fine-tuning)을 수행하기 전에, 비교 측정할 기준점 (Baseline)을 설정하는 것이 중요합니다. 이번 실험에서 기준점은 프롬프팅 (Prompting)만으로 기존의 Qwen 0.6B 모델을 "있는 그대로" 사용하는 것입니다. 기준점에 사용된 프롬프트 예시는 아래에서 확인할 수 있습니다:

[IMG:1]

기준점 모델의 정확도:

[IMG:2]

저의 오프라인 평가 (Offline Eval) 방법 중 하나로, 두 번째 데이터셋의 시나리오를 통해 모델을 테스트하기 위해 약 130개의 통합 테스트 (Integration Tests) 세트를 만들었습니다. 기준점 모델의 결과는 좋지 않았습니다. 131개의 테스트 중 모델은 단 13개의 질문만을 정확하게 분류했습니다 (정답률 약 10%). 아래 요약 내용을 참조하세요:

[IMG:3]

실제 실패 사례를 자세히 분석해 보면 몇 가지 공통적인 패턴이 나타납니다:

  • 모델이 주로 가전/기기 (Electric/Appliances)와 같은 광범위한 라벨을 과도하게 사용하며, 다른 대부분의 카테고리 (예: 수영장 (Pool), 요리 (Cooking), 냉난방 공조 (HVAC))를 놓칩니다.
  • 모델이 새로운 카테고리 (예: 아파트 (Apartments))를 임의로 만들어내며, 제공된 허용 카테고리 목록을 준수하지 않습니다.

테스트 보고서의 발췌본을 아래에 제공합니다:

[IMG:4]

Finetuning (미세 조정) – 1차 시도

기준점 실험 결과, Qwen 0.6B와 같은 아주 작은 모델은 프롬프팅만으로는 신뢰할 수 있는 성능을 제공할 수 없다는 것이 명확해졌습니다.

다음 실험으로, 이전과 동일한 프롬프트를 사용하되, 모델이 더 높은 정확도로 분류하는 방법을 배울 수 있도록 모델 미세 조정 (Fine-tuning)을 진행합니다.

관심이 있으실 경우 확인해 보실 수 있도록 여기에 미세 조정 스크립트를 포함했습니다. 개괄적으로 설명하자면, 저는 QLoRA를 미세 조정 전략으로 사용하여 Unsloth를 활용하고 있습니다. 참고할 점은, Unsloth에서 제공하는 기본 미세 조정 파라미터 (Parameters)가 매우 좋은 시작점을 제공한다는 것입니다. 제 경험상, 적어도 시작 단계에서는 Unsloth의 값을 너무 세밀하게 조정하는 것보다 좋은 데이터셋을 만드는 것이 더 중요했습니다.

하지만 피해야 할 흔한 함정 중 하나는 훈련 데이터에 대한 과적합 (overfitting)입니다. 그렇기 때문에 훈련 데이터에 포함되지 않은 데이터로 모델을 테스트하는 것이 중요합니다. 정적인 훈련/테스트 데이터 외에도, 향후 재훈련 시 훈련 데이터를 수정할 수 있도록 사용자 피드백을 제공하는 두 번째 채널을 통합했습니다.

결과:

일련의 통합 테스트 (integration tests)를 실행한 결과, 아래 보고서에서 볼 수 있듯이 예측 정확도가 명확하게 향상된 것을 관찰했습니다:

예측 정확도가 10%에서 79%로 상승했지만, 여전히 잘못된 결과의 명확한 패턴이 일부 보입니다:

  • 모델이 올바른 방향으로 가고 있다는 명확한 신호를 보여주고 있지만, 허용된 목록에서 올바른 카테고리의 파편(fragments)만을 출력하는 패턴이 보입니다. 예를 들어, hvac 대신 ac/air와 같이 출력되는 경우입니다.
  • 모델이 fountain, water heater, pool과 같이 의미론적으로 중복되는 카테고리(water-based confusion) 사이에서 혼란을 겪습니다.
미세 조정 (Finetuning) – 2차 시도

첫 번째 미세 조정 실험을 쉽게 개선할 수 있는 방법은 후처리 (post processing) 단계를 추가하는 것입니다. 이를 통해 예측이 의미론적으로는 맞지만 구문론적으로 틀린 경우(예: ac, air)의 결과를 정규화 (normalize)할 수 있습니다. 또 다른 조정 방법은 더 많은 예시를 제공하고 모델에게 해야 할 일과 하지 말아야 할 일을 알려줌으로써 프롬프트 (prompt) 자체에 더 많은 강화 (reinforcement)를 구축하는 것입니다. 두 아이디어 모두 합리적이라고 생각하지만, 카테고리가 추가될수록 유지보수 비용이 증가하게 됩니다.

대신, 저는 모델에게 카테고리를 매핑 (mapping)하는 방법을 가르치는 방식을 약간 변경하여 미세 조정 접근법을 수정할 수 있는지 확인하고 싶었습니다.

결과적으로, 1차 실험과 비교하여 정확도를 더욱 향상시키기 위해 프롬프트에 미세한 변화를 줄 수 있다는 것을 발견했습니다. 이 조정은 사실 아래 샘플에서 볼 수 있듯이, 카테고리를 의미론적 중복이 없는 두 글자의 불투명한 ID (opaque IDs)로 매핑하는 간단한 프롬프트 변경입니다.

이제, 의미가 잠재적으로 중복될 수 있는 가변적인 카테고리 문자열(예: 수계(water-based) 카테고리) 대신, 고정된 형식의 코드를 출력하도록 모델에 요청합니다.

흥미로운 점은 아래 요약에서 볼 수 있듯이, 이 간단한 변경만으로 성능이 매우 크게 향상되었다는 것입니다:

보시다시피, 예측 정확도(prediction accuracy)가 현재 약 92%에 달하며, 이는 상당히 정확한 수준입니다. 고정되고 중복되지 않는 출력을 요청하는 것이 tiny qwen 모델이 응답을 생성할 때 도움이 되는 것으로 보입니다.

하지만 여전히 몇 가지 오답이 있습니다. 구체적인 실패 사례를 아래에 포함했습니다:

이 시점에서 예측은 일반적으로 신뢰할 수 있으며, 미세 조정된(finetuned) LLM은 제 챗봇에서 사용 가능한 예측기(predictor) 역할을 수행하지만, 여전히 해결해야 할 문제들이 남아 있습니다. 눈에 띄는 문제 중 하나는 온수기(water heater) -> 수영장(pool)으로 분류되는 것인데, 이는 여전히 두 카테고리 사이의 중복되는 "물(watery)" 의미 때문일 가능성이 높습니다. 이를 해결하기 위해, 아마도 학습 데이터(training data)를 다시 검토하고 훨씬 더 미세하게(nuanced) 만들어야 할 것입니다.

샘플 채팅 상호작용은 아래 스크린샷에서 확인할 수 있습니다. 파란색 질문 말풍선 안에 있는 작은 카테고리 태그(예: "pool")에 특히 주의를 기울여 주세요. 이 부분이 tiny qwen 3:0.6B LLM에 의해 자동으로 분류되는 부분입니다.

관심이 있으시다면 확인해 보실 수 있도록 여기에 Github 리포지토리(repo)를 포함했습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 HN AI Posts의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0