YETI DOCS

Chatbot

송성근
2023년 2월 14일
프로젝트의 목표인 대화하는 듯한 느낌을 주기 위해서, 또 지금 가지고 있는 자원을 이용하여 현실적으로 개발을 진행하기 위해서 아래와 같은 조건이 필요합니다.

기능

  • 한국어 작업을 충분히 잘 처리해야 합니다.
  • 사람과 같은(상대방에 공감하는) 대화가 가능해야 합니다.
  • 챗봇에게 특정 상황과 페르소나를 부여할 수 있어야 합니다.

자원

  • 추론 시간이 충분히 짧아야 합니다.
  • 모델 크기가 너무 크지 않아야 합니다.

Architecture 🏗️

아키텍처 그림그림
좋은 성능을 내기 위한 방법으로 여러 모델을 조합하는 구조를 생각해 보았습니다.
  • 적절한 응답을 생성하기 위해 문장을 벡터로 만드는 Retrieval Model
  • 프롬프트로 적절한 응답을 생성하는 Generative Model
  • 기존의 내용을 통해 요약을 생성하는 Summarizer Model
적절한 응답을 생성하기 위해 총 세 가지 모델을 계획하였습니다. 모든 모델을 직접 학습하기에 시간이 부족하여 이미 학습된 모델을 적절하게 배치하여 프로젝트 마감 기한에 맞추며 성능을 최대화 하려 합니다.

Retrieval Model 🔎

들어온 요청에 대한 관련된 문구를 검색하기 위해 한국어로 학습된 모델이 필요합니다. 여기 site preview image 에서 한국어로 학습된 모델들의 정보를 볼 수 있습니다. 해당 레포에서 bert-base, roberta-base 모델을 KorNLI, KorSTS 데이터셋을 활용하여 학습을 진행하였다고 합니다.
NLI(Natural Language Inference)는 한 쌍의 문장의 관계가 entailment, contradiction, neutral 중 어느 것인지 판단하는 작업입니다. STS(Semantic Textual Similarity)는 두 문장 사이의 유사성을 점수로 분류하는 작업이죠 두 가지 데이터셋은 문제가 있습니다. 모두 짧은 문장으로 구성되어 있습니다. 그래서 긴 문장에 대한 정보를 벡터로 만드는 것에 한계가 있죠.
이러한 문제를 해결하고자 유저의 회고를 작은 크기의 몇 문장으로 자를 것입니다. 대화의 형식을 지향하기 때문에 사용자의 요청도 길지 않을 것이고요. 이러한 상태에서 검색을 통해 회고에서 관련한 문장을 찾을 것입니다. 또 찾은 문장에서 문맥을 이해하기 위해 해당 문장의 앞뒤 일정 범위를 함께 문구로 가져오는 방식을 채택할 것입니다.
전 / 후 비교 사진과 설명

Generative Model 🤖

좋은 답변을 생성하기 위해 이미 거대 모델로 서비스 중인 OpenAI의 GPT 3.5를 사용할 생각입니다. 물론 이를 활용하면 서비스를 제공하는 입장에서 사용자가 늘어날 때 마다 발생하는 비용이 커지는 문제가 생기죠. 따라서 적당한 규모의 언어 모델을 직접 Fine-Tuning하여 이를 대체할 예정입니다. 그 전에 Phase 1, GPT 3.5를 이용하여 적절한 성능을 낼 수 있는 Prompt와 모델 구조를 찾아내고 말이죠.
대화를 하는 듯한 느낌을 주기 위해서 응답을 생성하는데 걸리는 시간이 너무 길지 않아야 합니다. 하지만 GPT의 생성 속도를 보면 길게는 수 초에 이르는 것을 볼 수 있죠. 이러한 방식으로 대화를 진행하는 듯한 느낌을 줄 수 없을 것입니다.
그런데 GPT가 생성한 응답을 보면 한 문장이 아닌 경우가 많습니다. 따라서 응답이 모두 완성되면 전달하는 것이 아닌, 하나의 문장이 완성될 때마다 전달하는 방식으로 딜레이를 줄일 수 있겠습니다.
대충 흐름 설명

Persona 🎭

좋은 응답을 생성하기 위해 좋은 정보를 함께 넣어주어야 합니다. 어떠한 방법으로 정보를 넣어주면 어떠한 응답이 생성될지 여러 테스트를 진행할 것입니다.

Summarizer Model 📝

대화의 형식으로 진행을 하기 위해서 이전까지 어떠한 대화를 나눴는지 알려줄 필요가 있습니다. 하지만 기존의 대화 내용을 모두 넣는 것은 프롬프트의 길이가 길어지는 문제를 발생시키죠. 따라서 Facebook의 BlenderBot의 방식대로 지금까지 대화를 요약한 상태로 가지고 요청이 들어오면 요청과 함께 응답을 생성하는데 요약을 사용할 계획입니다.
대화 요약 모듈 변천사
BlenderBot 2 논문 리뷰하고 링크 넣을거임!

Flow 🔀

  1. 요청(query)이 들어오면 검색기(Retriever)에 보내 이를 벡터화하여 DB의 사용자가 사전에 입력한 자신에 대한 회고에서 관련된 문구(context)를 검색합니다.
  2. 요청과 문구를 프롬프트로 감싸 생성기(Generator)에 보내 적절한 응답을 생성합니다.
  3. 요청과 생성된 문구를 요약기(Summarizer)에 주어 적절한 요약을 생성합니다.
  4. 1번의 내용을 다시 실행합니다.
  5. 요청과 문구와 요약을 프롬프트로 감싸 생성기에 보내 적절한 응답을 생성합니다.
  6. 3-5번의 내용을 반복합니다.

Phase 2 📍

모델 선정

너무 큰 규모의 모델을 사용하기에 GPU 자원이 부족하고 추론 시간이 오래 걸립니다. 따라서 어느 정도 타협하여 모델을 선정해야 하죠.
여러 Benchmark에서 높은 점수를 달성한 LLaMA2, Mistral 등의 가장 작은 사이즈는 7B로 float16 연산을 이용해도 12GB GPU에서는 부족합니다. 또한 한국어 작업을 처리할 때 사람이 보기에 어색한 답변이 생성되는 것을 볼 수 있죠. 조금 더 작은 규모의 한국어 처리에 뛰어난 성능을 보이는 모델이 필요할 것 같습니다.

해결해야 할 문제

둘은 trade-off 관계
기존 서비스를 진행하는 ChatGPT API를 활용하여 응답을 생성하기에는 Latency가 너무 크다.