반갑습니다.
지난 4월부터 5월 말까지 소규모 프로젝트를 진행함에 있어 생각보다 시간이 많이 가게 되어서 그동안 공부했던 내용들을 제대로 정리하지 못했었습니다.
그렇게 프로젝트가 마무리가 되면서 여태 했던 내용들을 정리하려고 합니다.
모델 선정

우리는 한국어 지원과 이미지 인식 기능을 모두 갖춘 모델을 중점적으로 탐색하였으며, 그중에서도 빠른 서비스 제공이 가능한 모델을 우선 고려하여 최적의 모델을 선정하였습니다.
https://huggingface.co/Bllossom/llama-3.2-Korean-Bllossom-AICA-5B
Bllossom/llama-3.2-Korean-Bllossom-AICA-5B · Hugging Face
Update! [2024.12.12] 추가설명: KMMLU, KoBEST, LogicKor 등 벤치 관련 학습/테스트/유사 데이터를 전혀 사용하지 않았습니다. 벤치데이터 증강해가 쓰까서 학습하면 SOTA 성능 근접하게 나옵니다 모델위에
huggingface.co
선정이유
- PT에 나온 것 처럼 이미지, 텍스트 동시처리 가능
- Unsloth와 호환 가능하여 빠른 시간안에 파인튜닝 가능
- 나름 검증된 성능 -> LogicKor 벤치마크 7.38점이라는 준수한 성능 점수
훈련 방식 & 인퍼런스 방법

상세 내용
Unsloth를 활용한 훈련
- 기존 대비 약 83%의 훈련 시간 단축 효과를 얻었습니다. A100 환경 기준으로 파인튜닝 시간이 약 3시간 → 30분으로 대폭 줄어들었습니다.
RunPod Serverless
- RunPod Serverless 기반 인퍼런스는 레이턴시 문제를 효과적으로 해소할 수 있었으며, 서버리스 환경의 특성과도 잘 맞는 구조였습니다.
- 본 프로젝트에서는 대화형 응답이 아닌, 순차적인 이미지 인식 → 추천 결과 생성 방식으로 진행하였습니다.
서버리스?
서버리스 구조는 초기 호출 시 콜드 스타트 현상으로 인해 대화형 상호작용에는 부적합한 경우가 많습니다.
이를 방지하기 위한 방법으로는 다음과 같은 방안이 존재합니다:
- 예: 5분 간격으로 주기적 호출을 발생시켜 인스턴스를 유지 → 하지만 GPU 서버리스는 비용 부담이 크기 때문에 비효율적입니다.
이에 따라 본 프로젝트에서는 다음과 같은 방식을 채택했습니다:
- 대화형 방식 대신 요청 → 결과 반환 형태로 단순화 → 서버리스 환경에서도 안정적이며 효율적으로 대응 가능
파인튜닝

데이터 필터링 기준과 코디 조합 설계
훈련에 적합한 데이터셋을 만들기 위해 우리는 정제된 패션 상품 데이터셋을 구성하고 이를 기반으로 계절별 코디 추천 조합을 설계하였습니다.
상기 표를 기반으로 계절에 맞는 컬러들을 조합해서 실제 유저에게 적절한 상품을 추천할 수 있도록 유도하는 작업을 실시하였구요.

실제 출력을 위한 프롬프트는 하기 내용대로 작성했습니다.
prompt = f"""
당신은 패션 추천 전문가입니다. 아래 이미지를 보고 판단하여 적절한 코디를 JSON 형식으로 추천해주세요.
이미지를 참고하여 다음 형식에 맞춰 출력해주세요:
{{
"answer": "...",
"recommend": {{
"상의": [...],
"아우터": [...],
"하의": [...],
"신발": [...]
}}
}}
"""
총 38,000개의 데이터 셋을 매핑하여 훈련하였고, 계절별 데이터는 각각 20~30%의 분포로 고르게 선별하였습니다
계속 되는 Format 불안정성
그럼에도 불구하고, 이미지를 입력시켰을 때 프롬프트로 명시한 Format이 제대로 나오지 않는 경우가 생기곤 했습니다.
{
"Recommend" :
{
"상의" : ["이 상품은 여름에 어울리는 상품으로..."],
"하의" : ["데님팬츠 .."],
"아우터 : [...]
}
}
카테고리에 갑자기 answer가 나오는 대참사가 벌어지기도 했습니다;;
그렇기에 답변의 정확도를 높이기 위해 증강방법을 찾던 중, Openai Team의 CLIP을 통한 RAG 시스템을 활용하여 답변의 품질을 높인 사례를 발견하였습니다.
https://cookbook.openai.com/examples/custom_image_embedding_search
CLIP embeddings to improve multimodal RAG with GPT-4 Vision | OpenAI Cookbook
Open-source examples and guides for building with the OpenAI API. Browse a collection of snippets, advanced techniques and walkthroughs. Share your own examples and guides.
cookbook.openai.com
유사도 기반을 통한 이미지 매칭

