Deep Learning (TF, Keras, PyTorch)/Natural Language Processing

[LangChain] OpenAI Chat Model 의 인풋 메시지, 프롬프트

Rfriend 2024. 1. 8. 16:41

OpenAI의 프레임워크에서 "대규모 언어 모델(Large Language Model, LLM)"과 "챗 모델(Chat Model)"이라는 용어는 언어 모델의 두 가지 다른 측면이나 구현을 나타냅니다.  


1. LLM (Large Language Model) 

- 일반 설명: LLM은 OpenAI가 개발한 GPT-3나 GPT-4와 같은 대규모 언어 모델을 가리키는 광범위한 용어입니다. 이 모델들은 인간과 유사한 텍스트를 이해하고 생성할 수 있게 해주는 많은 수의 파라미터로 특징지어집니다. 

- 기능: LLM은 다양한 인터넷 텍스트로 훈련됩니다. 따라서 번역, 요약, 질문 답변 등 다양한 언어 작업을 수행할 수 있습니다. 

- 유연성: 이 모델들은 대화 작업을 위해 특별히 조정되지 않았습니다. 대신, 챗봇을 포함하여 다양한 애플리케이션에 적용될 수 있는 범용 모델입니다. 또한 콘텐츠 생성, 코딩 지원 등 다른 분야에도 확장됩니다. 

- 훈련 데이터: 이 모델들의 훈련 데이터는 인터넷에서 다양한 텍스트 소스를 포함하며, 언어, 맥락, 지식에 대한 광범위한 이해를 제공합니다. 


2. Chat Model

- 특징: 현재 여러분이 상호작용하고 있는 챗 모델처럼, 챗 모델은 대화 작업에 특화된 대규모 언어 모델의 더 전문화된 구현입니다. 

- 기능: 대화 참여, 질문 답변, 작업 지원, 그리고 여러 차례에 걸쳐 일관되고 맥락을 인식하는 대화를 유지(maintain a coherent and context-aware conversation over multiple turns)하는 데에 설계되었습니다.

- 훈련 및 조정: 일반 대규모 언어 모델을 기반으로 하지만, 대화적인 맥락에서 뛰어난 성능을 발휘하기 위해 추가적인 훈련이나 조정을 거칩니다. 이는 대화 데이터셋에 대한 훈련이나 대화에서의 성능을 개선하기 위한 강화 학습 기법을 사용할 수 있습니다. 

- 사용자 경험: 사용자 친화적이고 매력적인 대화 경험을 제공하는 데 중점을 둡니다. 종종 적절하고 맥락에 맞는 응답을 보장하기 위한 추가적인 안전장치나 지침이 포함됩니다. 


요약하자면, LLM은 다양한 언어 작업을 수행할 수 있는 범용 대규모 언어 모델인 반면, Chat Model은 대화 상호작용 및 대화에 최적화된 LLM의 특화된 버전(maintain a coherent and context-aware conversation over multiple turns)입니다. 

 

 

이번 포스팅에서는 LangChain으로 OpenAI의 ChatModel을 활용한 챗봇을 만들 때 인풋 메시지를 작성하는 방법을 소개하겠습니다. 

 

(1) SystemMessage(), HumanMessage()를 이용한 Messages 작성

(2) ChatPromptTemplate과 format_prompt()를 이용한 Formatted Prompts 작성

(3) ChatPromptTemplate 를 이용한 Formatted Prompts 작성

 

 

LangChain - OpenAI ChatModel - Messages

 

 

먼저 터미널에서 pip install 로 openai, langchain을 설치합니다. 

 

! pip install openai langchain

 

 

Prompt 작성과 Chat Model에 필요한 모듈을 importing 하고, 환경변수에 OpenAI API Key를 설정해줍니다. 

 

import os

from langchain.prompts import (
    ChatPromptTemplate, 
    SystemMessagePromptTemplate, 
    HumanMessagePromptTemplate,
)
from langchain.schema import SystemMessage, HumanMessage
from langchain.chat_models import ChatOpenAI

# set OpenAI API Key in your environment variables
os.environ["OPENAI_API_KEY"]="sk-xxxx..."

 

 

 

(1) SystemMessage(), HumanMessage()를 이용한 Messages 작성

 

Chat Model로는 OpenAI의 GPT-4 버전을 사용하겠습니다. 

 

# Chat Model
model = ChatOpenAI(temperature=0, model="gpt-4")

 

 

 

LangChain의 ChatModels 는 SystemMessage, HumanMessage, AIMessage의 3가지 종류의 메시지 클래스를 제공합니다. 

 

- (a) SystemMessage: 시스템 컴포넌트로부터의 메시지로, ChatModel에게 페르소나, 역할 설정.

- (b) HumanMessage: 사용자로부터의 메시지로, ChatModel에게 작업을 시키는 인풋 메시지.

- (c) AIMessage: AI 모델로부터의 메시지로, SystemMessage와 HumanMessage를 인풋으로 받아 아웃풋으로 반환하는 메시지 

 

 

아래 예에서는 langchain.schema 에서 SystemMessage, HumanMessage를 importing하여 리스트로 두 메시지를 묶어서 Chat Model 에 인풋으로 넣어주면 됩니다. 

 

