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와 결합하면 강력한 검색·분류 파이프라인을 구축할 수 있습니다.