LangChain 이란 ?
언어 모델을 더 잘 활용할수 있도록 도와주는 도구!
LangChain은 언어 모델로 구동되는 애플리케이션을 개발하기 위한 프레임워크이다.
가장 강력하고 차별화된 애플리케이션은 API를 통해 언어 모델을 호출할 뿐만 아니라 이를 통해 개발될 것이라 믿는다.
chatGPT의 문제
1. 정보 접근 제한
2. 토큰 제한
3. 환각증상
GPT개량
1. Fine-Tuning
2. N-shot Learning
3. RAG
LangChain의 구성 요소
LLM : 초거대 언어모델로, 생성 모델의 엔진과 같은 역할을 하는 핵심 구성요소
Prompts : 초거대 언어 모델에게 지시하는 명령문
Index : LLM이 문서를 쉽게 탐색할 수 있도록 구조화 하는 모듈
Memory : 채팅 이력을 기억하도록 하여, 이를 기반으로 대화가 가능하도록 하는 모듈
Chain : LLM 사슬을 형성하여, 연속적인 LLM호출이 가능하도록 하는 핵심 구성요소
Ageents : LLM이 기존 Prompt Template으로 수행할 수 없는 작업을 가능케 하는 모듈
LangChain은 특정 언어 모델을 만들려고 개발한게 아니다.
실습
코랩에서 실행한다.
!pip install openai
!pip install langchain
!pip install langchain-community langchain-core
openai와 langchain을 설치한다.
# os의 환경변수에 키값 저장
import os
os.environ["OPENAI_API_KEY"] = 'your_key'
os.environ["OPENAI_API_TYPE"] = 'azure'
os.environ["OPENAI_API_VERSION"] = '2023-05-15'
os.environ["AZURE_OPENAI_ENDPOINT"] = ' https://sktflyai.openai.azure.com/'
키값을 저장한다.
1. 완성형 언어모델
애저에서 davinci-002라는 완성형 언어모델을 배포한다.
from langchain.llms import AzureOpenAI # llms에 완성형 언어모델의 래퍼클래스가 들어있음
llm = AzureOpenAI(deployment_name='dev-davinci-002')
llm.invoke('Why python is the most popular language?')
결과 아래와 같은 답변이 생성된다.
davinci는 한글이 안되지만 gpt-35-turbo-instruct는 한글이 사용된다.
2. 대화형 언어모델
from langchain.chat_models import AzureChatOpenAI
chat = AzureChatOpenAI(deployment_name='dev-gpt-35-turbo')
chat.invoke('Why python is the most popular language? Answer the Korean')
- 스트리밍 방식으로 출력하기
# 스트리밍 방식으로 출력하기
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler # callback 처리
chat = AzureChatOpenAI(deployment_name='dev-gpt-35-turbo',
streaming=True, # streaming 지원
callbacks=[StreamingStdOutCallbackHandler()]) #날아오는 streaming callback
chat.invoke('Why python is the most popular language? Answer the Korean')
- system message 정의하기
실습 코드
https://github.com/joomj2000/Chatbot/blob/main/1_LLM.ipynb
Chatbot/1_LLM.ipynb at main · joomj2000/Chatbot
Contribute to joomj2000/Chatbot development by creating an account on GitHub.
github.com
템플릿 만들기
완성형과 대화형 모델이 다르게 있다.
완성형 대화모델을 사용해서 구체적인 템플릿을 만들어보자.
string_template='''
너는 요리사다. 제시하는 재료들로 만들 수 있는 요리를 추천하고 레시피를 제시하라
내가 가진 재료는 아래와 같다.
- 재 료 -
{ingredents}
'''
prompt=PromptTemplate(
input_variables=['ingredents'],
template=string_template ,
)
prompt
from langchain.llms import AzureOpenAI
llm=AzureOpenAI(
deployment_name='dev-gpt-35-turbo-instruct' #완성형 모델
)
response=llm(prompt.format(ingredents="소고기, 양파, 당근"))
print(response)
결과
대화형 언어모델은 system, human message를 구분해서 사용해야한다.
from langchain.prompts import (
ChatPromptTemplate,
PromptTemplate,
SystemMessagePromptTemplate,
AIMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
from langchain.chat_models import AzureChatOpenAI
chatgpt=AzureChatOpenAI(
deployment_name='dev-gpt-35-turbo', # 대화형 모델
model_name='dev-gpt-35-turbo'
)
# 대화형 프롬프트 템플릿 지정
system_prompt_template=SystemMessagePromptTemplate.from_template(string_template) # 페르소나 잡기
human_prompt_template=HumanMessagePromptTemplate.from_template("{ingredents}")
chat_prompt=ChatPromptTemplate.from_messages([system_prompt_template,human_prompt_template])
answer=chatgpt(chat_prompt.format_prompt(ingredents="소고기, 양파, 당근").to_messages())
print(answer.content)
few-short Learning
1. examples만들기
from langchain.prompts.few_shot import FewShotPromptTemplate
examples=[
{
'question':'아이유로 삼행시를 지어줘',
'answer':'''
아 아이유는
이 이상하게
유 유난히 좋다.
'''
},
{
'question':'이순신으로 삼행시를 지어줘',
'answer':'''
이 이순신 장군은
순 순순히 내어줄 것 같았던 조선의 바다를
신 신의와 충의의 마음으로 지켜냈다.
'''
}
]
2. 템플릿 만들기
example_prompt=PromptTemplate(input_cariables=['question','answer'],template='question: {question}\nanswer: {answer}')
3. few short learning
prompt=FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
suffix='question: {input}\nanswer:',
input_variables=['input']
)
llm(prompt.format(input='유관순으로 삼행시를 지어줘'))
few short learning은 실행시마다 해주어야해서 토큰을 많이 소모한다는 단점이 있지만, fine tuning을 하지 않아도 된다는 장점을 가지고 있다.
실습코드
https://github.com/joomj2000/Chatbot/blob/main/2_prompt_template.ipynb
Chatbot/2_prompt_template.ipynb at main · joomj2000/Chatbot
Contribute to joomj2000/Chatbot development by creating an account on GitHub.
github.com
RAG
Loader로 데이터 로딩하기
!pip install langchain langchain-community langchain-core
!pip install pypdf
웹 자료 가져오기
# WebBaseLoader 웹에있는 자료들을 긁어옴
from langchain.document_loaders import WebBaseLoader
loader = WebBaseLoader("https://www.naver.com")
data=loader.load()
print(data)
from langchain.document_loaders import PyPDFLoader # ptpdf 의 래퍼
loader = PyPDFLoader("/content/DJI_Osmo_Pocket_3_User_Manual_v1.0_en.pdf")
pages=loader.load_and_split()
print(pages[0])
word 파일 읽기
!pip install langchain langchain-community langchain-core
!pip install pypdf docx2txt
from langchain.document_loaders import Docx2txtLoader
loader = Docx2txtLoader("/content/LLM이 만들어 내는 혁명과 교통산업.docx")
data=loader.load()
print(data[0].page_content)
csv 파일읽기
from langchain.document_loaders import CSVLoader
loader = CSVLoader("/content/titanic3.csv",
csv_args={
'delimiter': ',',
'quotechar': '"',
'fieldnames': ['Pclass',
'Survived',
'Name',
'Sex',
'Age',
'SibSp',
'Parch',
'Ticket',
'Fare',
'Cabin',
'Embarked'
'Boat'
'Body'
'Home.dest']
})
data=loader.load()
data[:10]
실습코드
https://github.com/joomj2000/Chatbot/blob/main/3_Document_Loader.ipynb
Chatbot/3_Document_Loader.ipynb at main · joomj2000/Chatbot
Contribute to joomj2000/Chatbot development by creating an account on GitHub.
github.com
Splitter
document-loaders 모듈로 불러온 텍스트를 하나의 긴 텍스트로 되어있기 때문에 트랜스포메이션 변환 과정을 사용하여
좀 더 사용하기 쉽게 변환하는 과정이다.
기본으로 사용하는 Text splitter는 RecursiveCharacterTextSplitter이다.
우선 기본적인 CharcterTextsSplitter을 사용해보자.
!pip install langchain langchain-community langchain-core
!pip install pypdf
with open('/content/generative ai.txt') as f:
text_gen_ai = f.read()
from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(
separator = "\n",
chunk_size = 1000,
chunk_overlap = 200,
length_function = len,
)
texts=text_splitter.split_text(text_gen_ai) #chunk size보다 크면 WARNING 출력
자른걸 확인해보면 1000단위로 잘 잘라지지 않는다,,
이제 RevursiveCharacterTextSplitter을 사용해보자.
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size = 1000,
chunk_overlap = 100,
length_function = len,
)
texts = text_splitter.create_documents([text_gen_ai])
재귀적 호출을 사용하여 잘 잘리고 있다.
파이썬 코드 분류
from langchain.text_splitter import (RecursiveCharacterTextSplitter, Language)
RecursiveCharacterTextSplitter.get_separators_for_language(Language.PYTHON)
python_code='''
def hello_word():
print("hello world")
# Call the function
hello_word()
'''
#Python splitter
python_splitter = RecursiveCharacterTextSplitter.from_language(
language=Language.PYTHON,
chunk_size=50,
chunk_overlap=0,
)
python_texts = python_splitter.create_documents([python_code])
토큰 단위로 분할하기
!pip install tiktoken
import tiktoken
tokenizer=tiktoken.get_encoding('cl100k_base') #맞는 인코딩 방식을 찾아서 지정해야한다.
#토큰수를 세어주는 함수
def tiktoken_len(text):
tokens=tokenizer.encode(text)
return len(tokens)
tiktoken_len('I love you')
실습 코드
https://github.com/joomj2000/Chatbot/blob/main/4_splitter.ipynb
Chatbot/4_splitter.ipynb at main · joomj2000/Chatbot
Contribute to joomj2000/Chatbot development by creating an account on GitHub.
github.com
embeddings
애저에서 text-embedding-ada-002를 배포한다.
!pip install openai
!pip install langchain langchain-community langchain-core
!pip install pypdf tiktoken
# os의 환경변수에 키값 저장
import os
os.environ["OPENAI_API_KEY"] = 'your_key'
os.environ["OPENAI_API_TYPE"] = 'azure'
os.environ["OPENAI_API_VERSION"] = '2023-05-15'
os.environ["AZURE_OPENAI_ENDPOINT"] = 'https://sktflyai.openai.azure.com/'
# 배포된 모델 불러오기
from langchain.embeddings import AzureOpenAIEmbeddings
embeddings_model= AzureOpenAIEmbeddings(model = 'dev-text-embedding-ada-002', chunk_size=1000)
emveddings_example={
'안녕하세요',
'제 이름은 홍길동 입니다.',
'이름은 무엇입니까?',
'랭체인은 유용합니다.',
'Hello World'
}
emveddings_result=embeddings_model.embed_documents(emveddings_example)
embeddings_result=embeddings_model.embed_documents(emveddings_example)
# 각 데이터의 유사도를 비교하는 함수
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))
q = embeddings_model.embed_query('이 대화에서 언급된 이름은 무엇입니까?')
a=embeddings_model.embed_query('이 대화에서 언급된 이름은 홍길동 입니다.')
print(cos_sim(q,a)) #연관된 질문을 하면 유사도가 높게 나온다.
print(cos_sim(embeddings_result[0], embeddings_result[1]))
print(cos_sim(embeddings_result[0], embeddings_result[2]))
print(cos_sim(embeddings_result[0], embeddings_result[3]))
print(cos_sim(embeddings_result[0], embeddings_result[4]))
허깅페이스 임베딩 사용하기
!pip install sentence_transformers
from langchain.embeddings import HuggingFaceEmbeddings
model_name='BAAI/bge-small-en'
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': True}
hf = HuggingFaceEmbeddings(
model_name=model_name,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs
)
embedding_example={
'today is monday',
'weather is nice today',
"what's the problem",
'langchain is useful',
'Hello World',
'my name is morris'
}
embedding_result=hf.embed_documents(embedding_example)
q=hf.embed_query('Hello? who is this')
a= hf.embed_query('hi this is harrison')
print(cos_sim(q,a))
print(cos_sim(q, embedding_result[1]))
print(cos_sim(q,embedding_result[5]))
실습 코드
https://github.com/joomj2000/Chatbot/blob/main/5_embeddings.ipynb
Chatbot/5_embeddings.ipynb at main · joomj2000/Chatbot
Contribute to joomj2000/Chatbot development by creating an account on GitHub.
github.com
'SKT FLY AI' 카테고리의 다른 글
LLM (1) | 2024.11.09 |
---|---|
챗봇만들기 (0) | 2024.08.06 |
SKT FLY AI Challenger 5기 지원후기 [최종 합격] (0) | 2024.06.21 |