공개된 한글 챗봇 데이터와 pre-trained KoGPT2를 이용하여 간단한 대화를 나눌 수 있는 챗봇 모델이 등장하였습니다! 이를 활용하여 ainize의 GPU 환경에서 opyrator로 챗봇 프로토타입 컴컴이
을 만들었습니다.
-
한글 챗봇 데이터
인공데이터로 주로 사랑과 이별에 관한 내용입니다. 그 덕분에 챗봇은 연애상담에 최적화되어 있습니다. 그리고 감정상태에 따라 라벨링되어있습니다. 내용이 일상다반사라면 0, 이별(부정)라면 1, 사랑(긍정)은 2로 라벨을 표시합니다.
-
KoGPT2
GPT-2는 주어진 텍스트의 다음 단어를 예측하기에 적합한 학습 언어 모델이며 문장 생성에 최적화되어있습니다. KoGPT2는 GPT2의 부족한 한국어 성능을 극복하기 위해 40GB 이상의 텍스트로 학습된 한국어 디코더 모델입니다.
-
Tokenizer
기본적으로 tokenizers 패키지의 Character BPE tokenizer를 사용합니다.
from transformers import PreTrainedTokenizerFast
U_TKN = '<usr>'
S_TKN = '<sys>'
BOS = '</s>'
EOS = '</s>'
MASK = '<unused0>'
SENT = '<unused1>'
PAD = '<pad>'
TOKENIZER = PreTrainedTokenizerFast.from_pretrained("skt/kogpt2-base-v2",
bos_token=BOS, eos_token=EOS, unk_token='<unk>',
pad_token=PAD, mask_token=MASK
위와 같은 아키텍처를 통해 유저의 발화에 따른 챗봇의 응답을 생성할 수 있습니다.
- <usr> : 데이터의 Q필드(사용자의 발화)
- <sent> : 감정 라벨
- <sys> : 데이터의 A필드(챗봇의 응답)
각각의 데이터 필드에 매핑하여 **P(<sys> | <usr>, <sent>)**의 값이 최대가 되는, 즉 이전 내용과 감정 폭을 기반으로 가장 가능성이 높게 도출될 수 있는 <sys>가 챗봇의 응답이 되도록 합니다.
간단한 설명을 위해 argument parsing, 구체적인 클래스 메소드는 생략하였습니다. CharDataset 클래스에서 csv 데이터의 Q필드, label필드, A필드를 추출하여 토큰화합니다. 이를 기반으로 KoGPT2Chat에서 트레이닝을 하고 model_chp/model_-last.ckpt
에 트레이닝된 모델을 저장합니다. 더욱 자세히 트레이닝 메소드에 알고 싶다면 여기를 참고해주세요.
import numpy as np
import pandas as pd
import torch
from pytorch_lightning import Trainer
from pytorch_lightning.callbacks import ModelCheckpoint
from pytorch_lightning.core.lightning import LightningModule
from torch.utils.data import DataLoader, Dataset
from transformers.optimization import AdamW, get_cosine_schedule_with_warmup
from transformers import PreTrainedTokenizerFast, GPT2LMHeadModel
class CharDataset(Dataset):
def __init__(self, chats, max_len=32):
self._data = chats # 학습 데이터(csv)
self.first = True
self.q_token = U_TKN # <usr>
self.a_token = S_TKN # <sys>
self.sent_token = SENT # <sent>
self.bos = BOS # </s>
self.eos = EOS # </s>
self.mask = MASK # 이모티콘
self.pad = PAD
self.max_len = max_len
self.tokenizer = TOKENIZER
class KoGPT2Chat(LightningModule):
def __init__(self, hparams, **kwargs):
super(KoGPT2Chat, self).__init__()
self.hparams = hparams
self.neg = -1e18
self.kogpt2 = GPT2LMHeadModel.from_pretrained('skt/kogpt2-base-v2')
self.loss_function = torch.nn.CrossEntropyLoss(reduction='none')
트레이닝을 하기 위해 모든 코드를 이해해야할 필요는 없습니다. Colab을 통해 간단하게 트레이닝을 할 수 있도록 안내되어있습니다. 직접 코드를 수정하여 gpus, max_epochs 등 트레이닝 옵션을 자유롭게 부여하며 모델 학습을 진행할 수 있습니다. 저는 colab에 주어진 max_epochs보다 약간 높게 부여하여 더욱 주어진 데이터를 중점적으로 학습하도록 하였습니다.
위 과정을 거쳐 모델을 생성하였고, opyrator를 이용해 유저가 컴컴이에게 말을 걸면 컴컴이가 답하는 구조의 사이트를 간단하게 생성하였습니다. 더 자세한 opyrator를 사용 방식이 궁금하시다면 여기를 참고해주세요
[app.py]
from model import User, Comcom, KoGPT2Chat
def chatbot(input : User)->Comcom :
"""심심할 때 컴컴이와 대화해보세요."""
model = KoGPT2Chat.load_from_checkpoint('model_chp/model_-last.ckpt')
text = input.user
return Comcom(comcom = model.chat(text = text.strip()))
[model.py]
# 상단의 class 외에 아래와 같이 input, output class 추가
class User(BaseModel):
user : str = Field(
...,
title = "User",
max_length = 20
)
class Comcom(BaseModel):
comcom : str
심심하시다구요? 여기에서 컴컴이와 대화해보세요!