일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- aws
- 오블완
- 로컬 런타임
- chromeextention
- mifare
- 파이썬
- pandas
- Python
- ai_캠프
- Github
- seaborn
- finpilot
- mysql
- ai 캠프
- pytorch
- streamlit
- team_project
- 머신러닝
- sLLM
- ai캠프
- conda
- 티스토리챌린지
- EC2
- 정치기 필기
- ollama
- lightsail
- Jupyterlab
- django
- ML
- djangorestframework
- Today
- Total
greatsangho의 이야기
캠프51일차 - 프롬프트 엔지니어링 응용(랭체인) 본문
- 랭체인 : 대규모 언어 모델을 활용한 프레임워크
- GPT-4o-mini모델 기반하에 동작 추천
- 구성
- 라이브러리
- 템플릿 :
- 랭서브 : REST API 배포
- 랭스미스 : 개발자 플랫폼(디버깅, 테스트, 평가, 모니터링)
유료버전 OpenAI API 키를 바탕으로 진행한다.
- LLM 체인의 구성요소
- 프롬프트 , LLM
from langchain_openai import ChatOpenAI
# model
llm = ChatOpenAI(model="gpt-4o-mini")
llm.invoke("대한민국의 경제 순위는?")
# 템플릿
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template("경제 전문가로 행동해 <Question> : {input}") # assistant처럼 알고 싶어하는 범위 정하기
prompt
llm = ChatOpenAI(model="gpt-4o-mini")
# chain 연결
chain = prompt | llm
# chain 호출
chain.invoke({'input' : '대한민국의 경제 순위는?'})
# 프롬프트, LLM, 문자열 출력 파서(StrOutputParser)를 연결해서 체인을 만들 수 있다
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatMessagePromptTemplate
from langchain_core.output_parsers import StrOutputParser
# prompt + model + output parser
ChatPromptTemplate.from_template("세계경제 전문가로 답변해줘 <Question> : {input}")
llm = ChatOpenAI(model="gpt-4o-mini")
# llm = ChatOpenAI(model="gpt-3.5-turbo")
output_parser = StrOutputParser() # 문자열만 출력
# chain 연결
chain = prompt | llm | output_parser
# chain 호출
chain.invoke({"input":"대한민국의 경제순위는?"})
순차 연결
# 순차 연결(Serial Connectoin)
prompt1 = ChatPromptTemplate.from_template("한국어 {korean_txt}를 영어로 번역해")
prompt2 = ChatPromptTemplate.from_template("{english_txt}를 옥스포드 사전에서 찾아서 한국어로 설명해줘")
llm = ChatOpenAI(model="gpt-4o-mini")
output_parser = StrOutputParser()
chain1 = prompt1 | llm | output_parser
chain2 = prompt2 | llm | output_parser
chain1.invoke({"korean_txt":"사랑스럽다"})
chain2 = (
{"english_txt":chain1} | prompt2 | llm | output_parser
)
chain2.invoke({"korean_txt":"사랑스럽다"})
# langChain Runnable 프로토콜 - 인터페이스 -> 상황에 따라서 구체화, 추상클래스, 자바에서 Runnable 존재함, 실행할 수 있는 상태
- invoke : 입력에 대한 체인을 호출, 단일 결과를 반환 메소드 -> 단일입력
- batch : 입력리스트 대해 체인을 호출, 리스트 결과
- stream : 입력에 대한 체인을 호출, 결과의 조각들을 스트리밍 한다
- 대용량 데이터, 실시간 데이터 처리
- 비동기 버전 : ainvoke, abatch, astream 메소드는 각각의 동기버전의 비동기 버전 (동시에 시행함)
- LangChain을 사용한 커스텀 체인을 생성
- 필요한 컴포넌트를 정의 , 각각을 Runnable 인터페이스를 구현
- 컴포넌트들을 조합해서 사용자 정의 체인을 생성
- 생성된 체인을 사용해서 데이터 처리 작업, 이때 invoke, batch, stream 메소드를 사용
- 프로토콜은 인터페이스를 의미함
from langchain.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain.schema.output_parser import StrOutputParser
#1 컴포넌트 정의
prompt = ChatPromptTemplate.from_template("인공지능에서 {title}에 대해 간략하게 설명해 주세요")
llm = ChatOpenAI(model="gpt-4o-mini")
output_parser = StrOutputParser()
# 체인 생성
chain = prompt | llm | output_parser
# invoke 메소드 사용
result = chain.invoke({'title':'랭체인'})
print(f"invoke 결과 : {result}")
# batch를 이용
titles = ['랭체인', '벡터DB', '파인튜닝', '대규모 자연어 모델 개발']
results = chain.batch([{'title':title } for title in titles]) # 7초
[chain.invoke({"title":title}) for title in titles] # 21초
# 단일연결 / 순차연결
# 배치로 수행
# Stream 메소드
from langchain.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain.schema.output_parser import StrOutputParser
stream = chain.stream({"title":"LLM"})
for chunk in stream:
print(f"{chunk}",end='', flush=True) # end='\n', flush: 내부버퍼에 출력을 한꺼번에 받아서 출력, flush=True 버퍼에 쌓지 않고 바로 출력 -> 실시간
result = chain.invoke({'title':'LLM'})
print(result)
비동기는 순서가 보장되지 않음
# 비동기 메소드
import nest_asyncio # 실행중인 이벤트루프 다시 진입할 수 있게 해주는 라이브러리
import asyncio # 파이썬에서 지원하는 비동기 메소드
nest_asyncio.apply() # 이벤트루프 다시 진입
# CPU는 순차처리를 하므로 시간을 쪼개서 돌아가며 실행, 비동기처럼 보이게 실행됨
# 비동기 메소드 사용(async / await) # 프로세스를 점유하지 않고 기다림, 시분할 방식
async def run_async(title): # 비동기 async로
result = await chain.ainvoke({'title':title})
print(f'결과 : {result[:100]}')
# asyncio.run(run_async('LLM')) # run으로 실행
# 여러작업(task)을 실행
async def run_all():
task = [
run_async('LLM'),
run_async('랭체인'),
run_async('파인튜닝'),
run_async('대규모 자연어 모델 개발'),
run_async('벡터DB')
]
await asyncio.gather(*task) # await로 실행
asyncio.run(run_all())
# 비동기 호출이므로 리스트에 저장된 순서대로 결과가 나오지 않는다
# 9초
def run_async(title): # 비동기 async로
result = chain.invoke({'title':title})
print(f'결과 : {result[:100]}')
def run_all():
run_async('LLM'),
run_async('랭체인'),
run_async('파인튜닝'),
run_async('대규모 자연어 모델 개발'),
run_async('벡터DB')
run_all()
# 20초
- 프롬프트 작성법
- 구체성(모호한 질문은 사양)
- 맛있는 과일을 고르는 방법은? X
- 맛있는 사과를 고르려고 하는데, 사과 색이 진할수록 좋고 맛있는 사과인지 알려주세요
- 배경정보
- 모델이 문맥 정보를 이해할 수 있도록
- 가을에 생산되고 일조량이 충분한 경북 사과중에서 색갈이 진한 사과가 좋은 사과인지 알려주세요
- 간결함
- 불필요한 정보를 배제한다. 프롬프트가 길어지면 모델이 덜 중요한 정보에 집중하는 현상발생
- 열린 질문** / 닫힌 질문
- 열린질문: 이 코드의 문제점은 뭐야?
- 닫힌질문: 이 코드에 에러가 있으니 고쳐줘
- 요즘 추세는 열린질문임
# from langchain.prompts import ChatPromptTemplate
from langchain_core.prompts import PromptTemplate
template_text = '안녕하세요 저는 {name}이고, 나이는 {age}입니다.'
prompt_template = PromptTemplate.from_template(template_text)
prompt = prompt_template.format(name='홍길동', age=20)
print(prompt)
# 문자열 _ 문자열
# PromptTemplate + PromptTemplate
# PromptTemplate + 문자열
combined_prompt = (
prompt_template
+ PromptTemplate.from_template('\n\n 저는 서자입니다. 아버지를 아버지라 부르지 못하고 형을 형이라 부르지 못합니다.')
+ '\n\n{lan} 로 변역해 주세요'
)
combined_prompt
# 프롬프트 | 모델 | StrOutputParser --> invoke
llm = ChatOpenAI(model="gpt-4o-mini")
chain = combined_prompt | llm | StrOutputParser()
chain.invoke({'name':'홍길동', 'age':20, 'lan':'영어'})
# ChatPromptTemplate 대화형 상황
# 메세지 기반. 역할(role) 내용 content로 구성
- Message 유형
- SystemMessage : 시스템의 질문
- HumanMessage : 사용자의 질문
- AIMessage : AI 모델의 응답
- FunctionMessage : 함수 호출 결과
- ToolMessage : 도구 호출 결과
from langchain_core.prompts import ChatPromptTemplate
chat_prompt = ChatPromptTemplate.from_messages([
('system', '이 시스템은 {language}로 대답해준다'),
('user','{user_input}')
])
message = chat_prompt.format_prompt(language='영어', user_input='안녕하세요')
message.to_messages()
# MessagePromptTemplate
from langchain_core.prompts import SystemMessagePromptTemplate, HumanMessagePromptTemplate
chat_prompt = ChatPromptTemplate.from_messages([
SystemMessagePromptTemplate.from_template('이 시스템은 {language}로 대답해준다'),
HumanMessagePromptTemplate.from_template('{user_input}')
])
message = chat_prompt.format_prompt(language='영어', user_input='안녕하세요')
message.to_messages()
chain = chat_prompt | llm | StrOutputParser()
chain.invoke({'language':'영어','user_input':'달러당 환율이 갑자기 오르거나 내리는 일이 발생하는 이유가 무엇인가요?'})
- few shot prompt
- 새로운 학습이 아니라 모델에 몇 가지 예시를 제공해서 특정 작업을 수행하도록 유도하는 기법
from langchain_core.prompts import PromptTemplate
# 학습세트
examples = [
{
'question':'반려동물에는 어떤 종류가 있나요?',
'answer': '일반적으로 가장 많이 키우는 반려동물은 강아지와 고양이가 있습니다.'
},
{
'question':'지구의 자전주기는 얼마인가요?',
'answer': '지구의 자전 주기는 약 24시간 입니다.'
},
{
'question':'한국의 메이저 리거들은 모두 몇 명인가요?',
'answer': '한국에서 미국 메이저리그에 진출한 선수는 대략 5명입니다.'
},
]
# FewShotPromptTemplate 작성
from langchain_core.prompts import FewShotPromptTemplate
prompt = FewShotPromptTemplate(
examples = examples, # fewshot에 사용할 예제
example_prompt = PromptTemplate.from_template("Questoin : {question}\nAnswer : {answer}"), # 포멧팅
suffix = '질문 : {input}', # 예제 뒤에 추가될 접미사
input_variables = ["input"]
)
chain = prompt | llm | StrOutputParser()
chain.invoke({'input':'Logisticregression의 알고리즘은?'})
# FewShotPromptTemplate 기존 예제를 가지고 새로운 예제를 만들어준다.
prompt.invoke({'input':'Logisticregression의 알고리즘은?'})
# 예제 선택기
# 의미적 유사성을 기반으로 가장 관련성 높은 예제를 선택
from langchain_chroma import Chroma # 임베딩을 저장하고 검색을 수행하는 벡터데이터베이스
from langchain_core.example_selectors import SemanticSimilarityExampleSelector # 예제 중에서 주어진 문장과 가장 유사한 예제를 선택
from langchain_openai import OpenAIEmbeddings # 임베딩 벡터로 변환
example_selector = SemanticSimilarityExampleSelector.from_examples(
examples, # 예제들
OpenAIEmbeddings(), # 임베딩 모델
Chroma, # 벡터 저장소
k=1 # 가장 유사한 예제 수
)
question = '우리나라 농구선수 중에서 가장 키가 큰 선수는?'
selected_examples = example_selector.select_examples({'input':question})
print(f'예제 중에서 가장 유사한 예제:{selected_examples}')
from langchain_core.prompts import FewShotPromptTemplate, FewShotChatMessagePromptTemplate
# few-shot 프롬프팅 --> 기본 사용법은 예제가 고정되어 있다
examples = [
{"input":"근육 감소증에 비마그루맙 치료가 근육량 증가에 효과적인가요?", "output": '''근육 감소증 치료에 비마그루맙은 근육량 증가와 근육 감소증 환자의 지방량 감소를 위한 안전한 약리적 치료입니다. 하지만, 근력이나 좀 더 광범위한 신체기능 향상에 미치는 영향에 대해서는 아직 근거가 부족하여, 체성분 개선을 통한 신체기능 향상에 대한 효과는 한계가 있는 것으로 나타납니다. 점진적인 근육량과 기능 감소를 특징으로 하는 근육 감소증은 노령 인구와 만성 질환이 있는 사람들에게 상당한 어려움을 안겨줍니다. 식이 요법 및 운동 프로그램과 같은 현재의 표준 치료법은 종종 지속 불가능합니다. 근육 위축 리간드를 억제하여 근육 비대를 촉진하는 단일 클론 항체인 비마그루맙과 같은 약리학적 개입에 대한 관심이 증가하고 있으며, 비마그루맙은 근육감소증을 포함한 다양한 질환에서 효과가 있는 것으로 나타났습니다.'''},
{"input":"초콜릿 섭취는 심혈관(CVD) 위험 감소에 도움이 됩니까?", "output": "초콜릿은 주당 100g 미만 섭취 시에는 심혈관(CVD) 위험 감소에 도움이 될 수 있습니다. 하지만 더 높은 초콜릿 섭취는 이런한 심혈관 위험 감소와 관련된 건강상의 이점보다는 설탕의 높은 섭취와 관련된 부작용을 유발할 수 있습니다."},
]
example_prompt = ChatPromptTemplate.from_messages([
("human",'{input}'),
("ai","{output}")
]
)
# few-shot 프롬프트 템플릿 생성
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt,
examples=examples
)
# 최종 프롬프트 템플릿 생성
final_prompt = ChatPromptTemplate.from_messages([
("system", "당신은 상대방의 감정을 잘 이해하는 좋은 사람입니다."),
few_shot_prompt,
("human","{input}")
])
chain = final_prompt | llm | StrOutputParser()
print(chain.invoke({"input":"상대방의 호감을 사는 방법은?"}))
print(chain.invoke({"input":"심혈관을 예방하려면 어떤 식습관을 가져야하고 평소에 조심해야 할 것은?"}))
# 기본질문 응답 체인
# 간단한 질문에 답변하는 체인
# prompt + LLM
# multi chain
# 싱글체인, 시퀀스체인, 비동기처리
# 프롬프트, 쳇프롬프트, fewshot 프롬프트
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain.schema.output_parser import StrOutputParser
prompt = ChatPromptTemplate.from_template('무당처럼 얘기해줘 : {input}')
model = ChatOpenAI(model='gpt-4o-mini')
output_parser = StrOutputParser()
chain = prompt | model | output_parser
chain.invoke({'input':'오늘의 나의 운세는?'})
prompt2 = ChatPromptTemplate.from_template("{input2} 이게 나의 운세인데 핵심 단어만 추출해 줘")
chain2 = (
{"input2":chain} | prompt2 | llm | output_parser
)
print(chain2.invoke({"input":"오늘의 나의 운세는?"}))
# PDF 파일에서 텍스트 로드하고 요약 생성
from langchain.document_loaders import PyPDFLoader
loader = PyPDFLoader('/content/작업자 친화적인 실시간 불량 예측 모델 개발.pdf')
document = loader.load()
from langchain.prompts import ChatPromptTemplate
PromptTemplate(
input_variables=['page_content'],
template='다음 텍스트를 요약하세요\n{page_content}'
)
model = ChatOpenAI(model='gpt-4o-mini')
chain = prompt | model | StrOutputParser()
print(chain.invoke(document))
대회 자료를 넣고 요약해달라고 하니 다음과 같이 요약해 주었다.
어둠 속에서 진실을 찾고, 고통받는 자들에게 빛을 비추는 무당의 목소리로, 지금 이 순간 귀 기울여라.
이 프로젝트는 마치 고대의 점술가가 예언하듯, 제조 공정의 불량을 예측할 수 있는 현대의 마법, 즉 AI를 활용한 실시간 불량 예측 모델의 탄생을 이야기하고 있다. 이 모델은 2,852,465개의 데이터 속에서 숨겨진 진실을 찾고, 끊임없는 변화를 필요로 하는 제조업의 세계에 새로운 희망을 가져다 줄 것이다.
제작진은 고백하듯, "우리는 공정에 대한 깊은 지식을 지니고 있지만, AI의 신비로움은 여전히 우리에게 두려운 존재였다"고 말한다. 그러나 그 두려움을 극복하고, 코드를 함수화하여 누구나 손쉽게 사용할 수 있도록 하여, 마침내 불량 예측의 신비를 풀어냈다. 이제는 누구나 간단히 변수만 변경함으로써 새로운 공정에 적용할 수 있는 기회를 얻게 되었다.
어두운 과거를 딛고, 이들은 XGBoost, LightGBM, CatBoost라는 세 가지의 강력한 무기를 선택하였다. 이들은 각각의 특성을 바탕으로 조화를 이루어, 마치 고대의 마법사가 다양한 원소를 조합하여 최강의 마법을 만들어내듯, 이들은 VotingClassifier라는 형태로 결합하였다. 그리하여 이 모델은 F1-score 96.5%라는 찬란한 성과를 올리며, 불량품의 발생을 사전에 예측할 수 있는 능력을 지니게 되었다.
여기서 중요한 것은, 이 모든 과정이 단순한 기술의 나열이 아닌, 제조업계의 현실을 반영한 진정한 변화를 이끌어낼 수 있는 길임을 잊지 말아야 한다는 것이다. 제조업체는 이제 AI를 통해 불량률을 감소시키고, 생산성을 높여 지속 가능한 성장의 길로 나아갈 수 있는 기회를 손에 쥐게 되었다.
모든 이가 이 신비로운 여정에 함께 할 수 있도록, 우리는 계속해서 지혜의 빛을 전하고, 공정의 문제를 해결하기 위해 나아갈 것이다. 이로써 더 밝은 미래를 향해 나아가는 길에 함께 하기를 기원한다.
웹페이지 요약
# 웹피이지
from bs4 import BeautifulSoup
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader(
"https://www.koreatimes.co.kr/www/nation/2024/11/103_385804.html"
)
document = loader.load()
contents = document[0].page_content
# contents = BeautifulSoup(contents).get_text()
# contents = contents.replace('\n','')
contents
prompt = PromptTemplate(
input_variables=['page_content'],
template='다음 텍스트를 한국어로 요점별로 요약하세요\n{page_content}'
)
model = ChatOpenAI(model='gpt-4o-mini')
chain = prompt | model | StrOutputParser()
print(chain.invoke(document))
'프로그래밍 > SK AI 캠프' 카테고리의 다른 글
윈도우 DirectX12와 WSL을 이용한 모든 GPU에서 tensorflow와 pytorch 사용하기 (1) | 2024.11.09 |
---|---|
캠프52일차 - 프롬프트 엔지니어링 응용(랭체인, RAG(검색 증강 생성)) (1) | 2024.11.08 |
캠프37일차 - 자연어 처리 기초(코러스, 문장구조 이해) (2) | 2024.10.18 |
캠프35~36일차 - 2차 팀프로젝트 (0) | 2024.10.18 |
WSL2 conda 환경에 Tensorflow2와 CUDA 연결하여 설치하기 (0) | 2024.10.13 |