목차
KoGPT2 학습방식 개요 - 저는 주로 ver.1을 다루고 다른 팀원이 ver.2를 다뤘다. '기업설명, 슬로건'으로 이루어진 문장이 여럿 들어가는 거와 기업설명, 슬로건을 나눠서 학습시키는 것과 차이가 커보이지는 않는데 ver.2의 경우 성능이 좋지 않았다. 아마 코드가 영어슬로건 생성에 맞춰진 거라서 그렇지 않을까 싶다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
from transformers import TextDataset, DataCollatorForLanguageModeling
from transformers import GPT2LMHeadModel
from transformers import Trainer, TrainingArguments
from transformers import PreTrainedTokenizerFast
def load_dataset(file_path, tokenizer, block_size = 128):
dataset = TextDataset(
tokenizer = tokenizer,
file_path = file_path,
block_size = block_size,
)
return dataset
def load_data_collator(tokenizer, mlm = False):
data_collator = DataCollatorForLanguageModeling(
tokenizer=tokenizer,
mlm=mlm,
)
return data_collator
def train(train_file_path,model_name,
output_dir,
overwrite_output_dir,
per_device_train_batch_size,
num_train_epochs,
save_steps):
tokenizer = PreTrainedTokenizerFast.from_pretrained(model_name,
bos_token='</s>', eos_token='</s>', unk_token='<unk>',
pad_token='<pad>', mask_token='<mask>')
train_dataset = load_dataset(train_file_path, tokenizer)
data_collator = load_data_collator(tokenizer)
tokenizer.save_pretrained(output_dir, legacy_format=False)
model = GPT2LMHeadModel.from_pretrained(model_name)
model.save_pretrained(output_dir)
training_args = TrainingArguments(
output_dir=output_dir,
overwrite_output_dir=overwrite_output_dir,
per_device_train_batch_size=per_device_train_batch_size,
num_train_epochs=num_train_epochs,
)
trainer = Trainer(
model=model,
args=training_args,
data_collator=data_collator,
train_dataset=train_dataset,
)
trainer.train()
trainer.save_model()
train_file_path = './datasets/slogans.txt'
model_name = 'skt/kogpt2-base-v2'
output_dir = './models2'
overwrite_output_dir = False
per_device_train_batch_size = 8
num_train_epochs = 5.0
save_steps = 500
train(
train_file_path=train_file_path,
model_name=model_name,
output_dir=output_dir,
overwrite_output_dir=overwrite_output_dir,
per_device_train_batch_size=per_device_train_batch_size,
num_train_epochs=num_train_epochs,
save_steps=save_steps
)
|
cs |
gpt2 모델 중에서 pytorch로 학습을 시킨 경우가 많았는데, 생각보다 복잡하고 배우지를 않아서 사용하지 못 했다. skt/kopgt2 토크나이저를 사용하였고, skt/kogpt2-base-v2 모델을 사용하여 학습을 진행했다. 생각보다 학습 코드 자체에는 우리가 수정해서 성능을 개선시킬 것이 많지 않았다. 그래서 결과를 어떻게 개선시킬 수 있는지에 더욱 초점을 두고 프로젝트를 진행했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
from transformers import PreTrainedTokenizerFast, GPT2LMHeadModel
def load_model(model_path):
model = GPT2LMHeadModel.from_pretrained(model_path)
return model
def load_tokenizer(tokenizer_path):
tokenizer = PreTrainedTokenizerFast.from_pretrained(tokenizer_path)
return tokenizer
def generate_text(sequence, max_length):
model_path = "./models2"
model = load_model(model_path)
tokenizer = load_tokenizer(model_path)
ids = tokenizer.encode(f'{sequence},', return_tensors='pt')
final_outputs = model.generate(
ids,
do_sample=True,
max_length=max_length,
pad_token_id=model.config.pad_token_id,
top_k=50,
top_p=0.95,
)
print(tokenizer.decode(final_outputs[0], skip_special_tokens=True))
# sequence = input()
# max_len = int(input())
input = '기업 설명'
sequence = input
max_len = 50
print('input :' + sequence)
for i in range(10):
print(generate_text(sequence, max_len))
print('=' * 30) |
cs |
GPT 언어 모델 자체가 주어진 단어 다음에 등장할 단어의 확률을 예측하는 방식으로 학습된다. 그래서 transformer로 문장을 생성할 때 성능을 높이기 위해 top_k 와 top_p 샘플링 방식을 이용했다.
Top-K 샘플링 : 현재 단어 다음으로 나올 수 있는 단어를 개수로 제한한다. 아주 작은 확률의 단어도 선택 가능.
Top-P 샘플링 : 현재 단어 다음으로 나올 수 있는 단어를 확률로 제한한다. 누적활률로 계산을 하기 때문에 확률이 낮은 단어는 제외.
결과에서 문제점들이 많이 발견됐다.
1. input 값과 관련 없는 슬로건들이 등장한다.
2. 결과값의 문장 모양이(?) 통일성이 없다. => 슬로건, 광고문구만 뽑기 위해서 제약이 생긴다.
3. 완벽한 문장들이 등장해서 슬로건으로서의 가치가 떨어진다.
1, 2번을 해결하기 위해서 결국 노가다를 시작했다. 데이터셋을 조금 더 통일감 있게 구성을 하고('기업설명, 슬로건'으로 통일), 슬로건은 카테고리로 세분화가 되어있었는데, 더 세분화를 시켰다(화장품 -> 세럼, 스킨케어 등등). 그리고 1번을 더욱 정교하게 처리하기 위해서 텍스트 문장 유사도를 사용했다.
3번 문제도 약간은 복잡했다. 에포크 수를 변경하면서 loss 값이 가장 적은 최적의 에포크 수를 찾아서 저장을 했다. 하지만 실제로 에포크에 따른 모델들을 다 돌려봤을 때, loss값이 가장 적었던 모델이 너무 완벽한 문장이 나와서 오히려 광고문구 같은 느낌이 나지 않는 경우도 발생했다. 영어 모델의 경우는 에포크와 어떤 gpt2 모델을 돌리느냐에 따라서 결과값의 차이가 컸다.
그리고 혹시나 데이터 양이 많지 않아서 생긴 문제가 아닐까 싶어서(1만 개 정도), 애플의 슬로건만(200개?) 가지고 학습을 진행했더니 정말 충격적인 결과가 나왔다.
데이터의 양이 적으면 애초에 슬로건 자체가 형성이 되지 않고, gpt2나 kogpt2에서 이미 사전에 학습한 내용을 가지고 문장을 생성하기 때문에 데이터 자체에 문제는 아니었다. 물론 데이터가 많으면 많을수록 우리가 노가다 해야할 부분도 많겠지만... 더 좋은 결과가 나올 것이라고 장담한다.
잠깐 스트레칭을 하면서
고개도 도리도리 돌려주세요
이어서 쓰려다가 너무 길어질 것 같아서
2편으로 나눕니다.
GPT3 관련 내용은 아래 링크로 ▼
'도전하자. 프로젝트' 카테고리의 다른 글
6-5 파이널 프로젝트 웹 배포 : AWS, 구글 애즈 홍보, GA(구글애널리틱스) (0) | 2021.09.09 |
---|---|
6-4 파이널프로젝트 Sentence Transformer를 이용한 짧은 텍스트 / 제목 문장 유사도 (2) (1) | 2021.09.03 |
6-2 파이널프로젝트 나무위키, 네이버 블로그 크롤링 및 전처리 (4) | 2021.09.02 |
6-1 파이널 프로젝트 : 자연어처리, kogpt2를 이용한 슬로건 생성 (0) | 2021.08.26 |
5-3 파이썬 팀프로젝트 PyQt5로 간단 GUI 프로그램 만들기 (자동완성 기능) (2) | 2021.08.14 |