Skip to main content

문장 임베딩 — Sentence-BERT, E5, BGE

문장 임베딩(Sentence Embedding)은 문장 전체의 의미를 하나의 벡터로 인코딩합니다. 문장 간 유사도 비교, 검색, 클러스터링 등에 사용되며, RAG 파이프라인의 핵심 구성 요소입니다.

핵심 아이디어

BERT 같은 모델은 토큰 수준의 임베딩을 출력합니다. 문장 임베딩은 이를 하나의 고정 크기 벡터로 변환하여, **코사인 유사도(Cosine Similarity)**로 문장 간 의미적 유사도를 효율적으로 비교합니다.

동작 방식

주요 모델

Sentence-BERT (SBERT, 2019)

BERT를 Siamese 구조로 Fine-Tuning하여 문장 임베딩을 생성합니다.
from sentence_transformers import SentenceTransformer

model = SentenceTransformer('all-MiniLM-L6-v2')

sentences = [
    "딥러닝은 인공 신경망을 사용합니다",
    "신경망 기반의 기계 학습 기법입니다",
    "오늘 날씨가 좋습니다",
]

# 문장 임베딩 생성
embeddings = model.encode(sentences)
print(f"임베딩 shape: {embeddings.shape}")  # (3, 384)

# 유사도 계산
from sentence_transformers.util import cos_sim
similarities = cos_sim(embeddings, embeddings)
print(f"문장 1-2 유사도: {similarities[0][1]:.4f}")  # 높은 유사도
print(f"문장 1-3 유사도: {similarities[0][2]:.4f}")  # 낮은 유사도

E5 (2022) / BGE (2023)

최신 임베딩 모델들로, 다국어 지원과 높은 검색 성능을 제공합니다.
모델차원다국어특징
all-MiniLM-L6-v2384영어경량, 빠른 추론
multilingual-e5-large1024100+ 언어높은 검색 성능
bge-m31024100+ 언어밀집 + 희소 + 멀티벡터
gte-Qwen2-7B-instruct3584다국어최고 성능, 대형

구현

# Hugging Face Transformers 직접 사용
import torch
from transformers import AutoTokenizer, AutoModel

def mean_pooling(model_output, attention_mask):
    """토큰 임베딩을 평균하여 문장 임베딩 생성"""
    token_embeddings = model_output.last_hidden_state
    input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
    return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)

tokenizer = AutoTokenizer.from_pretrained('intfloat/multilingual-e5-small')
model = AutoModel.from_pretrained('intfloat/multilingual-e5-small')

sentences = ["query: 딥러닝이란?", "passage: 딥러닝은 다층 신경망을 사용하는 기계 학습의 한 분야입니다"]
encoded = tokenizer(sentences, padding=True, truncation=True, return_tensors='pt')

with torch.no_grad():
    outputs = model(**encoded)

embeddings = mean_pooling(outputs, encoded['attention_mask'])
embeddings = torch.nn.functional.normalize(embeddings, p=2, dim=1)

similarity = torch.dot(embeddings[0], embeddings[1])
print(f"유사도: {similarity.item():.4f}")

관련 기술 비교

방법입력 단위추론 속도정확도
TF-IDF단어 빈도매우 빠름낮음
Word2Vec 평균단어빠름보통
Sentence-BERT문장빠름높음
Cross-Encoder문장 쌍느림매우 높음
Bi-Encoder(Sentence-BERT, E5 등)는 빠르지만, 두 문장 간의 세밀한 상호작용을 포착하지 못합니다. 정밀한 유사도 판단이 필요하면 Cross-Encoder로 재순위화(Reranking)하는 2단계 파이프라인을 사용합니다. 이 내용은 RAG 탭의 Reranking 문서에서 다룹니다.

참고 논문

논문학회/연도핵심 기여
Sentence-BERT (Reimers & Gurevych)EMNLP 2019Siamese BERT로 문장 임베딩
Text Embeddings by Weakly-Supervised Contrastive Pre-training - E5 (Wang et al.)ACL 2022대규모 약한 지도 학습
C-Pack: Packaged Resources for General Chinese Embeddings - BGE (Xiao et al.)2023다국어 임베딩 + 리트리벌