- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 왜 임베딩이 중요한가
- 의미 벡터: 임베딩의 기본 개념
- 대조학습: 임베딩을 학습하는 방법
- 이중 인코더 구조
- 하드 네거티브: 어려운 부정 쌍
- 학습 데이터와 학습 단계
- E5, BGE, GTE 계열 개념
- Matryoshka 표현학습
- MTEB 벤치마크
- 검색과 RAG에서의 적용
- 재랭킹과의 관계
- 벡터 데이터베이스와 근사 최근접 이웃
- 검색 품질 평가 지표
- 자체 데이터 미세조정
- 실무 도입 체크리스트
- 한계와 주의점
- 마무리
- 참고 자료
왜 임베딩이 중요한가
대규모 언어 모델(LLM)이 아무리 뛰어나도, 모델이 학습하지 못한 사내 문서나 최신 정보를 다루려면 외부 지식을 끌어와야 합니다. 이때 "어떤 문서를 끌어올 것인가"를 결정하는 것이 바로 **검색(retrieval)**이고, 현대적 검색의 핵심 도구가 **텍스트 임베딩(text embedding)**입니다.
임베딩이란 단어, 문장, 문단 같은 텍스트를 고정 길이의 실수 벡터로 변환하는 것을 말합니다. 예를 들어 문장 하나를 768차원 벡터로 바꾼다고 하면, 그 문장의 "의미"를 768개의 숫자로 압축해 표현하는 셈입니다. 이 벡터 공간에서는 의미가 비슷한 문장끼리 가까이 모이고, 의미가 다른 문장끼리 멀리 떨어집니다.
이 글에서는 검색과 RAG의 심장이라 할 수 있는 텍스트 임베딩 모델의 원리를 살펴봅니다. 대조학습이라는 학습 방법, 이중 인코더 구조, 하드 네거티브 마이닝, 그리고 E5/BGE/GTE로 대표되는 최신 오픈소스 계열, Matryoshka 표현학습, MTEB 벤치마크, 마지막으로 재랭킹과의 관계까지 다룹니다. AI SOTA는 매우 빠르게 바뀌므로, 특정 순위나 구체 수치보다 개념과 아키텍처 원리에 집중하겠습니다.
의미 벡터: 임베딩의 기본 개념
벡터 공간에서의 의미
전통적인 텍스트 표현 방법인 TF-IDF나 BM25는 단어의 등장 빈도에 기반합니다. 이런 방식은 "강아지"와 "개"처럼 표기가 다르지만 의미가 같은 단어를 연결하지 못합니다. 이를 어휘 불일치(lexical mismatch) 문제라고 부릅니다.
반면 밀집 임베딩(dense embedding)은 의미를 벡터로 표현하기 때문에, 표기가 달라도 의미가 가까우면 벡터도 가까워집니다. 예를 들어 다음과 같은 관계를 벡터 공간에서 포착할 수 있습니다.
"강아지가 공원에서 뛴다" ---- 가까움 ---- "개가 밖에서 논다"
| |
멀어짐 멀어짐
| |
"금리 인상이 주식에 미치는 영향" ------------------
유사도 측정
두 임베딩 벡터가 얼마나 가까운지는 보통 코사인 유사도(cosine similarity)로 측정합니다. 코사인 유사도는 두 벡터 사이 각도의 코사인 값으로, 방향이 같을수록 1에 가깝고 반대일수록 -1에 가깝습니다.
코사인 유사도(a, b) = (a 내적 b) / (norm(a) * norm(b))
- 값 범위: -1 (정반대) ~ 1 (동일 방향)
- 대부분의 임베딩 모델은 정규화된 벡터를 출력하므로
코사인 유사도가 곧 내적(dot product)과 같아집니다.
검색 시스템은 질의(query)를 임베딩한 벡터와, 미리 임베딩해 저장해 둔 문서 벡터들 사이의 유사도를 계산해 가장 가까운 문서를 찾아냅니다. 이를 최근접 이웃 탐색(nearest neighbor search)이라 합니다. 문서 수가 많으면 근사 최근접 이웃(ANN, Approximate Nearest Neighbor) 알고리즘과 벡터 데이터베이스를 사용해 빠르게 검색합니다.
대조학습: 임베딩을 학습하는 방법
대조학습의 직관
좋은 임베딩을 만들려면 "가까워야 할 것은 가깝게, 멀어야 할 것은 멀게" 배치하도록 모델을 학습시켜야 합니다. 이를 위한 대표적 방법이 **대조학습(contrastive learning)**입니다.
대조학습의 기본 단위는 삼각관계입니다. 기준이 되는 앵커(anchor), 앵커와 의미가 통하는 긍정 쌍(positive), 그리고 앵커와 무관한 부정 쌍(negative)입니다.
앵커 (질문)
/ \
당겨서 가깝게 밀어서 멀게
/ \
긍정 (정답 문서) 부정 (무관한 문서)
학습이 진행되면 앵커와 긍정 쌍의 벡터는 서로 끌어당겨 가까워지고, 앵커와 부정 쌍의 벡터는 서로 밀어내 멀어집니다. 이 과정을 수많은 데이터로 반복하면, 의미 구조를 잘 반영하는 벡터 공간이 형성됩니다.
InfoNCE 손실 함수
대조학습에서 가장 널리 쓰이는 손실 함수가 InfoNCE입니다. NCE는 Noise Contrastive Estimation의 약자로, 하나의 긍정 쌍과 여러 부정 쌍 중에서 긍정을 골라내는 분류 문제로 학습을 정의합니다.
InfoNCE 손실 (앵커 q, 긍정 p, 부정 집합 N)
exp(sim(q, p) / T)
L = -log ---------------------------------------
exp(sim(q, p)/T) + Σ exp(sim(q, n)/T)
n in N
- sim: 유사도(보통 내적 또는 코사인)
- T: 온도(temperature) 파라미터. 작을수록 분포가 뾰족해짐
- 분자에 긍정, 분모에 긍정+부정 전체가 들어감
직관적으로 이 손실은 "긍정과의 유사도는 높이고, 부정과의 유사도는 낮춰라"는 신호를 줍니다. 소프트맥스 형태이므로, 긍정이 부정보다 상대적으로 얼마나 높은지가 중요합니다.
인배치 네거티브
부정 쌍을 어떻게 확보할지가 학습 효율을 좌우합니다. 가장 흔한 기법이 인배치 네거티브(in-batch negatives)입니다. 한 배치 안에 여러 개의 (질문, 정답) 쌍이 들어 있을 때, 어떤 질문 입장에서 보면 자기 정답을 제외한 나머지 쌍의 정답들은 모두 부정 쌍이 됩니다.
배치 (질문, 정답) 4쌍이 있을 때
정답1 정답2 정답3 정답4
질문1 [ 긍정 부정 부정 부정 ]
질문2 [ 부정 긍정 부정 부정 ]
질문3 [ 부정 부정 긍정 부정 ]
질문4 [ 부정 부정 부정 긍정 ]
대각선은 긍정, 나머지는 부정으로 한 번에 학습
이 방식은 추가 데이터 없이도 배치 크기에 비례하는 부정 쌍을 공짜로 얻을 수 있어 효율적입니다. 그래서 임베딩 학습에서는 큰 배치 크기가 성능에 유리한 경향이 있다고 알려져 있습니다.
이중 인코더 구조
이중 인코더란
검색용 임베딩 모델은 대부분 이중 인코더(dual encoder, bi-encoder) 구조를 씁니다. 질문과 문서를 각각 독립적으로 인코딩해 벡터로 만든 뒤, 그 두 벡터의 유사도만으로 관련성을 판단합니다.
질문 문서
| |
[인코더 A] [인코더 B]
| |
질문 벡터 문서 벡터
\ /
\-- 유사도 계산 -----/
|
관련성 점수
핵심은 질문과 문서가 서로를 보지 않고 각각 벡터가 된다는 점입니다. 덕분에 문서 벡터를 미리 계산해 저장해 둘 수 있고, 검색 시점에는 질문만 인코딩하면 됩니다. 이 사전 계산 가능성이 대규모 검색을 실용적으로 만드는 결정적 특징입니다.
많은 경우 인코더 A와 B는 가중치를 공유합니다. 즉 하나의 인코더로 질문도 문서도 인코딩합니다. 다만 "이것은 질문이다", "이것은 문서다"를 알려주는 프리픽스(instruction/prefix)를 붙여 역할을 구분하기도 합니다. E5 계열이 "query:"와 "passage:" 접두사를 쓰는 것이 대표적입니다.
크로스 인코더와의 대비
이중 인코더와 자주 비교되는 것이 크로스 인코더(cross-encoder)입니다. 크로스 인코더는 질문과 문서를 하나로 이어붙여 인코더에 함께 넣고, 둘 사이의 상호작용을 어텐션으로 직접 계산합니다.
[질문 + [SEP] + 문서] → [인코더] → 단일 관련성 점수
크로스 인코더는 질문과 문서를 함께 보므로 정확도가 높지만, 문서마다 질문과 짝지어 매번 계산해야 하므로 사전 계산이 불가능하고 느립니다. 그래서 크로스 인코더는 보통 재랭킹 단계에 쓰이고, 1차 검색은 이중 인코더가 담당하는 역할 분담이 일반적입니다. 이 관계는 뒤의 재랭킹 절에서 다시 다룹니다.
하드 네거티브: 어려운 부정 쌍
왜 하드 네거티브가 필요한가
인배치 네거티브로 얻는 부정 쌍은 대부분 질문과 완전히 무관한 문서라 구분이 쉽습니다. 모델이 쉬운 부정 쌍만 반복해서 보면, 겉으로는 비슷해 보이지만 실제로는 정답이 아닌 미묘한 문서를 걸러내는 능력이 잘 늘지 않습니다.
그래서 일부러 "헷갈리는 부정 쌍", 즉 **하드 네거티브(hard negative)**를 만들어 학습에 넣습니다. 하드 네거티브는 질문과 표면적으로는 관련 있어 보이지만 정답은 아닌 문서를 말합니다.
질문: "파이썬에서 리스트를 정렬하는 방법"
쉬운 부정: "고양이 사료 추천" (전혀 무관, 구분 쉬움)
하드 네거티브: "파이썬에서 리스트를 (주제는 같지만
생성하는 방법" 질문의 답은 아님)
하드 네거티브 마이닝
하드 네거티브는 보통 마이닝(mining) 과정을 통해 수집합니다. 대표적으로, 이미 학습된 검색 모델로 질문에 대해 상위 문서들을 뽑은 뒤, 그중 정답이 아닌 상위 문서를 하드 네거티브로 취합니다. 이렇게 수집한 하드 네거티브를 다시 학습에 넣으면 모델이 점점 더 미세한 차이를 구분하게 됩니다.
다만 마이닝한 문서 중에는 라벨이 안 붙었을 뿐 사실은 정답인 경우(false negative)가 섞일 수 있습니다. 이를 잘못 부정으로 학습하면 오히려 성능이 나빠지므로, 상위 몇 개는 제외하거나 별도 필터링을 하는 등 주의가 필요합니다.
학습 데이터와 학습 단계
데이터의 종류
임베딩 모델의 성능은 학습 데이터의 양과 다양성에 크게 좌우됩니다. 자주 쓰이는 데이터의 형태는 다음과 같습니다.
- 질의-문서 쌍: 검색 로그, QA 데이터셋 등에서 얻은 (질문, 관련 문서) 쌍
- 자연어 추론(NLI) 데이터: 함의/모순 관계로 긍정과 부정을 정의
- 문장 쌍 유사도 데이터: 사람이 매긴 유사도 점수가 있는 문장 쌍
- 웹에서 자연적으로 짝지어진 데이터: 제목-본문, 질문-답변, 인용-원문 등
대비 사전학습과 지도 미세조정
많은 최신 오픈소스 임베딩 모델은 두 단계로 학습됩니다.
[1단계: 대규모 약지도 대비 사전학습]
웹에서 자연적으로 짝지어진 방대한 텍스트 쌍으로
대조학습. 라벨 품질은 낮지만 양이 매우 많음.
|
v
[2단계: 고품질 지도 미세조정]
정제된 검색/QA/NLI 데이터셋 + 하드 네거티브로
대조학습. 양은 적지만 품질이 높음.
E5 계열이 이 "약지도 사전학습 후 지도 미세조정" 흐름을 명확히 제시한 대표 사례로 알려져 있습니다. 1단계에서 폭넓은 의미 구조를 익히고, 2단계에서 검색 태스크에 맞게 다듬는 구조입니다.
E5, BGE, GTE 계열 개념
여기서는 대표적인 오픈소스 임베딩 계열의 개념을 살펴봅니다. 구체적인 버전 번호나 벤치마크 순위는 시점과 버전에 따라 자주 바뀌므로, 계열별 아이디어 중심으로 정리합니다.
E5 계열
E5는 "EmbEddings from bidirectional Encoder rEpresentations"에서 따온 이름으로 알려져 있으며, 앞서 설명한 약지도 대비 사전학습과 지도 미세조정의 2단계 학습을 체계적으로 정리한 계열입니다. 질문과 문서에 각각 "query:"와 "passage:" 접두사를 붙여 역할을 구분하는 방식이 특징입니다. 이후 다국어 버전과 대형 모델, 그리고 LLM을 백본으로 삼아 지시문(instruction) 기반으로 임베딩을 만드는 방향으로도 확장되어 왔습니다.
BGE 계열
BGE는 BAAI General Embedding의 약자로, 베이징 지능원(BAAI)에서 공개한 임베딩 계열입니다. 대규모 대비 사전학습과 지도 미세조정을 결합하며, 다양한 언어와 태스크를 폭넓게 지원하는 것으로 알려져 있습니다. 특히 밀집 임베딩뿐 아니라 희소 표현과 다중 벡터 표현을 함께 다루는 방향으로도 확장된 버전이 공개되어, 여러 검색 방식을 하나의 모델에서 결합하려는 시도가 있었습니다.
GTE 계열
GTE는 General Text Embeddings의 약자로, 알리바바 계열에서 공개한 임베딩 모델입니다. 마찬가지로 다단계 대조학습을 사용하며, 여러 도메인의 데이터를 폭넓게 섞어 범용성을 높인 것으로 알려져 있습니다.
계열 비교 요약
| 계열 | 공개 주체(알려진 바) | 특징 개념 | 역할 접두사 |
|---|---|---|---|
| E5 | Microsoft 연구 계열 | 약지도 사전학습 + 지도 미세조정 정립 | query/passage 사용 |
| BGE | BAAI | 다국어, 다중 표현 결합 확장 | 지시문 기반 변형 존재 |
| GTE | Alibaba 계열 | 다도메인 혼합 대조학습 | 지시문 기반 변형 존재 |
위 표의 세부 사항은 시점과 버전에 따라 달라질 수 있으므로, 실제 도입 시에는 각 모델 카드와 공식 문서를 확인하는 것이 좋습니다.
Matryoshka 표현학습
차원 절단의 아이디어
임베딩 차원이 클수록 표현력은 좋아지지만, 저장 비용과 검색 비용도 함께 커집니다. 여기서 등장한 것이 **Matryoshka 표현학습(Matryoshka Representation Learning, MRL)**입니다. 이름은 러시아 인형 마트료시카에서 따왔습니다.
핵심 아이디어는 하나의 큰 임베딩을 학습하되, 앞쪽 일부 차원만 잘라 써도 의미가 유지되도록 학습한다는 것입니다. 즉 768차원 벡터의 앞 256차원만 써도, 앞 128차원만 써도 나름의 좋은 임베딩이 되도록 만듭니다.
전체 임베딩 (예: 768차원)
[■■■■■■■■■■■■■■■■■■■■■■■■]
└앞 64┘
└── 앞 128 ──┘
└──── 앞 256 ────┘
└──────── 앞 512 ────────┘
└────────── 앞 768 (전체) ──────────┘
앞에서부터 잘라도 각 절단 지점이
독립적으로 쓸 만한 임베딩이 되도록 학습
학습 방법과 장점
MRL은 여러 절단 지점 각각에 대해 대조학습 손실을 계산하고 그 합을 최소화하는 방식으로 학습합니다. 그 결과 하나의 모델로 여러 차원의 임베딩을 동시에 제공할 수 있습니다.
실무에서는 이 성질을 이렇게 활용합니다. 먼저 짧은 차원(예: 앞 128차원)으로 대량 후보를 빠르게 1차 검색하고, 상위 후보에 대해서만 전체 차원으로 정밀하게 재계산합니다. 저장 공간과 검색 속도를 아끼면서 정확도 손실은 최소화하는 것입니다. 다만 차원을 너무 심하게 줄이면 정확도가 떨어지므로, 태스크에 맞는 절단 지점을 실험으로 찾아야 합니다.
MTEB 벤치마크
MTEB란
임베딩 모델을 서로 비교하려면 공통의 평가 기준이 필요합니다. 이를 위한 대표적 벤치마크가 **MTEB(Massive Text Embedding Benchmark)**입니다. MTEB는 임베딩이 쓰이는 여러 태스크 유형을 한데 모아 종합적으로 평가합니다.
MTEB가 포함하는 태스크 유형(대표)
- Retrieval : 검색 (질의로 관련 문서 찾기)
- Reranking : 재랭킹
- Clustering : 군집화
- Classification: 분류
- STS : 문장 의미 유사도
- Pair Classification / Summarization 등
여러 태스크에 걸친 점수를 종합하기 때문에, 특정 태스크에만 과적합된 모델이 전체 순위에서 높게 나오기 어렵습니다. 이후 다국어를 폭넓게 포괄하는 방향으로 확장되어 왔습니다.
벤치마크 해석 시 주의점
MTEB 리더보드는 유용하지만, 순위를 절대적으로 받아들이는 것은 위험합니다. 몇 가지 주의점이 있습니다.
- 순위와 점수는 버전, 시점, 평가 설정에 따라 달라집니다. "현재 1위"라는 표현은 곧 옛말이 됩니다.
- 벤치마크 점수와 실제 서비스 데이터에서의 성능이 항상 일치하지는 않습니다. 도메인 특성이 다르면 순위가 뒤집힐 수 있습니다.
- 모델 크기, 임베딩 차원, 추론 속도, 라이선스 같은 실무 제약도 함께 봐야 합니다.
따라서 MTEB는 후보를 좁히는 출발점으로 삼고, 최종 선택은 자신의 데이터로 직접 평가하는 것이 바람직합니다.
검색과 RAG에서의 적용
RAG 파이프라인 속 임베딩
RAG(Retrieval-Augmented Generation)는 검색으로 관련 문서를 찾아 LLM의 입력에 붙여 답변을 생성하는 구조입니다. 임베딩은 이 중 검색 단계의 핵심입니다.
[문서 색인 준비 단계 (오프라인)]
문서 → 청킹 → 임베딩 → 벡터 DB 저장
[질의 처리 단계 (온라인)]
사용자 질문 → 질문 임베딩
→ 벡터 DB에서 유사 문서 검색(top-k)
→ (선택) 재랭킹
→ 문서 + 질문을 LLM에 전달
→ 답변 생성
청킹과 임베딩
긴 문서를 통째로 임베딩하면 의미가 뭉개지므로, 보통 적당한 크기의 청크(chunk)로 나눠 각각 임베딩합니다. 청크 크기와 겹침(overlap)을 어떻게 정하느냐가 검색 품질에 크게 영향을 줍니다. 너무 크면 관련 없는 내용까지 섞이고, 너무 작으면 문맥이 잘려 의미가 약해집니다.
또한 모델마다 처리할 수 있는 최대 입력 길이가 다르므로, 이를 초과하지 않도록 청킹해야 합니다. 최근에는 긴 문맥을 지원하는 임베딩 모델도 늘어나고 있지만, 입력이 길수록 의미가 희석될 수 있다는 점은 여전히 고려해야 합니다.
하이브리드 검색
밀집 임베딩만으로는 정확한 키워드 일치(고유명사, 코드, 숫자 등)에서 약할 수 있습니다. 그래서 밀집 검색과 BM25 같은 희소 검색을 함께 쓰는 하이브리드 검색이 자주 활용됩니다. 두 방식의 점수를 결합하면 의미 검색과 정확 일치의 장점을 모두 취할 수 있습니다.
[밀집 검색] 의미 유사도로 후보 A
[희소 검색] 키워드 일치로 후보 B
\ /
점수 결합(예: RRF)
|
최종 후보 목록
여기서 RRF는 Reciprocal Rank Fusion으로, 각 검색 결과의 순위를 역수로 합산해 결합하는 간단하고 강건한 방법입니다.
재랭킹과의 관계
앞서 이중 인코더와 크로스 인코더를 대비했습니다. 실무 검색은 두 단계로 나뉘는 경우가 많습니다.
[1단계: 검색 (이중 인코더)]
벡터 DB에서 top-k 후보를 빠르게 가져옴
(예: 상위 100개)
|
v
[2단계: 재랭킹 (크로스 인코더)]
100개 후보만 정밀하게 다시 채점해 순위 재조정
상위 몇 개만 LLM에 전달 (예: 상위 5개)
1단계는 속도가 중요하므로 사전 계산이 가능한 이중 인코더가 맡고, 2단계는 정확도가 중요하므로 질문과 문서를 함께 보는 크로스 인코더가 맡습니다. 이렇게 하면 전체 문서를 크로스 인코더로 채점하는 비용을 피하면서도, 최종 결과의 정확도를 끌어올릴 수 있습니다. 임베딩 검색과 재랭킹은 경쟁 관계가 아니라 상호 보완 관계입니다.
벡터 데이터베이스와 근사 최근접 이웃
왜 근사가 필요한가
문서가 수백만, 수천만 개가 되면 질의 벡터와 모든 문서 벡터의 유사도를 일일이 계산하는 것은 너무 느립니다. 그래서 실무에서는 근사 최근접 이웃(ANN, Approximate Nearest Neighbor) 알고리즘을 씁니다. 약간의 정확도를 양보하는 대신 검색 속도를 수십, 수백 배 끌어올립니다.
[완전 탐색(정확)]
질의 벡터 vs 전체 문서 벡터 하나하나 비교
→ 정확하지만 문서 수에 비례해 느림
[근사 최근접 이웃(ANN)]
벡터를 미리 인덱스 구조로 정리해 두고
가까운 영역만 골라 탐색
→ 약간의 누락 가능성, 훨씬 빠름
대표적 인덱스 방식
ANN 인덱스에는 여러 방식이 있습니다. 그래프 기반 방식인 HNSW(Hierarchical Navigable Small World)는 벡터들을 다층 그래프로 연결해, 가까운 이웃을 따라가며 빠르게 탐색합니다. 또 다른 방식으로는 벡터를 여러 조각으로 나눠 압축하는 곱 양자화(PQ, Product Quantization)가 있어 메모리를 크게 절약합니다. 실무의 벡터 데이터베이스는 이런 인덱스를 내부에 두고, 필터 조건(예: 특정 문서 유형만)과 함께 검색을 지원합니다.
인덱스에는 재현율(recall)과 속도, 메모리의 트레이드오프가 있습니다. 파라미터를 조정해 "얼마나 빠르게, 얼마나 정확하게"를 균형 있게 맞추는 것이 실무 튜닝의 핵심입니다.
검색 품질 평가 지표
임베딩과 검색 품질을 정량적으로 평가하려면 지표가 필요합니다. 대표적인 것들을 정리합니다.
[대표 검색 평가 지표]
- Recall@k : 상위 k개 안에 정답이 포함된 비율
- MRR : 정답이 처음 등장한 순위의 역수 평균
- nDCG@k : 순위 위치에 가중치를 둔 누적 이득
- MAP : 여러 정답에 대한 평균 정밀도의 평균
여기서 Recall@k는 "정답을 놓치지 않았는가"를, MRR과 nDCG는 "정답을 얼마나 위쪽에 배치했는가"를 봅니다. RAG처럼 상위 소수만 LLM에 넘기는 상황에서는 상위권 순위 품질(nDCG, MRR)이 특히 중요합니다. 자신의 데이터로 이런 지표를 측정해 모델과 파라미터를 고르는 것이 리더보드보다 훨씬 신뢰할 만합니다.
자체 데이터 미세조정
범용 임베딩 모델이 자신의 도메인에서 부족하다면, 자체 데이터로 미세조정하는 것을 고려할 수 있습니다. 흔한 절차는 다음과 같습니다.
[자체 미세조정 흐름]
1. (질문, 정답 문서) 쌍 수집 (검색 로그, 수작업 라벨 등)
2. 하드 네거티브 마이닝 (기존 모델로 상위 오답 수집)
3. InfoNCE 등 대조학습으로 미세조정
4. 자체 평가셋으로 Recall@k, nDCG 측정
5. 개선되면 배포, 아니면 데이터/설정 재조정
미세조정은 도메인 성능을 크게 높일 수 있지만, 데이터가 적으면 과적합 위험이 있고, 모델을 바꾸면 색인을 다시 만들어야 하는 비용도 있습니다. 그래서 먼저 프리픽스 조정, 하이브리드 검색, 재랭킹 같은 저비용 개선을 시도하고, 그래도 부족할 때 미세조정으로 넘어가는 순서가 합리적입니다.
실무 도입 체크리스트
임베딩 모델을 실제 서비스에 도입할 때 고려할 점을 정리합니다.
- 언어: 서비스 대상 언어를 잘 지원하는 다국어 모델인지 확인합니다.
- 도메인: 자신의 데이터로 직접 평가합니다. 리더보드 순위만 믿지 않습니다.
- 차원과 비용: 임베딩 차원이 저장/검색 비용에 직결됩니다. MRL 지원 모델이면 차원을 조절해 비용을 절감할 수 있습니다.
- 접두사/지시문: 모델이 요구하는 접두사나 지시문 형식을 반드시 지킵니다. 이를 빠뜨리면 성능이 크게 떨어질 수 있습니다.
- 정규화: 코사인 유사도를 쓰려면 벡터 정규화가 필요한지 확인합니다.
- 재랭킹: 정확도가 중요하면 크로스 인코더 재랭커를 추가하는 것을 고려합니다.
- 라이선스: 상업적 사용 가능 여부와 라이선스를 확인합니다.
한계와 주의점
임베딩 기반 검색에도 분명한 한계가 있습니다.
- 도메인 이동: 학습 데이터와 성격이 다른 도메인에서는 성능이 떨어질 수 있습니다. 전문 용어가 많은 분야일수록 자체 평가가 중요합니다.
- 정확 일치 약점: 밀집 임베딩은 고유명사, 코드, 숫자 같은 정확 일치에 약할 수 있어 하이브리드 검색이 필요할 때가 많습니다.
- 청킹 민감도: 청크 크기와 경계 설정에 따라 결과가 크게 달라집니다.
- 최신성: 벤치마크 순위와 최신 모델 정보는 매우 빠르게 바뀝니다. 이 글의 계열 설명도 개념 이해를 위한 것이며, 구체 스펙은 공식 문서로 확인해야 합니다.
- 편향: 학습 데이터의 편향이 임베딩에 반영될 수 있어, 민감한 응용에서는 검증이 필요합니다.
마무리
텍스트 임베딩은 검색과 RAG의 심장입니다. 대조학습과 InfoNCE라는 학습 원리, 이중 인코더라는 구조, 하드 네거티브라는 학습 기법, 그리고 Matryoshka 표현학습과 하이브리드 검색, 재랭킹까지 — 이 요소들이 맞물려 현대적 의미 검색을 이룹니다.
기억할 핵심은 다음과 같습니다. 첫째, 임베딩은 의미를 벡터로 압축한 것이고, 대조학습으로 "가까울 것은 가깝게" 배치하도록 학습됩니다. 둘째, 검색은 이중 인코더로 빠르게, 재랭킹은 크로스 인코더로 정밀하게 하는 2단계 구조가 실용적입니다. 셋째, 모델 선택은 리더보드가 아니라 자신의 데이터로 결정해야 합니다. AI 분야의 SOTA는 빠르게 바뀌지만, 이런 원리는 오래 유효합니다.
참고 자료
- InfoNCE / Contrastive Predictive Coding (arXiv 1807.03748): arxiv.org/abs/1807.03748
- Dense Passage Retrieval (arXiv 2004.04906): arxiv.org/abs/2004.04906
- Sentence-BERT (arXiv 1908.10084): arxiv.org/abs/1908.10084
- Text Embeddings by Weakly-Supervised Contrastive Pre-training, E5 (arXiv 2212.03533): arxiv.org/abs/2212.03533
- Matryoshka Representation Learning (arXiv 2205.13147): arxiv.org/abs/2205.13147
- MTEB: Massive Text Embedding Benchmark (arXiv 2210.07316): arxiv.org/abs/2210.07316
- MTEB 리더보드 (Hugging Face): huggingface.co/spaces/mteb/leaderboard
- BGE (FlagEmbedding) 저장소: github.com/FlagOpen/FlagEmbedding
- Sentence Transformers 문서: sbert.net