본문 바로가기

AI/자연어처리(NLP)

GPT-2 (Generative Pre-Training 2)

소설쓰는 인공지능!

본 글에서는 소설쓰는 인공지능인 GPT-2 모델의 사용법에 대해 알아보고

직접 인공지능이 소설을 쓰게 해본다.


최근 인공지능의 자연어 처리에서 가장 화제가 되고있는건

Bert, GPT-2, Transformer 이다.


Transformer : 번역(Neural Machine Translation)

Bert : 양방향 언어모델

GPT-2 : 단방향 언어모델


본 글에서는 파이토치를 이용한 GPT-2(Generative Pre-Training-2)에 대해 다룬다.


보통 Tensorflow로 학습된 모델을 convert_tf_checkpoint_to_pytorch_custom.py 을 이용하여 파이토치 버전으로 바꾼다.

하지만 이미 파이토치 버전으로 변환해 놓은 GPT2 pre-trained model을 아래 깃헙에서 받을 수 있다.


https://github.com/graykode/gpt-2-Pytorch



아래 깃헙에서 GPT2를 이용하여 Text-Generator를 이용할 수 있다.  graykode를 참고하였다.


https://github.com/keep-steady/gpt-2-Pytorch



1. 파이토치(0.41~)가 설치된 linux에서 다음 명령어를 수행하여 실행 예제 파일을 다운받는다

>> git clone https://github.com/graykode/gpt-2-Pytorch.git


2. 다운받은 gpt-2-Pytorch 폴더 안의 GPT2_Pytorch.ipynb 파일을 jupyter notebook을 이용하여 연다.



3. 첫 cell에 아래와 같은 코드가 있다.

!git clone https://github.com/graykode/gpt-2-Pytorch

%cd gpt-2-Pytorch

!curl --output gpt2-pytorch_model.bin https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-pytorch_model.bin

!pip install -r requirements.txt


첫 줄은 graykode의 깃헙에서 코드를 다운받는 명령어이다.

두번째 줄은 다운받은 gpt-2-Pytorch 폴더로 접근하고

curl 명령어로 아마존 드라이브에서 gpt2 모델을 가져온다.

그리고 requirements.txt에 있는 파일들을 설치하여 GPT2를 구동하기 위한 준비작업을 한다.


4. Text Generator 수행

main.py를 아래와 같은 명령어로 수행하거나

Jupyter notebook의 두번째 cell을 수행시킨다.

명령어는 다음과 같다.

python main.py --text "시작하는 문장 입력" --length '생성하고자 하는 token 길이를 숫자로'


!python main.py --length 200 --text "Today, The north korea's hacking group attacted bank of south korea. That bank was seriously damaged."



5. 결과

GPT-2에 "북한의 해킹그룹이 한국의 은행을 해킹했다. 그 은행은 심각한 피해를 입었다"

라는 입력을 주자 다음과 같은 글을 생성했다.


- 입력 TEXT

Today, The north korea's hacking group attacked bank of south Korea. That bank was seriously damaged.


- 생성된 TEXT

It was totally destroyed. The thieves of the north korea bank, who broke in to steal more than 100 BTC, were very careful about what they stole from them. This was the first time that anyone has been attacked by North Korea.

On the other hand, the hackers of the south korea bank were very careful about what they stole from them. This was the first time that anyone has been attacked by North Korea. The theft of more than 100 BTC from the stolen bank was the most heinous and damaging attack on South Korean society. This attack was carried out by the North Korean hackers and their allies.

This attack was carried out by the North Korean hackers and their allies. The theft of more than 100 BTC from the stolen bank, was the most serious and damaging attack on South Korean society. This attack was carried out by the North Korean hackers and their allies. The theft of more than 100 BTC from the stolen bank was the second most serious attack on South Korean society.



두 문장을 주어줬을 뿐인데 생각보다 훌륭한 글을 작성해냈다.



6. 문장을 생성해 내는 코드는 아래와 같다.

이전 단어들이 주어졌을 때 다음 단어가 나올 확률을 계산하는 방식이다.

GPT2\sample.py 의 sample_sequence 함수 에서 context를 입력으로 받으면 이를 output에 저장하고,

output을 입력으로 하여 model 에서 한 token을 생성하고

이 생성된 token을 output에 추가한다.

즉 입력 문장으로 token 생성, 입력문장 + 생성된 token을 이용하여 다음 token 생성, 이런식으로 반복하며 정해진 길이까지 글을 생성한다. 


prev = context

output = context

past = None

with torch.no_grad():

    for i in trange(length):

        logits, past = model(prev, past=past)

        logits = logits[:, -1, :] / temperature

        logits = top_k_logits(logits, k=top_k)

        log_probs = F.softmax(logits, dim=-1)

        if sample:

            prev = torch.multinomial(log_probs, num_samples=1)

        else:

            _, prev = torch.topk(log_probs, k=1, dim=-1)

        output = torch.cat((output, prev), dim=1)



7. GPT-2를 개발한 OpenAI 에서는 가짜 뉴스나 다른 나쁜 용도로 악용될 소지가 있으므로 아주 작은 모델만 오픈했다.

다양한 분야 4500만개 링크의 텍스트(40GB)를 인터넷에서 모아서 학습했다. 소설 3만 5,000권에 해당하는 데이터 크기이다.

모델의 파라미터는 15억개 이다. Bert-large(3.4억개)와 비교해도 엄청 큰 모델이다. BERT는 bidirectional 방식으로 처리했지만, GPT2는 unidirectional 방식을 고수했다.

특정 도메인에 특화한 훈련을 하지 않는 zero-shot 방식을 강조한다.

Text를 생성하는 NLG에 좋은 성능을 낸다.


엄청난 데이터로와 네트워크로 next tokens를 위한 joint probabilities를 극대화 하는 언어모델로 성능이 좋다.

악용될 우려가 있어 학습된 모델과 소스코드를 공개하지 않았다. 

대신 작은 데이터셋으로 학습된 별도의 작은 모델만 공개하여 실험을 수행해 보았다.