랭체인 Text Embeddings
Text Embedding
- 텍스트를 숫자로 이루어진 고차원 벡터로 변환하는 과정.
🔹 주요 역할
- 텍스트 간의 유사도 계산 가능 (비슷한 의미의 문장은 가까운 벡터를 가짐)
- 검색(Retrieval) 및 추천 시스템 에 활용
- GPT 같은 LLM이 문맥을 이해하는 데 도움
🔹 예시 (OpenAI Embeddings 사용)
from openai import OpenAI
client = OpenAI()
response = client.embeddings.create(
input="최성식의 연락처는?", model="text-embedding-ada-002"
)
embedding_vector = response.data[0].embedding
📌 즉, 텍스트 임베딩은 "문장의 의미"를 숫자로 표현하는 기술! 🚀
- 대부분의 경우, 대용량 말뭉치를 통해 사전학습된 모델로 쉽게 임베딩
- 임베딩 모델 : 비정형 데이터를 수치화해서 좌표상에 위치할 수 있도록 해줌
- 다차원의 벡터를 통해 비정형 언어를 정형 데이터로 바꾸는 역할을 담당하는 것
- 임베딩 모델이 학습되지 않은 문장에 대해서도 수치화하는 것을 잘할 수 있게 됨
사전학습 임베딩 모델
- OpenAI에서 제공하는 ada 모델, HuggingFace 모델 등
- 사용 목적 및 요구 사항에 따른 적절한 임베딩을 고르는 것이 RAG의 가장 주요한 부분
실습: Text Embeddings
실습 코드 : Text Embedding.ipynb
OpenAI Embeddings - ada-002
- OpenAIEmbeddings : OpenAI 임베딩 모델
- embeddings_model.embed_documents : 여러 개의 문장을 한꺼번에 임베딩
- 한글 문장을 embeddings에 저장
from langchain_openai import OpenAIEmbeddings
embeddings_model = OpenAIEmbeddings(openai_api_key = '{API KEY}')
embeddings = embeddings_model.embed_documents(
[
"안녕하세요",
"제 이름은 이하얀입니다.",
"이름이 무엇인가요?",
"랭체인은 유용합니다.",
"Hello World!"
]
)
len(embeddings), len(embeddings[0])
하나의 문장이 1536개의 차원을 가진 하나의 행이 된다는 의미
- 유사도 확인
- 지금 넣은 2문장도 1536차원으로 임베딩되었음을 알 수 있음
embedded_query_q = embeddings_model.embed_query("이 대화에서 언급된 이름은 무엇입니까?")
embedded_query_a = embeddings_model.embed_query("이 대화에서 언급된 이름은 이하얀입니다.")
print(len(embedded_query_q), len(embedded_query_a))
- 벡터 간 유사도 확인
- 코사인 유사도 사용
- 순서 : 질문-답변, 질문-두 번째 문장, 질문-네 번째 문장
from numpy import dot
from numpy.linalg import norm
import numpy as np
def cos_sim(A, B):
return dot(A, B) / (norm(A)*norm(B))
print(cos_sim(embedded_query_q, embedded_query_a))
print(cos_sim(embedded_query_q, embeddings[1]))
print(cos_sim(embedded_query_q, embeddings[3]))
오픈 소스 - HuggingFaceEmbeddings
- sentence-transformers 라이브러리 다운
!pip install sentence-transformers
1. BAAI/bge-small-en 임베딩 모델
- 주의 : 구글 코랩 환경일 경우 런타임 > 런타임 유형 변경 > GPU로 변경하여 사용
from langchain_community.embeddings import HuggingFaceEmbeddings
model_name = "BAAI/bge-small-en"
bge_embedding= HuggingFaceEmbeddings(
model_name=model_name
)
- 한글 문장 테스트
examples = bge_embedding.embed_documents(
[
"안녕하세요",
"제 이름은 홍두깨입니다.",
"이름이 무엇인가요?",
"랭체인은 유용합니다.",
]
)
embedded_query_q = bge_embedding.embed_query("이 대화에서 언급된 이름은 무엇입니까?")
embedded_query_a = bge_embedding.embed_query("이 대화에서 언급된 이름은 홍길동입니다.")
print(cos_sim(embedded_query_q, embedded_query_a))
print(cos_sim(embedded_query_q, examples[1]))
print(cos_sim(embedded_query_q, examples[3]))
- 영어 문장 테스트
examples2 = bge_embedding.embed_documents(
[
"today is tuesday",
"weather is nice today",
"what's the problem?",
"langchain in useful",
"Hello World!",
"my name is morris"
]
)
embedded_query_q = bge_embedding.embed_query("Hello? who is this?")
embedded_query_a = bge_embedding.embed_query("hi this is harrison")
print(cos_sim(embedded_query_q, embedded_query_a))
print(cos_sim(embedded_query_q, examples2[1]))
print(cos_sim(embedded_query_q, examples2[3]))
- 여러개 문장 비교
sentences = [
"안녕하세요",
"제 이름은 홍길동입니다.",
"이름이 무엇인가요?",
"랭체인은 유용합니다.",
"홍길동 아버지의 이름은 홍상직입니다."
]
examples3 = bge_embedding.embed_documents(sentences)
embedded_query_q = bge_embedding.embed_query("홍길동은 아버지를 아버지라 부르지 못하였습니다. 홍길동 아버지의 이름은 무엇입니까?")
embedded_query_a = bge_embedding.embed_query("홍길동의 아버지느 엄했습니다.")
print("질문: 홍길동은 아버지를 아버지라 부르지 못하였습니다. 홍길동 아버지의 이름은 무엇입니까? \n", "-"*100)
print("홍길동의 아버지는 엄했습니다. \t\t 문장 유사도: ", round(cos_sim(embedded_query_q, embedded_query_a),2))
print(sentences[1] + "\t\t 문장 유사도: ", round(cos_sim(embedded_query_q, examples3[1]),2))
print(sentences[3] + "\t\t 문장 유사도: ", round(cos_sim(embedded_query_q, examples3[3]),2))
print(sentences[4] + "\t 문장 유사도: ", round(cos_sim(embedded_query_q, examples3[4]),2))
2. jhgan/ko-sroberta-multitask
from langchain.embeddings import HuggingFaceEmbeddings
#HuggingfaceEmbedding 함수로 Open source 임베딩 모델 로드
model_name = "jhgan/ko-sroberta-multitask"
ko_embedding= HuggingFaceEmbeddings(
model_name=model_name
)
examples = ko_embedding.embed_documents(
[
"안녕하세요",
"제 이름은 홍두깨입니다.",
"이름이 무엇인가요?",
"랭체인은 유용합니다.",
]
)
embedded_query_q = ko_embedding.embed_query("이 대화에서 언급된 이름은 무엇입니까?")
embedded_query_a = ko_embedding.embed_query("이 대화에서 언급된 이름은 홍길동입니다.")
print(cos_sim(embedded_query_q, embedded_query_a))
print(cos_sim(embedded_query_q, examples[1]))
print(cos_sim(embedded_query_q, examples[3]))
3. OpenAI 임베딩 모델 - text-embedding-3-small
import os
import openai
from langchain_openai import OpenAIEmbeddings
from google.colab import userdata
openai.api_key = userdata.get('OPENAI_API_KEY')
embeddings_model = OpenAIEmbeddings(model = 'text-embedding-3-small')
embeddings = embeddings_model.embed_documents(
[
"Hi there!",
"Oh, hello!",
"What's your name?",
"My friends call me World",
"Hello World!"
]
)
len(embeddings), len(embeddings[0])
- OpenAI 임베딩 모델로 청크들을 임베딩 변환
from langchain_community.document_loaders import PyPDFium2Loader
from langchain_text_splitters import RecursiveCharacterTextSplitter
#임베딩 모델 API 호출
embeddings_model = OpenAIEmbeddings(model = 'text-embedding-3-small')
#PDF 문서 로드
loader = PyPDFium2Loader("/content/drive/MyDrive/NLP톺아보기/file/[이슈리포트 2022-2호] 혁신성장 정책금융 동향.pdf")
pages = loader.load()
#PDF 문서를 여러 청크로 분할
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=100
)
texts = text_splitter.split_documents(pages)
embeddings = embeddings_model.embed_documents([i.page_content for i in texts])
len(embeddings), len(embeddings[0])