다만 아쉬운건 CLIP은 저번에 정리했던 내용대로 Text to Image 조합이기 때문에 사실상 서비스 제공과는 조금 멀지 않았나 싶었지만 테스트 결과 기존 56%의 정확도에서 약 80% 가량 상승하였습니다.
https://cheorish.tistory.com/25
[딥러닝, 논문리뷰] CLIP -Learning Transferable Visual Models From Natural Language Supervision - 이론 1편
https://arxiv.org/abs/2103.00020 Learning Transferable Visual Models From Natural Language SupervisionState-of-the-art computer vision systems are trained to predict a fixed set of predetermined object categories. This restricted form of supervision limit
cheorish.tistory.com
그렇게 최종적으로 하기 아키텍처대로 진행하게 되었습니다.

왜 PGVector인가?
관계형 데이터베이스와 통합형 활용
- 벡터 데이터 뿐만 아니라, 상품의 메타데이터 또한 같이 저장 되기 때문에 정확도 확인을 위해 로깅을 활용할 때 있어 유용함
- 별도로 벡터 DB에 활용할 필요도 없으며, PostgreSQL과도 같이 사용할 수 있기 때문....(이지만, 결국 팀원들은 MySQL이 편하다고 해서 그냥 2개 같이 썼습니다...)
- 기존 벡터 DB들은 대부분 로컬에서 저장하는 경향들이 크다보니 클라우드 환경에서 확장성에 한계가 있을 것 같아 RDBMS와 연동하기 쉬운 PGVector를 사용하였습니다.
끝나지 않는 문제

CLIP을 통한 RAG 시스템을 도입하여도 총 3개의 조합을 추천해야 하는 시스템 구조에서는 여전히 불완전한 출력 문제가 발생했습니다.
유사도 기반으로 보강된 데이터를 삽입하여 선제적으로 안정성을 확보하려는 시도를 했지만,
그럼에도 불구하고 실제 서비스에 투입하기에는 조합 수 부족 또는 불완전한 코디가 출력되는 문제가 반복적으로 나타났습니다.
Post-Filtering 단계 도입
이에 따라 저희 팀은 후처리(Post-Filtering) 단계를 도입하여 다음과 같은 절차로 문제를 해결하고자 하였습니다:
주요 도입 목표
- 추천 결과가 항상 총 3개의 코디 조합(상의, 하의, 신발)으로 구성되도록 보장
- 누락된 아이템이 존재하는 경우, 보완 가능한 후보군을 데이터베이스 내에 있는 아이템으로 재추출
- 모든 추천 결과가 일관된 JSON 포맷을 유지하며 서비스에 투입 가능하도록 검증
- RAG 기반 1차 추천 결과 수신
- CLIP 유사도 기반으로 추출된 상의/하의/신발 후보군 수신
- 조합 누락 여부 검증
- 조합 수가 3개 미만인 경우 → 불완전 조합으로 판단
- 결측 보완 로직 실행
- 누락된 카테고리에 대해 보완 가능한 후보군을 통해 재추출
- 혹은 해당 계절/스타일에 맞는 디폴트 아이템군 삽입
- 최종 JSON 포맷 재정렬 및 검증
- 완성된 조합을 기준으로 JSON 형태로 재구성
- 구조/필수값 누락 여부 자동 검증
이처럼 Post-Filtering을 통해 출력 안정성을 보완함으로써,
유저가 어떤 이미지를 입력하더라도 항상 완성도 높은 코디 세트가 제공되도록 시스템을 설계하였습니다.
그렇게 하여 서비스 제공에 문제가 되지 않도록 조치하였습니다.
모델 인퍼런스 추적 & 모델 성능 평가
결과 값 잘 내뱉고 있는지?


