임베딩이란?
임베딩은 텍스트, 이미지, 코드를 숫자 벡터(배열)로 변환하는 기술입니다. 의미가 비슷한 내용은 벡터 공간에서 가까이 위치합니다.
flowchart LR T1["'파이썬 튜토리얼'"] --> E[임베딩 모델] T2["'Python 강의'"] --> E T3["'고양이 사료'"] --> E E --> V1["[0.82, 0.31, ...]"] E --> V2["[0.79, 0.35, ...]"] E --> V3["[0.12, 0.91, ...]"] V1 --- |"유사도 0.95"| V2 V1 --- |"유사도 0.08"| V3
주요 임베딩 모델 비교
| 모델 | 차원 | 컨텍스트 | 언어 | 특징 |
|---|---|---|---|---|
| text-embedding-3-large | 3072 | 8191 토큰 | 다국어 | OpenAI 최고 품질 |
| text-embedding-3-small | 1536 | 8191 토큰 | 다국어 | 비용/품질 균형 |
| BGE-M3 | 1024 | 8192 토큰 | 다국어 | 한국어 최강, 무료 |
| E5-large-v2 | 1024 | 512 토큰 | 영어 | 검색 특화 |
| Cohere embed-v3 | 1024 | 512 토큰 | 다국어 | API 서비스 |
| nomic-embed-text | 768 | 8192 토큰 | 영어 | 로컬 실행 가능 |
OpenAI Embeddings API
from openai import OpenAI
import numpy as np
client = OpenAI()
def get_embedding(text: str, model="text-embedding-3-small") -> list[float]:
text = text.replace("
", " ")
return client.embeddings.create(input=[text], model=model).data[0].embedding
# 단일 임베딩
vec = get_embedding("인공지능이란 무엇인가?")
print(f"벡터 차원: {len(vec)}") # 1536
# 배치 처리 (비용 절감)
texts = ["첫 번째 문서", "두 번째 문서", "세 번째 문서"]
response = client.embeddings.create(input=texts, model="text-embedding-3-small")
vectors = [item.embedding for item in response.data]
# 코사인 유사도 계산
def cosine_similarity(a: list, b: list) -> float:
a, b = np.array(a), np.array(b)
return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))
query_vec = get_embedding("파이썬 배우기")
doc_vec = get_embedding("Python 프로그래밍 강좌")
print(f"유사도: {cosine_similarity(query_vec, doc_vec):.4f}") # 약 0.92
BGE-M3: 무료 한국어 최강 모델
from FlagEmbedding import BGEM3FlagModel
# 모델 로드 (처음 실행 시 자동 다운로드)
model = BGEM3FlagModel('BAAI/bge-m3', use_fp16=True)
# 문서 임베딩
documents = [
"인공지능은 컴퓨터 과학의 한 분야입니다",
"머신러닝은 데이터로 모델을 학습합니다",
"오늘 저녁 메뉴는 삼겹살입니다",
]
doc_embeddings = model.encode(
documents,
batch_size=12,
max_length=512,
return_dense=True,
return_sparse=True, # 희소 벡터도 함께 (BM25 효과)
return_colbert_vecs=False,
)['dense_vecs']
# 쿼리 검색
query = "딥러닝 알고리즘"
query_embedding = model.encode([query])['dense_vecs'][0]
# 유사도 계산
from sklearn.metrics.pairwise import cosine_similarity
scores = cosine_similarity([query_embedding], doc_embeddings)[0]
for i, score in enumerate(scores):
print(f"{score:.4f}: {documents[i]}")
Sentence Transformers (로컬 실행)
from sentence_transformers import SentenceTransformer
# 다양한 모델 선택 가능
model = SentenceTransformer('paraphrase-multilingual-mpnet-base-v2')
sentences = [
"The weather is lovely today.",
"It's so sunny outside!",
"He drove to the stadium.",
]
embeddings = model.encode(sentences)
# 유사도 행렬
from sentence_transformers import util
cosine_scores = util.cos_sim(embeddings, embeddings)
for i in range(len(sentences)):
for j in range(i+1, len(sentences)):
print(f"{sentences[i][:30]} ↔ {sentences[j][:30]}: {cosine_scores[i][j]:.4f}")
pgvector로 프로덕션 시맨틱 검색
import psycopg2
import numpy as np
from openai import OpenAI
client = OpenAI()
# 테이블 생성 (한 번만)
def setup_db(conn):
with conn.cursor() as cur:
cur.execute("CREATE EXTENSION IF NOT EXISTS vector")
cur.execute('''
CREATE TABLE IF NOT EXISTS documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding vector(1536)
)
''')
conn.commit()
# 문서 삽입
def insert_doc(conn, content: str):
vec = client.embeddings.create(
input=[content],
model="text-embedding-3-small"
).data[0].embedding
with conn.cursor() as cur:
cur.execute(
"INSERT INTO documents (content, embedding) VALUES (%s, %s)",
(content, vec)
)
conn.commit()
# 시맨틱 검색
def semantic_search(conn, query: str, top_k: int = 5):
query_vec = client.embeddings.create(
input=[query],
model="text-embedding-3-small"
).data[0].embedding
with conn.cursor() as cur:
cur.execute(
'''SELECT content, 1 - (embedding <=> %s::vector) AS similarity
FROM documents
ORDER BY embedding <=> %s::vector
LIMIT %s''',
(query_vec, query_vec, top_k)
)
return cur.fetchall()
# 사용
conn = psycopg2.connect("postgresql://localhost/mydb")
setup_db(conn)
results = semantic_search(conn, "파이썬 머신러닝 라이브러리")
for content, score in results:
print(f"{score:.4f}: {content[:60]}")
차원 축소와 시각화
import numpy as np
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
# 고차원 임베딩을 2D로 축소
words = ["고양이", "개", "강아지", "자동차", "버스", "비행기"]
embeddings = [get_embedding(w) for w in words]
pca = PCA(n_components=2)
coords = pca.fit_transform(embeddings)
plt.figure(figsize=(8, 6))
for i, word in enumerate(words):
plt.scatter(coords[i, 0], coords[i, 1])
plt.annotate(word, (coords[i, 0], coords[i, 1]))
plt.title("단어 임베딩 2D 시각화")
plt.savefig("embeddings_vis.png")
임베딩 활용 사례
mindmap root((임베딩 활용)) 검색 시맨틱 검색 코드 검색 이미지 검색 추천 협업 필터링 콘텐츠 기반 상품 추천 분류 감정 분석 스팸 필터 카테고리 분류 RAG 문서 청킹 컨텍스트 검색 답변 생성
임베딩 모델 선택 기준: 한국어 포함이면 BGE-M3(무료) 또는 text-embedding-3-small, 영어 전용이면 E5-large가 비용 효율적입니다.





