반응형
이전에 chatGPT를 API를 이용해서 Discord bot 을 구현 했습니다.
아래 참조
https://yongeekd01.tistory.com/193
생각해보니 채팅을 무한히 반복하면 토큰수가 초과되어 세션에 문제가 생기는걸 깜빡 했습니다.
그부분을 해결해 보겠습니다.
대화를 계속 누적해서 보내다 보니 생길 수 밖에 없는 문제겠네요.
openai에서 제공하는 tiktoken을 이용해서 해결해 보겠습니다.
tiktoken은 OpenAI에서 제공하는 토큰화 패키지로, 텍스트를 모델에서 처리할 수 있는 토큰 형태로 변환하는 데 사용됩니다.
텍스트를 모델 입력으로 제공하기 전에 해당 텍스트를 모델이 이해할 수 있는 형식으로 변환하는 과정이라고 볼수 있습니다.
1. tiktoken을 사용해서 토큰 수 계산
먼저 tiktoken을 설치 합니다.
pip3 install tiktoken
단순히 문자열을 토큰으로 변환 했을때 토큰 수만 세보려면 다음과 같이 하면 됩니다.
import tiktoken
# 원하는 롬과 코덱을 선택 (여기서는 기본 gpt-4 코덱을 사용)
encoding = tiktoken.encoding_for_model("gpt-4")
# 텍스트를 토큰으로 변환
text = "너는 프로그래머야. 질문의 대답 찾기 위한 파이썬 코딩을 하고 그 코드에 대해서 자세히 설명해줘"
tokens = encoding.encode(text)
print(f"Tokens:", tokens, f" {len(tokens)}")
# 토큰을 다시 텍스트로 변환
original_text = encoding.decode(tokens)
print("Original Text:", original_text)
2. 코드 수정하기
API 사용시 돈문제도 있으니까 ^^ 4K 정도의 90%가 차면 문자열을 누적하는 리스트를 초기화 하는 부분을 추가하도록 하겠습니다.
import discord
import os
from openai import OpenAI
import tiktoken
discord_bot_token = os.environ.get('DISCORD_BOT_TOKEN')
openai_api_key = os.environ.get('OPENAI_API_KEY')
channel_id = '자신의 채널 아이디' #채널에 오른쪽 버튼 누르면 보입니다.
#history_messages = [{"role": "system", "content": "너는 똑똑한 helper"}]
class MyClient(discord.Client):
tokens = 0 #토큰 수 누적 변수
history_messages = [{"role": "system", "content": "너는 똑똑한 helper"}]
async def on_ready(self):
print(f'Logged on as {self.user}!')
channel = client.get_channel(int(channel_id))
await channel.send("난똑똑해! 무엇이든 물어봐~~")
async def on_message(self, message):
if message.author == client.user:
#봇자신이 보낸건 처리하지 않기
print(f'Message from me {message.author}: {message.content}')
return
print(f"current tokens = {self.tokens}")
#system role 빼고 대충 4K, 90%정도 되면 지우기
if self.tokens > int(4096 * 0.9) :
print(f"tokens limit! clear list {self.tokens}")
self.history_messages = self.history_messages[:1] # 첫 번째 system role 항목만 남기고 나머지 삭제
self.tokens = 0
#이전 대화에 현재 질문 추가하기
self.history_messages.append({"role": "user", "content": f"{message.content}"})
self.tokens += len(encoding.encode(message.content)) #토큰 수 갱신
completion = chatClient.chat.completions.create(
model="gpt-4o",
messages = self.history_messages
)
#chatgpt응답을 assistant role로 다시 전달하기 위해 저장
response = {"role": "assistant", "content": f"{completion.choices[0].message.content}"}
self.history_messages.append(response)
self.tokens += len(encoding.encode(completion.choices[0].message.content)) #토큰 수 갱신
#실제 질문 답변
answer = completion.choices[0].message.content
#print(response)
print(answer)
await message.channel.send(answer)
chatClient = OpenAI()
encoding = tiktoken.encoding_for_model("gpt-4") # 원하는 코덱을 선택 (여기서는 기본 gpt-4 코덱을 사용)
intents = discord.Intents.default()
intents.message_content = True
client = MyClient(intents=intents)
client.run(discord_bot_token)
자 이제 토큰 제한을 어느정도는 해결 할 수 있겠네요
반응형
'IT > 개발' 카테고리의 다른 글
vlc를 이용해서 동영상 파일을 rtsp 스트림으로 전송하기 (0) | 2024.07.11 |
---|---|
google Gemma 2 개요 및 간단 테스트 (0) | 2024.07.01 |
chatGPT를 discord bot으로 만들어보자(초간단, 대화기억, chatGPT-4o) (0) | 2024.06.18 |
pytorch openpose를 사용해보자(초간단, yolov9 연동 결과) (1) | 2024.06.14 |
paddle OCR을 이용해서 문자 인식 해보기(easy OCR과 결과 비교) (0) | 2024.06.10 |