목표
gpt stream 공부
공부
이전 글에 이어서, 캐릭터의 대사를 뽑아주는 경우에는
"조금 더 생동감을 높이기 위해 GPT가 응답을 주는대로 받아오는 것이 좋지 않을까"
해서 고민하게 되었다.
찾아보니 GPT에는 스트리밍이 기본적으로 가능하더라.
openai.ChatCompletion.create(
model=GPT_MODEL_ENGINE,
messages=messages,
stream=True,
)
단순하게 맨 밑에 stream=True만 해주면 스트리밍이 가능한데,
이렇게 하면 GPT의 응답이 generator 형태로 제공되어, 반복해서 값을 넘겨줘야 한다.
여기에 웹 소켓으로 실시간 전송을 해준다면, 내가 원하는대로 GPT의 응답이 올 때마다 값을 받아서, 클라이언트가 아무 화면도 못 보는 채로 대기하는 일이 없다.
여기까지는 굉장히 쉽게 했는데, 이 값들을 반복자를 이용해서 어떻게 넘겨줘야할지 감이 오지 않았다.
response 값을 어떻게 받아서 선택해야할지 몰라서,
우선 response = next(stream)을 통해 response에 다음 객체를 담아주고,
print문으로 response값을 확인해보았다.
{
"id": "",
"object": "",
"created": ,
"model": "",
"system_fingerprint": "",
"choices":
[
{
"index": ,
"delta": {
"role": "",
"content": ""
},
"logprobs": ,
"finish_reason":
}
]
}
음 뭐 대충 이런 형태가 나오더라
그러면 어떻게 뽑아내야 result 값으로 넘겨줄 수 있을까?
response = next(stream)
result = response.choices[0]['delta']['content'].strip()
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
'group_name',
{
'type': '',
'message': result,
}
)
대충 이렇게 넣어봤다. 과연 될까?
전송은됐다.
근데 진짜 전송만 됐다.. 가장 큰 문제는 한 번만 보내지는 현상이다. 매우 당연하다.
아까 말했든 반복자를 통해 계속해서 보내줘야하는데 한 번만 보내고 있으니 그냥 빈 값만 들어가고 끝난다.
수정해서 반복을 통해 연속적으로 보내보자.
for response in stream:
if 'delta' in response.choices[0] and 'content' in response.choices[0]['delta']:
result = response.choices[0]['delta']['content'].strip()
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
'group_name',
{
'type': '',
'message': result,
}
)
이렇게 하니 성공했다.
여기서 살짝 삽질한 부분은, 어쨌든 계속 next 값을 찾기 때문에, 종료 조건을 주지 않으면 안되더라.
if 'delta' in response.choices[0] and 'content' in response.choices[0]['delta']:
해당 코드 없이 진행하니, 마지막에 delta가 빈 값이 생겨서, content가 없다며 오류가 발생했다.
꼭 체크하길 바란다.
마치며
아무튼 이런식으로 해서 얼추 스트리밍까지 구현한 것 같다.
정말 많은 삽질이 있었지만, 그만큼 많이 찾아보고 공부가 됐다는 것에 의의를 두기로 했다.
앞으로 주 개발은 spring boot로 할 것이지만, 참여하고 있는 프로젝트에서 장고를 쓰는 만큼 다른 언어도 좀 공부하면서 시야를 넓혀야겠다.