AIEmbeddingVectorNLPComputer VisionMultimodal
텍스트·이미지·멀티모달 임베딩 원리와 활용
텍스트 임베딩, 이미지 임베딩, 멀티모달 임베딩의 원리와 차이를 코드 예제와 함께 설명합니다.
VWV2026-04-025분 읽기
임베딩(Embedding)이란?
임베딩은 의미 정보를 담은 고차원 숫자 벡터입니다. 텍스트든 이미지든 오디오든, 컴퓨터가 처리할 수 없는 비정형 데이터를 벡터 공간에 배치함으로써 유사도 계산, 검색, 분류 등이 가능해집니다.
"고양이" → [0.12, -0.87, 0.34, 0.55, ...] (1536차원 벡터)
"猫" → [0.13, -0.85, 0.36, 0.53, ...] (비슷한 위치)
1. 텍스트 임베딩
원리
Transformer 기반 언어 모델(BERT, GPT 등)의 마지막 레이어 출력을 풀링(pooling)하여 생성합니다.
| 방법 | 설명 |
|---|---|
| CLS 토큰 풀링 | [CLS] 토큰의 출력 벡터 사용 |
| 평균 풀링 | 모든 토큰 벡터의 평균 |
| 최대 풀링 | 각 차원의 최댓값 선택 |
주요 모델 비교
| 모델 | 차원 | 특징 |
|---|---|---|
text-embedding-3-small (OpenAI) |
1536 | 비용 효율적 |
text-embedding-3-large (OpenAI) |
3072 | 고성능 |
all-MiniLM-L6-v2 (Sentence-BERT) |
384 | 오픈소스, 빠름 |
bge-m3 (BAAI) |
1024 | 다국어, 오픈소스 |
코드 예제
from sentence_transformers import SentenceTransformer
import numpy as np
model = SentenceTransformer("BAAI/bge-m3")
sentences = [
"인공지능 보안 취약점 분석",
"AI security vulnerability analysis",
"오늘 점심 메뉴는 뭘까요",
]
embeddings = model.encode(sentences, normalize_embeddings=True)
# 코사인 유사도 계산
def cosine_sim(a, b):
return np.dot(a, b) # 이미 정규화됨
print(cosine_sim(embeddings[0], embeddings[1])) # ~0.92 (같은 의미)
print(cosine_sim(embeddings[0], embeddings[2])) # ~0.21 (다른 의미)
2. 이미지 임베딩
원리
CNN(ResNet, EfficientNet) 또는 Vision Transformer(ViT)의 특징 추출 레이어 출력을 벡터로 사용합니다.
이미지(224×224×3) → CNN/ViT → 특징 벡터 [0.34, -0.12, ...] (2048차원)
코드 예제
from PIL import Image
import torch
from torchvision import models, transforms
# ResNet50 특징 추출기
model = models.resnet50(weights="IMAGENET1K_V2")
model.fc = torch.nn.Identity() # 마지막 FC 레이어 제거
model.eval()
preprocess = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
])
def get_image_embedding(path: str) -> torch.Tensor:
img = Image.open(path).convert("RGB")
tensor = preprocess(img).unsqueeze(0)
with torch.no_grad():
return model(tensor).squeeze() # (2048,) 벡터
emb = get_image_embedding("screenshot.png")
print(emb.shape) # torch.Size([2048])
활용 사례
| 사례 | 내용 |
|---|---|
| 역방향 이미지 검색 | 비슷한 이미지 찾기 |
| 얼굴 인식 | FaceNet 임베딩 비교 |
| 악성코드 시각화 분석 | 바이너리→이미지→임베딩 |
| 피싱 사이트 탐지 | 로고 이미지 유사도 |
3. 멀티모달 임베딩
원리
텍스트와 이미지를 같은 벡터 공간에 투영합니다. 대표 모델은 OpenAI의 CLIP입니다.
"강아지가 공원에서 뛰는 사진" (텍스트) → [0.71, -0.23, ...]
🐕 강아지 달리기 이미지 (이미지) → [0.69, -0.25, ...]
코사인 유사도 ≈ 0.94
CLIP 코드 예제
from PIL import Image
import open_clip
import torch
model, _, preprocess = open_clip.create_model_and_transforms("ViT-B-32", pretrained="openai")
tokenizer = open_clip.get_tokenizer("ViT-B-32")
model.eval()
image = preprocess(Image.open("dog.jpg")).unsqueeze(0)
texts = tokenizer(["강아지", "고양이", "자동차"])
with torch.no_grad():
image_features = model.encode_image(image)
text_features = model.encode_text(texts)
# 정규화
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)
similarity = (image_features @ text_features.T).squeeze()
print(similarity) # tensor([0.92, 0.45, 0.18]) — "강아지"가 가장 유사
임베딩 유형 비교
| 구분 | 입력 | 출력 | 주요 용도 |
|---|---|---|---|
| 텍스트 임베딩 | 텍스트 | 벡터 | 검색, 분류, RAG |
| 이미지 임베딩 | 이미지 | 벡터 | 유사 이미지 검색, 분류 |
| 멀티모달 임베딩 | 텍스트 + 이미지 | 공유 벡터 | 크로스모달 검색, VQA |
벡터 DB 저장 및 검색
임베딩을 실제로 활용하려면 벡터 데이터베이스가 필요합니다.
import chromadb
client = chromadb.Client()
collection = client.create_collection("docs")
# 저장
collection.add(
ids=["doc1", "doc2"],
embeddings=[[0.1, 0.2, ...], [0.4, 0.5, ...]],
documents=["보안 취약점 리포트", "AI 에이전트 설계"],
)
# 쿼리
results = collection.query(
query_embeddings=[[0.1, 0.2, ...]],
n_results=2,
)
| 벡터 DB | 특징 |
|---|---|
| Chroma | 오픈소스, 로컬 실행 간편 |
| Pinecone | 관리형 서비스, 대용량 적합 |
| Weaviate | 하이브리드 검색 지원 |
| pgvector | PostgreSQL 확장, 기존 DB 통합 |
정리
임베딩은 RAG, 의미 검색, 추천 시스템, 이미지 분류 등 현대 AI 애플리케이션의 기반 기술입니다. 텍스트·이미지·멀티모달 각 영역에 맞는 모델을 선택하고, 벡터 DB와 결합하면 강력한 검색·분류 파이프라인을 구축할 수 있습니다.