우선, 언어 모델을 만들기 위해 해야 하는 절차는 다음과 같다.
1. 가져올 뉴스데이터 URL를 확보한다.
2. TEXT를 추출한 후 파라미터를 조정해 스플릿한다.
3. 임베딩을 진행한다.
4. 벡터저장소에 저장한다.
5. 리트리버를 구성한다.
6. 프롬프트를 작성한다.
7. 모델에 적용한다.
1번 랭체인 라이브러리를 사용하였으며, URL 이 아니더라도 PDF, Log, Json 등 데이터 형태에 따라 변경한다.
from langchain.document_loaders import WebBaseLoader
import bs4
from langchain.schema import Document
loader = WebBaseLoader(
web_paths=("https://www.news1.kr/industry/distribution/5496643",),
bs_kwargs=dict(
parse_only=bs4.SoupStrainer(
"article",
attrs={"class": ["col-lg-7 article-padding-lg-right position-relative gx-0"]},
)
),
)
docs = loader.load()
print(f"문서의 수: {len(docs)}")
full_text = docs[0].page_content
cutoff_text = "hjin@news1.kr"
target_text = full_text.split(cutoff_text)[0] + cutoff_text if cutoff_text in full_text else full_text
docs = [Document(page_content=target_text, metadata=docs[0].metadata)]
print(docs)
2번 텍스트를 스플릿한다.
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=3000, # 청크의 크기
chunk_overlap=50 # 청크 간 중복되는 문자의 수
)
# 문서를 청크로 분할
splits = text_splitter.split_documents(docs)
3번 임베딩을 진행한다. OpenAI는 유료이기때문에... 실수하지 않도록 캐시를 저장해두는 것이 좋다.
# OpenAI 임베딩 설정
openai_embedding = OpenAIEmbeddings()
# 캐시 저장소 설정 (중복결제 방지)
store = LocalFileStore("./cache/")
# 캐시를 적용한 임베딩 설정
cached_embedder = CacheBackedEmbeddings.from_bytes_store(
openai_embedding,
store,
namespace=openai_embedding.model
)
4번 벡터DB에 벡터화된 데이터를 저장한다.
# FAISS 벡터 데이터베이스 생성 및 저장
vector_db = FAISS.from_documents(documents=splits, embedding=cached_embedder)
5번 리트리버를 구성한다.
# 리트리버 구성
retriever = vector_db.as_retriever()
6번 프롬프트를 작성한다.
from langchain_core.prompts import PromptTemplate
# 직접 프롬프트 템플릿을 생성
prompt = PromptTemplate.from_template(
"""당신은 질문-답변(Question-Answering)을 수행하는 친절한 AI 어시스턴트입니다. 당신의 임무는 주어진 문맥(context)에서 주어진 질문(question)에 답하는 것입니다.
검색된 다음 문맥(context)을 사용하여 질문(question)에 답하세요. 만약, 주어진 문맥(context)에서 답을 찾을 수 없다면, 답을 모른다면 '주어진 정보에서 질문에 대한 정보를 찾을 수 없습니다'라고 답하세요.
한글로 답변해 주세요. 단, 기술적인 용어나 이름은 번역하지 않고 그대로 사용해 주세요.
#Question:
{question}
#Context:
{context}
#Answer:"""
)
7. 언어모델에 적용한다.
llm = ChatOpenAI(model_name="gpt-4o", temperature=0)
# LLM 체인 생성
llm_chain = (
{
"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
class StreamChain:
def __init__(self, chain):
self.chain = chain
def stream(self, query):
response = self.chain.stream(query)
complete_response = ""
for token in response:
print(token, end="", flush=True)
complete_response += token
return complete_response
chain = StreamChain(llm_chain)
8. 모델을 사용하여 질문을 던져보자.
answer3번에 경우 질문에 해당하는 답이 없지만 할루시네이션을 일으킬 수 있어 프롬프트에 입력할 때 주어진 정보에 해당하는 답변이 없다면 답이 없다고 말하도록 설정해주어야 신뢰할 수 있는 정보가 될 수 있다.
꼭 OpenAI 모델을 사용해야 하는 것은 아니며, 허깅페이스나 더 낮은 무료버전 모델을 사용해도 무방하다.
'Scientist > ML.DL' 카테고리의 다른 글
[LangChain] Text Splitter 종류 (0) | 2024.08.09 |
---|---|
[LangChain] PDF Loader 종류 (0) | 2024.08.09 |
[ML/DL] LangChain이란? (0) | 2024.07.18 |
[ML/DL] NLP TF-IDF / Word2Vec (0) | 2024.07.18 |
[ML/DL] NLP 토크나이저 종류 (0) | 2024.07.17 |