💻 What?
- 6월 23일 (월): 저번 주에 배웠던 기초 LangGraph의 응용 버전으로 메모리를 활용하는 법을 배웠다. 그리고 sLLM Fine-Tuning에 대한 이론을 배웠다. 강사님께서 Pre-trained Model의 모든 Parameter를 학습시키는 Full Fine-Tuning과 일부만을 학습시켜 비용을 줄이는 PEFT(Parameter-Efficient Fine-Tuning)에 대해 소개해주셨다.
- 6월 24일 (화): Fine-Tuning 이론의 심화 학습과 실습을 진행했다. PEFT 방법 중 하나인 LoRA(Low-Rank Adaptation)에 대해 심층적으로 학습하고, HuggingFace 라이브러리를 활용해 실제로 LoRA Fine-Tuning을 실습했다.
kanana모델에 특정 뉴스 기사와 주가 정보와의 관계를 Fine-Tuning하여, 뉴스 기사를 입력받으면 해당 뉴스 기사로 인한 주가 정보의 변동을 예측하는 모델을 만드는 실습을 진행했다. - 6월 25일 (수): CNN(Convolutional Neural Network)에 대해 학습했다. CNN이 주목받기 시작한 배경부터 Convolution과 Pooling의 개념에 대해 다뤘고, Cloud 환경에서 VGGNet Pre-trained 모델에 품종 데이터를 Fine-Tuning해서 Image Classification 실습을 진행했다.
- 6월 26일 (목): CNN의 심화 수업으로 GAN(Generative Adversarial Network)과 Diffusion Model, Stable Diffusion에 대해 배웠다. GAN의 Generative가 의미하는 바에 대해 구체적으로 배운 뒤 간단한 실습을 거쳤다.
- 6월 27일 (금): 3차 미니 프로젝트가 시작되었다. 주제는 RAG 시스템 구현으로, 팀원들과 함께 RAG 체인 구성, 데이터 크롤링 및 전처리 등을 수행했다.
😮 So What?
Full Fine-Tuning
수업에서 배운 LLM Fine-Tuning을 미니 프로젝트에서 직접 다룰 일이 생겼다. 우리 팀의 주제는 쇼핑몰의 리뷰 데이터를 Document로써 활용하는 쇼핑몰 제품 정보 제공 Chatbot 구현이었다. 데이터 전처리 팀인 나는 우선 기본적인 전처리 업무를 수행했다. 우리가 수집한 데이터는 약 100만 개의 리뷰였다. 각 리뷰에는 제품명, 리뷰 텍스트, 성분 등 여러 특징들이 있기 때문에, 이들을 한 눈에 파악할 수 있게 Table 형식으로 가공했다. 이후 RAG 팀의 데이터 요구 사항을 받아 어떻게 전처리를 하면 좋을지 고민했다. Chatbot이 받을 질문 시나리오들을 구성해봤을 때, 그 중에서 답변의 품질이 낮을 것이라고 판단되는 시나리오가 하나 있었다.
A 제품을 이용한 사람들의 부정적인 경험들을 소개해주세요.
제품 하나에 달린 리뷰가 천 개가 넘는 경우도 상당수 존재했다. 수많은 리뷰들에 대해 하나하나 유사도 비교를 하는 것은 LLM의 답변 속도를 현저히 낮춘다. 이 때 Document의 metadata에 리뷰의 감성(긍정&부정)을 추가해서 metadata filter 기반으로 1차 검색을 수행한 결과물에 대해서만 유사도 비교를 한다면 시간 비용이 절감될 것이다. 이런 생각에 나는 감성 정보를 metadata로 활용할 수 있게끔 전처리 과정에서 감성 분석(Sentiment Analysis)를 진행하여 감성이라는 열을 테이블에 추가하는 작업을 수행했다. 이때 진행한 것이 Full Fine-Tuning이었다.
1. 문장 단위 Tokenizing
리뷰를 한 문장으로 간결하게 적는 사람들이 있는 반면, 특정 제품의 소비 배경, 장점, 단점, 총평 등 몇 단락에 걸쳐 자세히 작성하는 사람들도 있다. 후자의 경우 한 문서에 여러가지 감성이 혼재되어 있기 때문에, 문서를 특정 Label로 분류한 Confidence가 높지 않을 것이다. 때문에 감성 분석 모델에 넣을 문서를 모두 문장 단위로 바꿔주는 작업을 수행했다. 그렇게 약 310만 개의 문장을 만들었다.
import kss
df['문장리스트'] = df['리뷰'].progress_apply(kss.split_sentences)
df = df.explode('문장리스트', ignore_index=True)
df = df.rename(columns={'문장리스트':'문장'}
df = df.drop(columns=['리뷰'])
# 네 문장짜리 리뷰 하나가 있었다고 가정합시다.
# 이제 이 리뷰는 4개의 행으로 분리되었습니다.
2. 표본 추출
감성 분석은 모델을 만드는 과정에는 리뷰만 필요한 게 아니다. 해당 리뷰(X)의 감성 정보(y)가 있어야 둘 사이의 패턴을 모델에 학습시킬 수 있을 것이다. 가진 게 리뷰밖에 없던 우리는 모델에 학습시킬 정답지가 필요했고, 나는 2000 문장의 표본을 추출하여 gpt-4.1에게 넘겨준 뒤 답지를 제공해달라고 요청했다. 제품의 세부 카테고리별로 층화 표본 추출을 진행해서, 각 카테고리 별 데이터포인트의 비율을 유지하려고 노력했다.
class Sentiment(BaseModel):
sentiment: str = Field(description="분석된 감성. '긍정', '부정', '중립' 중 하나의 값이어야 합니다.")
template = """
당신은 한국 화장품 리뷰의 감성을 분석하는 최고의 전문가입니다.
주어진 문장을 분석하여 '긍정', '부정', '중립' 중 하나로 분류해주세요.
# 감성 분류 기준:
- "긍정": 제품에 대한 만족, 칭찬, 추천, 재구매 의사 등 긍정적인 내용.
- "부정": 제품에 대한 불만, 단점, 비판, 부작용 등 부정적인 내용.
- "중립": 객관적인 사실 전달(예: 제형, 색상 설명), 긍/부정이 혼재되어 판단이 어려운 문장. 배송, A/S 등 서비스 품질 및 제품 용기의 품질이나 외관 등, 제품 자체의 성능에 대한 판단이 아닌 문장.
{format_instructions}
# 분석할 문장:
{review_sentences}
"""
model = ChatOpenAI(model='gpt-4.1', temperature=0.1)
3. 미세 조정
이제 2000개의 학습 데이터를 실제로 감성 분류를 수행할 모델에 학습시킬 차례다. 우리는 HuggingFace의 pre-trained 텍스트 분류 모델을 미세 조정하기로 했고, 방법은 Full Fine-Tuning으로 진행했다. 사실 gpt의 성능이 워낙 좋아서 미세 조정 없이 300만 문장 모두 gpt에게 감성 분석 해달라고 요청하면 고품질의 데이터를 얻을 수 있겠지만, gpt API를 300만 회 요청하게 된다면 지갑이 깃털처럼 가벼워지리라.
우리가 선택한 모델은 한국어 임베딩이 가능한 모델 중 하나인 beomi/kcbert-base였고, 해당 모델에 2000개의 리뷰와 감성을 학습시켰다. 결과는 아래와 같다.
- iPad7/kcbert_full_finetuned
- Loss: 1.33
- Accuracy: 0.81
- F1: 0.81
4. 추론
Fine-Tuned 모델로 310만 문장의 감성을 추론했다. 결과는 다음과 같다.
팀원들과 모여 정성 평가를 진행해본 결과 전반적으로 잘 분류하는 느낌이 들었으나 '그냥 아이크림만 바르는거보다 효과도 귯'과 같은 긍정 문장과 '개인적으로 다크서클이 고민인데 조금이라도 나아졌으면 좋겠네요~~'라는 사용 경험이 아닌 기대를 담은 중립 문장들 중 일부를 부정으로 추론하는 아쉬운 결과가 파악되었다.
5. 향후 과제
우선 표본의 크기 때문에 위와 같은 현상이 발생한 것으로 추측된다. 300만 개 중 2000개, 모집단의 0.1%도 되지 않는 데이터로 모수의 특성을 대표하려 한 것이 원인이겠다. 남은 기간을 고려하면 시간 내에 발전시키는 것은 어렵다고 판단되어, 해당 데이터셋을 Vector DB에 올린 뒤 바로 RAG 체인과 결합해야겠다. 또한 Full Fine-Tuning이 아닌 LoRA 방식을 활용하여 미세 조정하는 것도 고려해야겠다. RAG 과제에서의 감성분석, 배보다 배꼽일 수 있겠으나 내가 관심 있었던 분야를 실제 사례에 적용할 수 있는 정말 유익한 기회였다.

향후 과제:
- 표본 수를 늘린 뒤 기존 접근법 그대로 미세 조정
- LoRA 접근법으로 미세 조정
🎈 Now What?
일단 이제 RAG 팀에 붙어 프로젝트 마무리를 도와야겠다. 수업 시간에 배운 것들에 대한 기억을 되살려 팀에 많은 기여가 되도록 노력하자.
지금 벌려 놓은 일들이 굉장히 많다. 이에 대해 다음 주 회고에서 자세히 적어보려 한다. 프로젝트가 끝나면 슬슬 일들을 하나씩 처리하고, 이를 열심히 기록해야겠다. 남은 3개월 수험생처럼 살아보자. 나는 할 수 있다🔥🔥🔥
'SKN_13th' 카테고리의 다른 글
| [플레이데이터 SK네트웍스 Family AI 캠프 13기] 13주차 회고 (2) | 2025.06.22 |
|---|---|
| [플레이데이터 SK네트웍스 Family AI 캠프 13기] 12주차 회고 (6) | 2025.06.14 |
| [플레이데이터 SK네트웍스 Family AI 캠프 13기] 11주차 회고 (7) | 2025.06.08 |
| [플레이데이터 SK네트웍스 Family AI 캠프 13기] 월간 회고: 5월 (0) | 2025.05.31 |
| [플레이데이터 SK네트웍스 Family AI 캠프 13기] 9주차 회고 (0) | 2025.05.25 |