텍스트를 의미를 담은 숫자 벡터로 변환하는 것입니다.
의미가 비슷한 문장은 벡터 공간에서 가까운 위치에 놓이기 때문에, 단어가 겹치지 않아도 유사한 내용을 찾아낼 수 있습니다.
#### 1) 왜 필요한가
컴퓨터는 텍스트를 그대로 이해하지 못합니다. "강아지"와 "개"가 비슷한 의미라는 것도, "강아지"와 "주식"이 전혀 다르다는 것도 모릅니다. Embedding은 이 문제를 해결하기 위해 **텍스트(또는 이미지)를 실수 벡터로 변환**하고, 그 벡터 공간에서 의미적 거리를 계산 가능하게 만드는 기술입니다.
```
"강아지가 뛰어논다" → [0.21, -0.43, 0.88, ..., 0.05] (예: 1536차원)
"개가 달린다" → [0.19, -0.41, 0.85, ..., 0.03]
"주식 시장 폭락" → [-0.77, 0.12, -0.05, ..., 0.91]
```
앞의 두 벡터는 가깝고, 세 번째는 멉니다. 단어가 하나도 안 겹쳐도 의미가 비슷하면 벡터가 가까워지는 게 핵심입니다.
#### 2) 내부적으로 어떻게 만들어지는가
Transformer 기반 Encoder 모델(BERT 계열, 또는 GPT 계열의 중간층)에 텍스트를 넣으면, 각 토큰마다 벡터가 나옵니다. 문장 전체의 임베딩은 보통 이 토큰 벡터들을 평균 내거나(mean pooling), 맨 앞의 특수 토큰(`[CLS]`) 벡터를 그대로 쓰는 방식으로 만듭니다.
```
"강아지가 뛰어논다"
↓ 토크나이징
["강아지", "가", "뛰어", "논다"]
↓ Transformer Encoder
[벡터1, 벡터2, 벡터3, 벡터4] (토큰별 벡터)
↓ Pooling (평균 또는 CLS)
[0.21, -0.43, 0.88, ...] (문장 하나의 벡터)
```
이 모델은 방대한 텍스트로 사전 학습되면서, "비슷한 문맥에 자주 등장하는 단어는 비슷한 벡터를 갖도록" 자동으로 조정됩니다. 이게 근본 원리입니다.
#### 3) 유사도는 어떻게 계산하는가
두 벡터가 얼마나 가까운지는 보통 **코사인 유사도**로 잽니다. 벡터의 크기가 아니라 방향(각도)만 봅니다.
python
```
import numpy as np
def cosine_similarity(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
# 값이 1에 가까울수록 유사, 0이면 무관, -1이면 반대
```
값이 1에 가까우면 의미가 거의 같고, 0에 가까우면 무관, 음수면 반대 의미에 가깝습니다.
#### 4) 실제로 벡터로 확인해보기
python
```
from openai import OpenAI
client = OpenAI()
def get_embedding(text):
response = client.embeddings.create(
input=text,
model="text-embedding-3-small"
)
return response.data[0].embedding
v1 = get_embedding("강아지가 뛰어논다")
v2 = get_embedding("개가 달린다")
v3 = get_embedding("주식 시장 폭락")
print(len(v1)) # 1536 — 벡터 차원 수
```
`text-embedding-3-small`은 1536차원, `text-embedding-3-large`는 3072차원 벡터를 냅니다. 차원이 클수록 표현력은 좋아지지만 저장 공간과 검색 속도에서 비용이 커집니다.
#### 5) 대표적인 임베딩 모델
| 모델 | 특징 |
| --- | --- |
| **OpenAI text-embedding-3** | API 호출, 성능 좋고 다국어 지원 |
| **BGE (BAAI)** | 오픈소스, 한국어 성능 좋음, 로컬 실행 가능 |
| **KoSimCSE / KoSBERT** | 한국어 특화 오픈소스 |
| **Sentence-Transformers (all-MiniLM 등)** | 가볍고 빠름, 로컬 실습용으로 적합 |
| **Cohere Embed** | 다국어, 검색 특화 |
로컬에서 무료로 실습하려면 `sentence-transformers`가 제일 간편합니다.
python
```
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("BAAI/bge-m3")
v1 = model.encode("강아지가 뛰어논다")
v2 = model.encode("개가 달린다")
```
#### 6) 면접에서 나올 수 있는 심화 질문 대비
**Q. 임베딩 차원이 크면 무조건 좋은가요?**
아닙니다. 차원이 커지면 미묘한 의미 차이까지 표현할 수 있지만, 저장 용량과 검색 속도가 늘어나고 "차원의 저주"로 오히려 유사도 구분이 흐려지는 경우도 있습니다. 그래서 실무에서는 필요 이상으로 큰 모델을 쓰지 않고, 성능과 비용의 균형점을 찾습니다.
**Q. 같은 텍스트를 다른 임베딩 모델에 넣으면 벡터를 비교할 수 있나요?**
안 됩니다. 모델마다 벡터 공간의 좌표축 자체가 다르기 때문에, A 모델로 만든 벡터와 B 모델로 만든 벡터는 서로 거리 비교가 불가능합니다. RAG 시스템에서 검색용 임베딩 모델을 한 번 정하면 이후 문서·질문 모두 같은 모델로 일관되게 임베딩해야 합니다.
**Q. Fine-tuning된 임베딩 모델이 필요한 경우는?**
특정 도메인(의료, 법률, 반도체 공정 용어 등)에서 일반 임베딩 모델이 도메인 용어를 잘 구분하지 못할 때입니다. 이 경우 도메인 데이터로 임베딩 모델을 추가 학습(fine-tuning)해서 검색 정확도를 높입니다.
<br>
***
**Vector DB가 무엇인가요?**
Embedding으로 변환된 벡터를 저장하고, 질문 벡터와 가장 가까운 벡터를 빠르게 찾아주는 데이터베이스입니다.
대표적으로 Chroma, FAISS, Milvus, pgvector가 있습니다.
**일반 데이터베이스 대신 Vector DB를 쓰는 이유는?**
일반 DB는 값이 정확히 일치하는 것을 찾습니다. 반면 Vector DB는 의미가 유사한 것을 찾습니다.
예를 들어 "휴가 신청은 어떻게 하나요"라는 질문에 "연차 사용 절차"라는 문서를 찾아내려면 키워드 일치로는 불가능하고,
의미 기반 검색이 필요합니다.
**검색 품질을 높이려면 무엇이 중요한가요?**
문서를 어떤 크기로 자르는지(청킹), 부서나 날짜 같은 메타데이터로 먼저 걸러내는지,
그리고 키워드 검색과 병행하는지가 중요합니다. 고유명사나 제품코드는 벡터 검색만으로는 잘 안 잡히기 때문입니다.
콘텐츠를 불러오는 중..

댓글목록
최고관리자님의 댓글
똥컴에도 희망이 있습니다.