Embedding Model
텍스트를 벡터로 변환하는 모델
텍스트를 벡터로 변환하는 모델
Embedding Model은 텍스트, 이미지, 오디오 등 비정형 데이터를 고정 길이의 수치 벡터(임베딩)로 변환하는 AI 모델입니다. 이 벡터는 원본 데이터의 의미적 특성을 수학적으로 인코딩하여, 컴퓨터가 유사도 계산, 검색, 분류 등을 수행할 수 있게 합니다.
초기에는 Word2Vec, GloVe 같은 정적 임베딩이 주류였지만, 2018년 BERT 등장 이후 Transformer 기반 모델이 대세가 되었습니다. 현재는 OpenAI text-embedding-3, Cohere Embed v3, Google Gecko 등 상용 API와 BGE, E5, GTE 같은 오픈소스 모델이 경쟁하고 있습니다.
임베딩 모델은 텍스트를 입력받아 보통 256~3072차원의 실수 벡터를 출력합니다. 의미가 비슷한 텍스트는 벡터 공간에서 가깝게, 다른 텍스트는 멀리 위치합니다. 이 특성 덕분에 코사인 유사도나 유클리드 거리로 의미적 유사성을 수치화할 수 있습니다.
실무에서 Embedding Model은 RAG(검색 증강 생성), 시맨틱 검색, 추천 시스템, 중복 탐지, 클러스터링의 핵심 컴포넌트입니다. Vector Database(Pinecone, Weaviate, Milvus)와 결합하여 수억 건의 문서에서 밀리초 내에 관련 정보를 찾아냅니다.
# Embedding Model 활용 예제
from openai import OpenAI
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
client = OpenAI()
# 1. OpenAI text-embedding-3-small 사용 ($0.02/1M tokens)
def get_embedding(text: str, model="text-embedding-3-small"):
response = client.embeddings.create(input=text, model=model)
return response.data[0].embedding
# 임베딩 생성
texts = [
"Python은 데이터 분석에 많이 사용됩니다",
"파이썬은 머신러닝 분야에서 인기가 높습니다",
"자바스크립트는 웹 개발에 필수입니다",
"오늘 날씨가 좋네요"
]
embeddings = [get_embedding(t) for t in texts]
# 2. 유사도 계산
similarity_matrix = cosine_similarity(embeddings)
print("텍스트 유사도 행렬:")
print(np.round(similarity_matrix, 2))
# Python-파이썬: 0.92 (높음), Python-날씨: 0.31 (낮음)
# 3. 시맨틱 검색 구현
query = "데이터 사이언스 프로그래밍 언어"
query_emb = get_embedding(query)
scores = cosine_similarity([query_emb], embeddings)[0]
ranked_results = sorted(zip(texts, scores), key=lambda x: x[1], reverse=True)
print("\n검색 결과:")
for text, score in ranked_results:
print(f" {score:.3f}: {text}")
# 4. 오픈소스 모델 (sentence-transformers)
from sentence_transformers import SentenceTransformer
# BGE 모델 - 한국어 지원, 무료
model = SentenceTransformer('BAAI/bge-m3') # 다국어 지원
embeddings = model.encode(texts)
print(f"\n임베딩 차원: {embeddings.shape}") # (4, 1024)
# 5. 배치 처리 + Vector DB 저장 (Chroma 예시)
import chromadb
from chromadb.utils import embedding_functions
chroma_client = chromadb.Client()
openai_ef = embedding_functions.OpenAIEmbeddingFunction(
model_name="text-embedding-3-small"
)
collection = chroma_client.create_collection(
name="documents",
embedding_function=openai_ef
)
# 문서 추가 (임베딩 자동 생성)
collection.add(
documents=texts,
ids=[f"doc_{i}" for i in range(len(texts))]
)
# 유사 문서 검색
results = collection.query(
query_texts=["AI 프로그래밍"],
n_results=2
)
print(f"\n검색된 문서: {results['documents']}")
"RAG 파이프라인의 검색 품질이 낮은 건 임베딩 모델 문제일 수 있어요. text-embedding-ada에서 text-embedding-3-large로 바꾸면 MTEB 벤치마크 기준 15% 정도 성능이 올라갑니다."
"임베딩 모델 선택 시 고려하는 건 세 가지입니다. 첫째 차원 수(검색 속도 vs 정확도 트레이드오프), 둘째 max token 길이(긴 문서 처리 가능 여부), 셋째 다국어 지원(한국어 성능) 입니다."
"도메인 특화 검색이라면 Fine-tuning을 고려해보세요. 법률 문서에 일반 임베딩 모델 쓰면 전문 용어를 못 잡는데, 법률 코퍼스로 contrastive learning 하면 recall이 30% 이상 오릅니다."
모델마다 벡터 공간이 완전히 다릅니다. 모델을 바꾸면 기존에 저장된 모든 임베딩을 다시 생성해야 합니다. 그렇지 않으면 검색 결과가 엉망이 됩니다.
대부분의 임베딩 모델은 512~8192 토큰 제한이 있습니다. 긴 문서는 청크로 분할하고, 각 청크를 별도 임베딩한 뒤 검색 시 조합해야 합니다.
일부 모델(E5, BGE)은 쿼리 앞에 "query: ", 문서 앞에 "passage: " 프리픽스를 붙여야 최적 성능이 나옵니다. 모델 문서를 반드시 확인하세요.