Formatted message가 아닌 일반 메시지를 인풋으로 넣을 때 바로 사용할 수 있어서 편리합니다. 

 

# System, Human Messages
# Chat models accept List[BaseMessage] as inputs, 
# or objects which can be coerced to messages, 
# including str (converted to HumanMessage) and PromptValue.
messages = [
    SystemMessage(
        content="You are a helpful assisant that translate English to Korean."
    ), 
    HumanMessage(
        content="Translate this sentence from English to Korean: I love programming."
    ), 
]


model.invoke(messages)
# AIMessage(content='나는 프로그래밍을 사랑한다.')

 

 

 

(2) ChatPromptTemplate과 format_prompt()를 이용한 Formatted Prompts 작성

 

이번에는 Prompt 메시지의 내용을 기본 뼈대의 Template을 만들어놓고, Chat Model을 실행시킬 때 사용자가 맞춤형으로 Prompt의 일부 부분을 인풋으로 넣어주어 Formatted prompts 를 만들어 최종 Chat Model을 실행시킬 때 사용하는 ChatPromptTemplate을 소개하겠습니다. 

 

아래 Template 작성 예에서는 System template에서 {input_language}, {output_language} 부분, 그리고 Human template의 {text} 부분이 나중에 사용자가 최종 입력하는 값에 따라 입력이 되어서 최종 Formatted prompt 가 작성되는 방식입니다. 

 

먼저, System template, Human template을 만들고, 

 

# You can make use of templating by using a MessagePromptTemplate
# (a) System Message
system_template = """
You are a helpful assistant that translate {input_language} to {output_language}"""
system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)


# (b) Human Message
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)

 

 

다음으로 ChatPromptTemplate.from_messages([템플릿 리스트...]) 를 사용하여 Chat Prompt를 만듭니다. 

 

# You can build a ChatPromptTemplate from one or more MessagePromptTemplates.
chat_prompt = ChatPromptTemplate.from_messages(
    [system_message_prompt, human_message_prompt]
)

 

 

마지막으로, chat_prompt.format_prompt() 에서 아래처럼 사용자 인풋에 해당하는 변수 별 값을 입력해주면 ChatPromptValue()를 반환합니다. 

 

# ChatPromptTemplate’s format_prompt – this returns a PromptValue, 
# which you can convert to a string or Message object, 
# depending on whether you want to use the formatted value as input to an llm or chat model.
chat_prompt.format_prompt(
    input_language="English", 
    output_language="Korean",
    text="I love programming.")

# ChatPromptValue(messages=[
# SystemMessage(content='\nYou are a helpful assistant that translate English to Korean'), 
# HumanMessage(content='I love programming.')])

 

 

chat_prompt.format_prompt().to_messages() 를 뒤에 붙여주면 [SystemMessage, HumanMessage]를 반환합니다. --> 다음 단계에서 ChatModel에 인풋으로 넣어줍니다. 

 

# to_messages()
chat_prompt.format_prompt(
    input_language="English", 
    output_language="Korean",
    text="I love programming.").to_messages()

# [SystemMessage(content='\nYou are a helpful assistant that translate English to Korean'),
#  HumanMessage(content='I love programming.')]

 

 

ChatModel 에 위에서 작성한 [SystemMessage, HumanMessage] 를 인풋으로 넣어 invoke()로 실행시킵니다. 

 

# Get a chat completion from the formatted messages
model.invoke(
    chat_prompt.format_prompt(
        input_language="English", 
        output_language="Korean",
        text="I love programming.").to_messages()
)

# AIMessage(content='나는 프로그래밍을 사랑한다.')

 

 

 

 

(3) ChatPromptTemplate 를 이용한 Formatted Prompts 작성

 

위의 (2)번 방법이 Formatted Prompts를 작성하는 방법이었는데요, 코드가 길고 좀 복잡한 면이 있습니다. 이번의 (3)번 방법은 보다 직관적이고 코드도 간결해서 사용하기에 상대적으로 편리합니다. 

 

ChatPromptTemplate.from_messages([("system", "Message..."), ("human", "Message...")]) 로 Chat Prompts 를 작성해줍니다. 

 

# Chat Prompts
final_prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a helpful assistant that translate {input_language} to {output_language}"), 
        ("human", "{text}")
    ]
)

 

 

'|'로 Prompt와 Chat Model을 Chaining 해주고, invoke({"인풋변수": "인풋 값"}) 형식으로 딕션어리에 키:값 쌍으로 입력해주면 됩니다. (2)번 방법보다 상대적으로 직관적이어서 이해하기 쉽습니다. 

 

# Chainning using '|' operator
chain = final_prompt | model


# Invoke a chain
chain.invoke({
    "input_language": "English", 
    "output_language": "Korean", 
    "text": "I love programming."}
)

# AIMessage(content='나는 프로그래밍을 사랑한다.')

 

 

[ Reference ]

- LangChain - ChatOpenAI: https://python.langchain.com/docs/integrations/chat/openai

 

 

이번 포스팅이 많은 도움이 되었기를 바랍니다. 

행복한 데이터 과학자 되세요!  :-)

 

728x90
반응형