- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 들어가며
- Embedding이란 무엇인가?
- 주요 임베딩 모델 완전 비교 (2025 기준)
- MTEB 벤치마크 결과 해석
- 언어별 최고 모델 선택
- 실용적인 선택 가이드
- 차원 축소와 비용 절감: Matryoshka Representation Learning
- 실전 임베딩 파이프라인 구축
- 빠른 결정 요약
들어가며
RAG 시스템을 구축할 때 가장 먼저 결정해야 하는 것 중 하나가 임베딩 모델이다. 잘못 선택하면 검색 품질이 나빠지고, 비용이 10배 이상 차이 날 수 있다. 그런데 놀랍도록 많은 팀이 "OpenAI 쓰면 되겠지"로 결정을 끝낸다.
이 글에서는 2025년 기준 주요 임베딩 모델을 실제 성능, 비용, 다국어 지원, 인프라 요구사항 측면에서 비교하고, 상황별 최고의 선택을 제시한다.
Embedding이란 무엇인가?
임베딩은 텍스트를 의미를 담은 숫자 벡터로 변환하는 기술이다.
from openai import OpenAI
import numpy as np
client = OpenAI()
# 텍스트 → 벡터 변환
text = "인공지능이 세상을 바꾸고 있다"
response = client.embeddings.create(
input=text,
model="text-embedding-3-small"
)
embedding = response.data[0].embedding
print(f"벡터 차원: {len(embedding)}") # 1536
# 의미적 유사도 계산
def cosine_similarity(a: list, b: list) -> float:
a_np = np.array(a)
b_np = np.array(b)
return float(np.dot(a_np, b_np) / (np.linalg.norm(a_np) * np.linalg.norm(b_np)))
# 유사한 문장끼리는 높은 유사도
text1 = "머신러닝은 AI의 한 분야다"
text2 = "딥러닝은 인공지능 기술이다"
text3 = "오늘 날씨가 맑다"
emb1 = client.embeddings.create(input=text1, model="text-embedding-3-small").data[0].embedding
emb2 = client.embeddings.create(input=text2, model="text-embedding-3-small").data[0].embedding
emb3 = client.embeddings.create(input=text3, model="text-embedding-3-small").data[0].embedding
print(f"AI 관련 두 문장 유사도: {cosine_similarity(emb1, emb2):.3f}") # ~0.85
print(f"AI vs 날씨 유사도: {cosine_similarity(emb1, emb3):.3f}") # ~0.30
임베딩 공간에서 비슷한 의미를 가진 텍스트는 가까이, 다른 의미는 멀리 위치한다. RAG 시스템은 이 특성을 활용해 "의미적으로 가장 관련 있는 문서"를 검색한다.
주요 임베딩 모델 완전 비교 (2025 기준)
OpenAI Embeddings
가장 널리 사용되는 상용 임베딩 모델이다.
from openai import OpenAI
client = OpenAI()
# text-embedding-3-small: 빠르고 저렴, 대부분의 경우에 충분
small_emb = client.embeddings.create(
input="your text here",
model="text-embedding-3-small"
).data[0].embedding
# 차원: 1536, 비용: $0.020/1M tokens
# text-embedding-3-large: 최고 품질, 5배 비쌈
large_emb = client.embeddings.create(
input="your text here",
model="text-embedding-3-large"
).data[0].embedding
# 차원: 3072, 비용: $0.130/1M tokens
# 차원 축소 지원 (Matryoshka Representation Learning)
reduced_emb = client.embeddings.create(
input="your text here",
model="text-embedding-3-small",
dimensions=256 # 1536에서 256으로 축소, 저장 비용 6배 절감
).data[0].embedding
장점:
- 신뢰할 수 있는 일관된 성능
- 별도 인프라 불필요, 즉시 사용 가능
- OpenAI 생태계와 완벽한 통합
단점:
- 규모가 커지면 비용 급증
- 데이터가 OpenAI 서버로 전송됨 (프라이버시 우려)
- 한국어/일본어 성능이 전문 다국어 모델 대비 떨어짐
Cohere Embed
다국어 지원이 탁월한 상용 모델이다.
import cohere
co = cohere.Client(api_key="your-key")
# 한국어 포함 100개+ 언어 지원
texts = [
"인공지능이 세상을 바꾸고 있다",
"AI is changing the world",
"AIが世界を変えている"
]
response = co.embed(
texts=texts,
model="embed-multilingual-v3.0",
input_type="search_document" # 문서 인덱싱용
# input_type="search_query" # 쿼리 임베딩용
)
# 쿼리는 다른 input_type 사용 (중요!)
query_response = co.embed(
texts=["AI 발전에 대해 알려줘"],
model="embed-multilingual-v3.0",
input_type="search_query" # 쿼리 전용
)
# 압축 지원: 저장 비용 대폭 절감
compressed_response = co.embed(
texts=texts,
model="embed-multilingual-v3.0",
input_type="search_document",
embedding_types=["float", "int8", "binary"] # 다양한 정밀도
)
# binary: 원본 대비 32배 저장 공간 절감!
장점:
- 한국어/일본어 포함 100개+ 언어에서 최고 수준 성능
- int8/binary 압축으로 저장 비용 4~32배 절감
- search_document/search_query 분리로 검색 품질 향상
단점:
- float32 기준으로는 OpenAI보다 약간 비쌈
- 데이터가 Cohere 서버로 전송됨
오픈소스 모델 (자체 호스팅)
데이터 프라이버시가 중요하거나 규모가 크다면 자체 호스팅이 답이다.
from sentence_transformers import SentenceTransformer
import torch
# BGE-M3: 2025년 최고의 오픈소스 다국어 임베딩 모델
model = SentenceTransformer("BAAI/bge-m3")
texts = ["인공지능이 세상을 바꾸고 있다", "AI is changing the world"]
embeddings = model.encode(texts, normalize_embeddings=True)
print(f"차원: {embeddings.shape}") # (2, 1024)
# E5-mistral-7b: 7B LLM을 인코더로 사용, 최고 품질
# (GPU 메모리 최소 16GB 필요)
e5_model = SentenceTransformer("intfloat/e5-mistral-7b-instruct")
# 사용 시 쿼리에 "Instruct: ... \nQuery: " 접두어 필요
query = "Instruct: 관련 문서를 검색하시오\nQuery: 인공지능 기술 동향"
doc = "최근 AI 기술이 빠르게 발전하고 있다"
query_emb = e5_model.encode(query, normalize_embeddings=True)
doc_emb = e5_model.encode(doc, normalize_embeddings=True)
# nomic-embed-text-v1.5: 균형잡힌 성능/크기
nomic_model = SentenceTransformer("nomic-ai/nomic-embed-text-v1.5", trust_remote_code=True)
# 768차원, 좋은 성능 대비 가벼운 모델
# multilingual-e5-large: 안정적인 다국어 선택
ml_e5 = SentenceTransformer("intfloat/multilingual-e5-large")
# 일본어 포함 다국어에서 강력한 성능
MTEB 벤치마크 결과 해석
MTEB(Massive Text Embedding Benchmark)는 56개의 데이터셋에서 임베딩 모델을 평가하는 표준 벤치마크다. leaderboard.txt에서 확인할 수 있다.
주요 태스크별 해석
MTEB 태스크 유형:
- Retrieval (검색): RAG에서 가장 중요. nDCG@10 지표
- STS (Semantic Textual Similarity): 문장 간 유사도. Spearman 상관계수
- Classification: 텍스트 분류. Accuracy
- Clustering: 군집화. V-measure
- Reranking: 재순위 매기기. MAP
RAG 시스템 구축 시 → Retrieval 점수 최우선
텍스트 분류 시 → Classification 점수 우선
의미 유사도 계산 시 → STS 점수 우선
2025년 주요 모델 MTEB 점수 비교
| 모델 | 평균 | Retrieval | STS | 차원 | 비용 |
|---|---|---|---|---|---|
| text-embedding-3-large | 64.6 | 55.4 | 81.7 | 3072 | $0.13/1M |
| Cohere embed-v3 | 64.5 | 55.0 | 82.1 | 1024 | $0.10/1M |
| E5-mistral-7b | 66.6 | 56.9 | 84.7 | 4096 | 자체 호스팅 |
| BGE-M3 | 63.2 | 54.9 | 79.8 | 1024 | 자체 호스팅 |
| text-embedding-3-small | 62.3 | 53.2 | 80.4 | 1536 | $0.02/1M |
주의: 영어 기반 MTEB 점수다. 한국어/일본어 성능은 별도 평가 필요.
언어별 최고 모델 선택
| 언어 | 1순위 | 2순위 | 비고 |
|---|---|---|---|
| 한국어 | BGE-M3 (OSS) | Cohere multilingual | BGE-M3이 한국어에서 특히 강함 |
| 일본어 | multilingual-e5-large | BGE-M3 | 두 모델 모두 우수 |
| 영어 | E5-mistral-7b | text-embedding-3-large | 오픈소스가 상용 능가 |
| 다국어 혼합 | Cohere multilingual | BGE-M3 | 100개+ 언어 균일 지원 |
| 코드 | text-embedding-3-large | voyage-code-2 | 코드 특화 모델 유리 |
실용적인 선택 가이드
다음 함수로 상황에 맞는 모델을 빠르게 결정할 수 있다:
def choose_embedding_model(
languages: list, # 예: ['ko', 'en'], ['ja', 'en', 'zh']
budget: str, # 'low', 'medium', 'high'
privacy_required: bool, # 데이터를 외부로 보내면 안 되는 경우
scale: str, # 'small'(<100k req/day), 'medium', 'large'(>1M req/day)
use_case: str = 'rag' # 'rag', 'classification', 'similarity'
) -> dict:
"""
상황별 최적 임베딩 모델 추천
Returns:
dict: {'model': str, 'reason': str, 'estimated_monthly_cost': str}
"""
# 프라이버시 또는 대규모 → 자체 호스팅
if privacy_required or scale == 'large':
if 'ko' in languages or 'ja' in languages:
return {
"model": "BAAI/bge-m3",
"reason": "최고의 오픈소스 한국어/일본어 지원 + 프라이버시 보장",
"estimated_monthly_cost": "GPU 서버 비용만 (~$200-500/월)"
}
if use_case == 'rag' and budget == 'high':
return {
"model": "intfloat/e5-mistral-7b-instruct",
"reason": "최고 품질 오픈소스, 영어 Retrieval 최강",
"estimated_monthly_cost": "GPU 서버 비용만 (A100 기준 ~$1000/월)"
}
return {
"model": "nomic-ai/nomic-embed-text-v1.5",
"reason": "가벼우면서 좋은 성능, 자체 호스팅 용이",
"estimated_monthly_cost": "GPU 서버 비용만 (~$100-200/월)"
}
# 다국어 (3개 이상) → Cohere
if len(languages) > 2:
return {
"model": "cohere/embed-multilingual-v3.0",
"reason": "100개+ 언어 균일한 고품질 지원",
"estimated_monthly_cost": "요청량에 따라 $100-1000/월"
}
# 비용 민감 + 영어 위주
if budget == 'low' and 'en' in languages:
return {
"model": "text-embedding-3-small",
"reason": "가장 저렴하고 대부분의 영어 태스크에 충분",
"estimated_monthly_cost": "1M req 기준 ~$20/월"
}
# 기본: 최고 품질 상용
return {
"model": "text-embedding-3-large",
"reason": "최고의 상용 임베딩 품질, 운영 부담 없음",
"estimated_monthly_cost": "1M req 기준 ~$130/월"
}
# 사용 예시
result = choose_embedding_model(
languages=['ko', 'en'],
budget='medium',
privacy_required=True,
scale='medium',
use_case='rag'
)
print(f"추천 모델: {result['model']}")
print(f"이유: {result['reason']}")
차원 축소와 비용 절감: Matryoshka Representation Learning
OpenAI의 text-embedding-3 모델과 일부 오픈소스 모델은 MRL을 지원한다. 전체 차원의 앞부분만 잘라내도 품질이 거의 유지된다.
from openai import OpenAI
import numpy as np
client = OpenAI()
def compare_dimension_tradeoffs(text: str):
"""차원별 성능/비용 트레이드오프 분석"""
dimensions_to_test = [256, 512, 1024, 1536] # 1536이 기본
results = {}
for dim in dimensions_to_test:
response = client.embeddings.create(
input=text,
model="text-embedding-3-small",
dimensions=dim
)
emb = response.data[0].embedding
results[dim] = {
"embedding": emb,
"storage_bytes": len(emb) * 4, # float32 = 4 bytes
"relative_storage": f"{dim/1536:.1%} of full"
}
print(f"차원 {dim}: 저장 {results[dim]['storage_bytes']} bytes "
f"({results[dim]['relative_storage']})")
return results
# 실제 성능 측정 (MTEB Retrieval 점수 기준)
# 모델: text-embedding-3-small
# 1536차원: 53.2 (기준)
# 1024차원: 52.8 (-0.4)
# 512차원: 52.1 (-1.1)
# 256차원: 50.9 (-2.3)
# → 256차원으로 줄여도 품질 4% 미만 감소, 저장 비용 6배 절감!
# pgvector 사용 시 실질적인 저장/검색 비용 비교:
# 문서 100만 건 기준:
# 1536차원: 100만 × 1536 × 4 bytes = 6.14 GB
# 256차원: 100만 × 256 × 4 bytes = 1.02 GB
# → 저장 비용 6배 절감 + 검색 속도 약 3배 향상
실전 임베딩 파이프라인 구축
from sentence_transformers import SentenceTransformer
import numpy as np
from typing import Union
import time
class EmbeddingPipeline:
"""프로덕션 임베딩 파이프라인"""
def __init__(self, model_name: str = "BAAI/bge-m3"):
self.model = SentenceTransformer(model_name)
self.model_name = model_name
def embed_documents(self, texts: list, batch_size: int = 32) -> np.ndarray:
"""문서 배치 임베딩 (인덱싱용)"""
all_embeddings = []
for i in range(0, len(texts), batch_size):
batch = texts[i:i + batch_size]
# BGE 계열은 "passage: " 접두어 사용
if "bge" in self.model_name.lower():
batch = [f"passage: {t}" for t in batch]
embeddings = self.model.encode(
batch,
normalize_embeddings=True,
show_progress_bar=False
)
all_embeddings.append(embeddings)
return np.vstack(all_embeddings)
def embed_query(self, query: str) -> np.ndarray:
"""쿼리 임베딩 (검색용)"""
if "bge" in self.model_name.lower():
query = f"query: {query}" # BGE 계열 쿼리 접두어
return self.model.encode(
query,
normalize_embeddings=True
)
def benchmark(self, texts: list) -> dict:
"""임베딩 속도 벤치마크"""
start = time.time()
embeddings = self.embed_documents(texts)
elapsed = time.time() - start
return {
"total_texts": len(texts),
"total_time_sec": elapsed,
"texts_per_second": len(texts) / elapsed,
"embedding_shape": embeddings.shape
}
# 사용 예시
pipeline = EmbeddingPipeline("BAAI/bge-m3")
# 문서 임베딩
documents = [
"RAG는 검색 증강 생성 기술입니다",
"임베딩은 텍스트를 벡터로 변환합니다",
"벡터 데이터베이스는 유사도 검색에 최적화되어 있습니다"
]
doc_embeddings = pipeline.embed_documents(documents)
# 쿼리 임베딩
query = "텍스트 검색 기술에 대해 알려주세요"
query_embedding = pipeline.embed_query(query)
# 유사도 계산
similarities = np.dot(doc_embeddings, query_embedding)
best_match_idx = np.argmax(similarities)
print(f"가장 관련 있는 문서: {documents[best_match_idx]}")
print(f"유사도 점수: {similarities[best_match_idx]:.3f}")
빠른 결정 요약
당장 시작해야 한다면: text-embedding-3-small (OpenAI) — 가장 쉽고, 대부분의 경우 충분하다.
한국어/일본어가 중요하다면: BGE-M3 (자체 호스팅) 또는 Cohere embed-multilingual-v3.0
비용이 최우선이라면: BGE-M3이나 nomic-embed-text-v1.5를 자체 호스팅 — 규모가 커질수록 압도적으로 유리하다.
최고 품질이 필요하다면: E5-mistral-7b-instruct — 오픈소스 중 최강이지만 GPU 16GB+ 필요.
데이터 프라이버시가 필수라면: 상용 API 전부 제외, 자체 호스팅만 고려.
임베딩 모델 교체는 RAG 시스템 전체를 재인덱싱해야 하므로, 초기에 충분히 검토하는 것이 중요하다.