본문 바로가기

연구 과제 (끝나면 해당 카테고리로 이동)

ChatBot(챗봇) 만들어보기

728x90
반응형

# 챗봇을 만들어보자.

skt/kogpt2-base-v2 라는 한국어 모델을 활용해서 데이터를 학습 시켜보고 챗 봇을 만들어보자.

 

음 일단 학습을 시키기엔 내 노트북이 사양이 좋지 않으니, 학습 데이터 양을 조절해서 진행을 해야한다.

학습 데이터의 양은 약 700개 정도이다. 원래 학습 해야할 데이터 셋의 약 10%정도를 학습을 시켜서 챗봇을 만들어 보고자 한다. 700개 학습 시키는데도 30분정도가 걸린다...

 

1. 데이터 셋 준비

일단 데이터 셋을 준비 해야 하는데, 인터넷에서 잠시 찾아보면 쉽게 찾을 수 있다.

예를들면 캐글에서 챗봇 데이터를 찾는다면 아래와 같이 쉽게 찾을수 있다. 이외에도 데이터는 많다. 깃헙만 가봐도 많이 찾을수 있다.

https://www.kaggle.com/code/pinooxd/gpt2-chatbot

 

gpt2-chatbot

Explore and run machine learning code with Kaggle Notebooks | Using data from No attached data sources

www.kaggle.com

2. 학습 코드 작성

데이터 셋이 준비 되었으면, 학습 코드를 작성하면 된다.

파이썬 코드는 아래와 같다.

chatbot-train.py

import pandas as pd
from transformers import PreTrainedTokenizerFast, GPT2LMHeadModel, Trainer, TrainingArguments
import torch
import os
import shutil

# 데이터셋 경로
dataset_path = r'C:\Users\김승현\Documents\dataset\train\Question_pair\kor_Pair_test.csv'

# 데이터셋 로드
df = pd.read_csv(dataset_path)

# 토크나이저 및 모델 로드
try:
    tokenizer = PreTrainedTokenizerFast.from_pretrained(
        'skt/kogpt2-base-v2',
        bos_token='</s>', eos_token='</s>', unk_token='<unk>',
        pad_token='<pad>', mask_token='<mask>'
    )
    model = GPT2LMHeadModel.from_pretrained('skt/kogpt2-base-v2')
except Exception as e:
    print(f"Error loading model: {e}")
    # Clear the cache and try again
    model_cache_dir = os.path.join(os.path.expanduser("~"), ".cache", "huggingface", "transformers")
    if os.path.exists(model_cache_dir):
        shutil.rmtree(model_cache_dir)
    tokenizer = PreTrainedTokenizerFast.from_pretrained(
        'skt/kogpt2-base-v2',
        bos_token='</s>', eos_token='</s>', unk_token='<unk>',
        pad_token='<pad>', mask_token='<mask>'
    )
    model = GPT2LMHeadModel.from_pretrained('skt/kogpt2-base-v2')

# Set pad_token
tokenizer.pad_token = tokenizer.eos_token


# 데이터셋 전처리
def preprocess_function(examples):
    inputs = tokenizer(examples['question1'], examples['question2'], truncation=True, padding='max_length',
                       max_length=128)
    inputs['labels'] = inputs['input_ids'].copy()
    return inputs


# 데이터셋을 Hugging Face의 Dataset 객체로 변환
from datasets import Dataset

dataset = Dataset.from_pandas(df)
tokenized_dataset = dataset.map(preprocess_function, batched=True)

# 학습 인자 설정
training_args = TrainingArguments(
    output_dir='./results',
    num_train_epochs=3,
    per_device_train_batch_size=4,
    save_steps=10_000,
    save_total_limit=2,
)

# Trainer 설정
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_dataset,
)

# 모델 학습
trainer.train()

chatbot-interface.py

# app.py
from flask import Flask, request, jsonify
from transformers import PreTrainedTokenizerFast, GPT2LMHeadModel
import torch

app = Flask(__name__)

# 모델과 토크나이저 로드
model = GPT2LMHeadModel.from_pretrained('skt/kogpt2-base-v2')
tokenizer = PreTrainedTokenizerFast.from_pretrained('skt/kogpt2-base-v2')

# 모델과 토크나이저 저장
model.save_pretrained('./results')
tokenizer.save_pretrained('./results')

# 모델과 토크나이저 다시 로드
tokenizer = PreTrainedTokenizerFast.from_pretrained('./results')
model = GPT2LMHeadModel.from_pretrained('./results')

@app.route('/chat', methods=['POST'])
def chat():
    user_input = request.json.get('message')
    input_ids = tokenizer.encode(user_input, return_tensors='pt')
    gen_ids = model.generate(input_ids,
                             max_length=128,
                             repetition_penalty=2.0,
                             pad_token_id=tokenizer.pad_token_id,
                             eos_token_id=tokenizer.eos_token_id,
                             bos_token_id=tokenizer.bos_token_id,
                             use_cache=True)
    generated = tokenizer.decode(gen_ids[0])
    generated = generated.replace('\n', ' ')  # 줄바꿈 문자를 공백으로 대체
    return jsonify({'response': generated})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

결과는 아래와 같다. 학습한 내용이 나오는거 같은데, 소설처럼 표현해준다.

3. 자세히 남겨보면 아래와 같다.

응답이 좀 느리고, 너무 소설같은 대답을 하는거 외엔 음 흥미롭긴 하다.

 

나만의 데이터를 학습 시키고 관련 정보를 받을수 있으면 좋겠는데...

 

- 끝 -

728x90
반응형