모델이 어떤 Output과 Input 값이 제대로 들어가고 있는지 확인하기 위하여 MLflow를 사용하며 내용들을 추적하였습니다.
모델의 Output의 정량적 평가

저희팀은 모델을 평가하는데 있어 MLflow와 HuggingFace API에서 제공해주는 Evaluate 함수를 이용하여 모델의 정량적 평가를 진행하였습니다. 그렇지만 일반 VQA 기반 평가 지표이다보니 질문-응답 정합성을 평가하는 데에는 유용하지만, 패션 코디 추천이라는 도메인 특화 생성 태스크에는 여러 문제점이 발생
왜 커스텀 평가지표를 만들었는지?
- 도메인 적합성 부족 : 이 부분이 가장 컸습니다. 실제로 모델 자체는 질의-응답의 순서가 아닌 실질적으로 이미지를 인식해서 위 상품이 어느 계절에 맞는지, 카테고리 추천을 제대로 하는지에 대한 여부가 가장 중요하기 때문에 커스텀하게 되었습니다.
평가 기준
- 카테고리 : 메인 카테고리와, 서브 카테고리를 제대로 명시하여 format안에 존재하게끔 하는지?
- 계절 여부 : 답변에서 계절 여부를 정확히 내뱉었는지에 대한 여부
모니터링과 자동화
요새 핫한 Claude.ai의 MCP를 활용해서 기존 우리 서버에서 로그를 저장하고 있던 ELK 스택과 연동하여 자연어를 통해 로그를 관리하고 그에 맞는 분석을 자동으로 실시할 수 있게 하였습니다.

여기서 가장 유효했던 점은
1. 자연어를 기반으로 유지보수를 조금 더 편하게 할 수 있다는 점
2. 어느 부분에서 문제가 생겼는지를 조금 더 직관적이게 알 수 있다는 점이었습니다.
마무리하며....
이번 멀티모달 패션 추천 시스템을 기획하고 설계하면서, 여러 기술적 선택을 신중하게 고민하고 최적의 조합을 찾기 위해 노력했습니다. 하지만 프로젝트를 마무리하며 돌아보았을 때, 한 가지 아쉬움이 남는 부분이 있었습니다.
바로, RAG(Retrieval-Augmented Generation) 시스템을 설계할 때,
CLIP 외에도 DINO-ViT라는 또 다른 강력한 이미지 모델이 존재했다는 사실을 초기에는 알지 못했다는 점입니다.
CLIP은 “이미지 ↔ 텍스트” 임베딩에 특화된 모델로,
이미지와 문장 간의 의미적 유사도를 측정하는 데 매우 적합합니다. 실제로 저희는 이를 기반으로 패션 코디 추천 후보를 추출했습니다.
하지만 이후 찾아본 DINO-ViT (Self-Distillation with No Labels, Vision Transformer)는 Image-to-Image 유사도에 훨씬 더 최적화된 구조를 가지고 있었고, 다음과 같은 장점이 있었습니다:
- 텍스트가 없어도 이미지 간의 의미 유사도 파악이 가능 → CLIP은 텍스트-이미지 쌍이 학습 기반이라 “텍스트 없는 순수 이미지 비교”에는 상대적으로 제한적
- 객체 중심의 시각적 특징을 더 잘 보존 → 의류처럼 시각적 디테일이 중요한 도메인에서 더 정교한 매칭 가능
- 보다 세밀한 이미지 검색에 용이 → 상의, 하의, 신발처럼 구체적인 아이템 레벨 유사도 비교에 효과적
만약 DINO-ViT를 썼더라면?
- Image-to-Image 기반의 유사도 검색으로 더욱 정확한 후보 아이템 매칭이 가능했을 것
- 텍스트 없이도 이미지 간의 비주얼 피처 중심 비교가 가능하여,
- 다양한 스타일/계절 조합 생성의 품질도 한층 더 올라갔을 것
다음 프로젝트에서는 이 교훈을 기반으로,
정확도와 유연성을 동시에 고려한 모델 설계를 할 수 있도록 하겠습니다.
감사합니다.
위 프로젝트는 상업적 용도가 아닌 일반 교육용으로 진행하였음을 알려드립니다.
'멀티모달_프로젝트' 카테고리의 다른 글
| [멀티모달 기초논문] VIT - An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale (2) | 2025.03.13 |
|---|