본문 바로가기
  • 컴공생의 공부 일기
  • 공부보단 일기에 가까운 것 같은
  • 블로그
🤖 AI/AI

🔬임베딩 모델로 데이터 의미 압축하기 : 의미 검색 구현

by 정람지 2025. 1. 20.

LLM을 활용한 실전 AI 애플리케이션 개발

- 허정준


🪧의미 검색 구현하기

의미 검색 (semantic search)

Sentence-Transformers 라이브러리 + Faiss 라이브러리 

=> Sentence-Transformers로 임베딩 생성 / Faiss 라이브러리로 거리를 계산하고 가까운 임베딩 찾기

 

Faiss 라이브러리 

- 메타에서 개발한 벡터 연산 라이브러리

- 기본적 벡터 거리 검색 방법 (코사인 유사도, 유클리드 거리, 등) + 벡터 검색 속도 향상 ANN 알고리즘 등 제공


🫔 의미 검색 구현하기

예제 10.8 실습에 사용할 모델과 데이터셋 불러오기
from datasets import load_dataset
from sentence_transformers import SentenceTransformer

klue_mrc_dataset = load_dataset('klue', 'mrc', split='train')
sentence_model = SentenceTransformer('snunlp/KR-SBERT-V40K-klueNLI-augSTS')

모델

 

snunlp/KR-SBERT-V40K-klueNLI-augSTS · Hugging Face

snunlp/KR-SBERT-V40K-klueNLI-augSTS This is a sentence-transformers model: It maps sentences & paragraphs to a 768 dimensional dense vector space and can be used for tasks like clustering or semantic search. Usage (Sentence-Transformers) Using this model b

huggingface.co

데이터셋

 

klue/klue · Datasets at Hugging Face

 

huggingface.co

 

 

예제 10.9 실습 데이터에서 1,000개만 선택하고 문장 임베딩으로 변환
klue_mrc_dataset = klue_mrc_dataset.train_test_split(train_size=1000, shuffle=False)['train']
embeddings = sentence_model.encode(klue_mrc_dataset['context'])
embeddings.shape
# 출력 결과
# (1000, 768)

1000개 데이터셋 셔플 없이 가져와서 문장 임베딩 진행

encode()

 

 

예제 10.10 KNN 검색 인덱스를 생성하고 문장 임베딩 저장
import faiss
# 인덱스 만들기
index = faiss.IndexFlatL2(embeddings.shape[1])
# 인덱스에 임베딩 저장하기
index.add(embeddings)

faiss 라이브러리를 이용해서 KNN 검색 인덱스 생성 ( 데이터베이스 테이블 같은 거)

임베딩 저장

 

예제 10.11 의미 검색의 장점
query = "이번 연도에는 언제 비가 많이 올까?"
query_embedding = sentence_model.encode([query])
distances, indices = index.search(query_embedding, 3)

for idx in indices[0]:
  print(klue_mrc_dataset['context'][idx][:50])

# 출력 결과
# 올여름 장마가 17일 제주도에서 시작됐다. 서울 등 중부지방은 예년보다 사나흘 정도 늦은   (정답)
# 연구 결과에 따르면, 오리너구리의 눈은 대부분의 포유류보다는 어류인 칠성장어나 먹장어, 그 (오답)
# 연구 결과에 따르면, 오리너구리의 눈은 대부분의 포유류보다는 어류인 칠성장어나 먹장어, 그 (오답)



예제 10.12 의미 검색의 한계
query = klue_mrc_dataset[3]['question'] # 로버트 헨리 딕이 1946년에 매사추세츠 연구소에서 개발한 것은 무엇인가?
query_embedding = sentence_model.encode([query])
distances, indices = index.search(query_embedding, 3)

for idx in indices[0]:
  print(klue_mrc_dataset['context'][idx][:50])

# 출력 결과
# 태평양 전쟁 중 뉴기니 방면에서 진공 작전을 실시해 온 더글러스 맥아더 장군을 사령관으로 (오답)
# 태평양 전쟁 중 뉴기니 방면에서 진공 작전을 실시해 온 더글러스 맥아더 장군을 사령관으로 (오답)
# 미국 세인트루이스에서 태어났고, 프린스턴 대학교에서 학사 학위를 마치고 1939년에 로체스 (정답)

의미 검색 : 검색 쿼리 문장을 문장 임베딩으로 변환하고 인덱스에서 검색 수행

임베딩 변환 : encode 메서드

검색 수행 : search 메서드 ( 가까운 n 개 문서를 전달받겠다 )

 

의미 검색의 장점

키워드가 동일하지 않아도 의미가 유사하면 찾을 수 있다

 

의미 검색의 단점

관련성이 떨어지는 검색 결과가 나오기도 한다


🫔 라마인덱스에서 Sentence-Transformers 모델 사용하기

기본적으로 임베딩 모델을 OpenAI의 text-embedding-ada-002를 사용!

대신 Sentence-Transformers 라이브러리를 사용해 임베딩을 수행하기

 

Embeddings - LlamaIndex

Embeddings Concept Embeddings are used in LlamaIndex to represent your documents using a sophisticated numerical representation. Embedding models take text as input, and return a long list of numbers used to capture the semantics of the text. These embeddi

docs.llamaindex.ai

예제 10.13 라마인덱스에서 Sentence-Transformers 임베딩 모델 활용
from llama_index.core import VectorStoreIndex, ServiceContext
from llama_index.core import Document
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

embed_model = HuggingFaceEmbedding(model_name="snunlp/KR-SBERT-V40K-klueNLI-augSTS")
service_context = ServiceContext.from_defaults(embed_model=embed_model, llm=None)
# 로컬 모델 활용하기
# service_context = ServiceContext.from_defaults(embed_model="local")

text_list = klue_mrc_dataset[:100]['context']
documents = [Document(text=t) for t in text_list]

index_llama = VectorStoreIndex.from_documents(
    documents,
    service_context=service_context,
)