Decoder > 자연어 생성 Encoder > 자연어 이해 Encoder-Decoder 같이 이용 > BART 등
LLM 의 핵심 기능은 Attention
LLM 의 핵심 기능은 Attention
LSTP 의 단점을 극복하는 LLM 의 Attention
Transformer 등장 이후 LLM 의 발전
Transformer 가 2014년에 등장한 이후 LLM 발전은 빠르게 이어지고 있다.
프롬프트 엔지니어링
LLM 에 질의하는 것을 '프롬프트 한다'라고 표현한다.
'프롬프트'는 Windows 출시 전에 DOS 에서 등장한 단어다. DOS 를 실행하면 CMD 창에 커서가 깜빡 깜빡 하는데, 이렇게 입력을 기다리는 상황을 '프롬프트'라고 한다.
LLM 의 답변은 '컴플리션'이라고 표현한다.
'프롬프트 엔지니어링'은 질문을 잘 하는 방법을 의미한다.
프롬프트 기본 원칙
프롬프트 3원칙
각종 기업들이 만든 11개 프롬프트 엔지니어링
프롬프트 기법 1 : 제로샷
원 샷 프롬프트
퓨샷 프롬프트
역할 부여 프롬프트
아
Chain Of Thought (CoT)
Tree-of-Thought
ReAct
제어 지시 Instruction Prompting
자기 피드백
출력제어
질의 최적화
RAG
Retreival Augmented Generation 검색 증강 생성 이라는 것입니다. LLM 이 응답을 생성할 때, 외부의 신뢰할 수 있는 소스를 참고해서 LLM 의 환각 문제를 극복해보자 하는 것이 RAG 였습니다.
LLM 이 답변을 할 때 참고할 수 있는 Context 를 주는 것이 RAG 라고 이해하면 되겠습니다.
Context 를 생성할 때는 Vector DB 에 저장된 것들을 활용해서 생성합니다.
GPT 할루시네이션 극복 방법
가장 처음 등장하는 방법은 '파인튜닝'입니다. 추가적인 데이터를 줘서 학습시키는 방법이죠.
두 번째 방법은 'RAG' 를 이용하는 것입니다.
세 번째 방법은 '에이전트'를 이용하는 방법입니다.
RAG 의 동작 구조
1. 문장 읽은 후 텍스트 추출 2. 텍스트 분할 3. 임베딩 (숫자로 변환) 4. Vector DB 저장 (임베딩 저장소) 5. 질문 6. 유사도 검색 7. 검색된 결과를 Context 로 LLM 에 질문
임베딩
임베딩이란 복잡한 데이터들을 'N차원'의 데이터로 변환시키는 것입니다. 기본적으로 컴퓨터는 숫자만 이해할 수 있기 때문에 숫자로 변환이 필요한데요. 컴퓨터가 활용하기 편하도록 저장한다고 이해 하시면 되겠습니다.첫 번째 원 핫 인코딩인데요. 지금 보면 각도가 45도씩 나누어져 있기 때문에 각 단어의 유사도를 확인할 수가 없습니다. 이런 이유로 차원의 개수를 비약적으로 늘려나가게 됩니다.
이런 식으로 임베딩을 하게 된다는 의미입니다. 그래서 고차원의 인코딩 데이터를 저차원의 임베딩을 합니다. 예시로는 2차원이지만, 실제로 사용되는 서비스에서는 실 세계가 워낙 고차원으로 표현되기 때문에 임베딩 결과도 고차원으로서 표현됩니다.
유사도 검색
유사도를 검색하는 방법은 굉장히 다양합니다. 두 개의 각도가 0도로 일치할 수록 유사도가 크다고 판단할 수 있습니다.
예시를 들면 위와 같습니다. Norm 이라는 증명된 공식으로 유사도를 검색해볼 수 있습니다.
10차원으로 인코딩된 두 개의 값을 코사인 유사도로 판단해보면 위와 같이 0.31이 나오는 것을 볼 수 있습니다.
RAG 처리 대표적인 라이브러리
랭체인이 대표적인 RAG 를 위한 라이브러리입니다. 랭체인의 장점은 어떠한 LLM 모델을 사용하던 동일한 인터페이스로 사용할 수 있습니다.
벡터 DB
FAISS 라는 벡터 DB를 우리는 사용합니다. 무료 벡터 DB입니다.
LLM 에 따라 임베딩 모델이 결정됨
LLM 에 따라서 LLM 이 제공해주는 임베딩 모델이 결정됩니다.
LLM 이 제공해주는 임베딩 모델의 특징 : 다국어
몸무게 별 식단 추천 서비스
import streamlit as st
from openai import OpenAI
import openai
import os
api_key = os.getenv('OPENAI_API_KEY')
openai.api_key = api_key
client = OpenAI()
def isObese( height, weight ):
idealWeight = (height - 100) * 0.85
obesity = weight / idealWeight * 100
if obesity <= 90:
return '저체중'
elif obesity <= 110:
return '정상'
elif obesity <= 120:
return '과체중'
else:
return '비만'
with st.form('myform'):
st.header('비만도')
height = st.text_input('키')
weight = st.number_input('몸무게',value=0, step=1, min_value=0, max_value=200)
# birth = st.date_input('생일')
submit = st.form_submit_button('결과')
if submit:
result = isObese(int(height), int(weight))
s = f'키:{height} 몸무게:{weight} 결과:{result}'
st.write( s )
if result == '저체중':
st.image('./under.png')
elif result == '정상':
st.image('./normal.png')
elif result == '과체중':
st.image('./over.png')
elif result == '비만':
st.image('./obese.png')
completion = client.chat.completions.create(model="gpt-3.5-turbo",
messages=[
{'role':'system', 'content':'PT 선생님이야. 헬스장에서 회원의 건강을 관리해. 회원의 건강 관리를 위해 강하게 식단을 강조해줘.'},
{'role':'user','content': f'지금 회원 정보를 알려줄게. 키 {height} 몸무게 {weight} 비만도는 {s}야. 이 사람의 건강 유지를 위해 아침, 점심, 저녁 식단을 추천해줘'}] )
st.write(completion.choices[0].message.content)