- Published on
[GPT-2] Language Models are Unsupervised Multitask Learners
Summary
- 더 많은 데이터, 더 큰 모델로 여러 Task 를 한꺼번에 학습했더니 Fine-Tuning 없이도 Fine-Tuning 모델보다 성능이 좋아졌다.
- Byte-level BPE 로 Tokenize 하여 Out of Vocabulary 문제의 가능성을 줄이고, 효율성은 높였다.
- 다양한 Task 를 학습할 수 있는 데이터셋(WebText)을 Reddit 을 사용하여 만들었다.
Problem of Fine-Tuning Approach
GPT는 Generative Pre-trained Transformer 의 약자이다. 풀 네임에서는 모델의 대표적인 특성이 정말 잘 드러나고 있는데, Transformer 구조를 가지고 Generative model 의 특성을 가지도록 Pre-Trained 된 모델이라고 할 수 있다.
Pre-Training 된 모델은 이후 개별 Task(Downstream task)에 맞춰 layer 를 추가하고, 새로운 데이터에 대해 추가적인 학습도 진행하게 된다. 이 과정을 Fine-Tuning 이라 하는데 Fine-Tuning 은 다음과 같은 여러가지 문제를 안고 있다.
- 추가 layer 뿐만 아니라 Pre-trained 모델에 대해서도 학습을 진행해야 하므로, 연산 비용이 높다.
- Task 에 맞게 적절히 labeled 된 데이터를 충분히 확보해야 한다.
Fine-Tuning 단계로 인한 위 두 가지 문제점은 실제 사용자 입장에서 불편함을 가중한다. 새로운 영역에 GPT 모델을 적용하고자 할 때에는 매번 새롭게 (대부분 사람이 labeling 하여 얻어진) 학습 데이터를 만들고, 추가적인 학습도 해주어야 하기 때문이다.
Zero-Shot: Remove a Fine-Tuning
GPT-2는 위와 같은 문제를 갖는 Fine-Tuning 단계를 없애버려도 높은 성능을 확보할 수 있다는 것을 보여준다. Fine-Tuning 을 통해 특정 분야를 잘 아는 Specialist 를 만들 것이 아니라, Pre-Training 모델을 처음부터 모든 Task 를 잘 해결하는 Generalist 로 만들어버리겠다는 것이다.
General system 은 다양한 Task 들을 적절히 처리해야 하는데, 한 가지 문제가 있다면 Task 별로 원하는 출력이 달라진다는 것이다. 동일한 것에 대해 묻는 질문이라 할지라도 O/X 퀴즈인지, 선택형 문제인지, 서술형 문제인지에 따라 해답이 달라지는 것처럼.
Specialist 를 만드는 GPT-1 는 세 가지 유형의 문제 각각에 대해 Fine-Tuning 을 진행하여 문제를 해결할 것이다. General system 은 사람이 그러하듯, 문제의 유형이 무엇인지에 대한 정보를 함께 받아 적절한 형태의 정답을 반환하도록 학습한다. 즉 이 문제가 O/X 퀴즈인지, 서술형인지에 대한 정보를 입력에서 함께 받는다는 것이다.
- GPT-1:
p(output | input)
- GPT-2:
p(output | input, task)
GPT-2는 "충분한 Capacity 를 가지고 있는 언어 모델은 natural language sequece 형태로 표현된 다양한 Task 를 추론하고 학습할 수 있을 것"이라는 아이디어에서 시작되었다고 한다.
Training Dataset
General system 을 만들기 위해서는 크고 다양한 특성을 갖는 언어 데이터 셋을 확보하는 것이 필요했다고 한다. 이를 위해 Common Crawl 과 같은 서비스를 사용하는 것을 고려했으나, 데이터의 질적인 측면에서 문제가 있다는 점이 다른 논문(Trinh & Le (2018))에서 언급된 만큼 적합하지 않은 것으로 판단했다고 한다.
대신 General system 학습에 적절할 만큼 다양한 영역을 포괄하면서도 최소한의 품질이 확보되는 문서로만 구성된 새로운 데이터 셋을 직접 만들었다. 특히 사람에 의해 curating/filtering 되는 문서들을 수집하는 것을 목표로 했는데, 이를 위해 Reddit 을 적극적으로 활용했다고 한다. 구체적으로 Reddit 에서 3 Karma(좋아요) 이상을 받은 Post 들에 포함된 Out-bound link 는 괜찮은 문서로 보았다는 것이다. 이렇게 수집된 link 의 html 에서 텍스트를 추출하여 WebText
라는 데이터 셋을 만들고, GPT-2 의 학습에 사용하게 된다.
한 가지 특이점이 있다면 여기서 위키피디아 링크는 제거했다는 것이다. 위키피디아의 정보들은 너무 광범위하게 사용되어 테스트 셋에도 포함될 가능성이 높다고 판단하였기 때문이다.
Input Representation
Text를 확보하였으니 이를 어떻게 Token화 하여 모델의 입력으로 전달할 것인지 정해야 한다. 자연어를 Token화 하는 방법은 매우 다양한데, GPT-1 에서는 빈도 수에 따라 subword 를 추출하는 BPE(Byte-Pair Encoding)를 사용하였다.
BPE: Byte-Pair Encoding
BPE에 대한 설명은 Huggingface nlp course에 잘 정리되어 있다. 여기서는 course 에서 나오는 예시를 바탕으로 이를 간략히 요약해보고자 한다.
GPT-1 에서는 subword 를 추출하는 알고리즘으로 사용되었지만 본래 BPE는 데이터를 압축하는 알고리즘으로 개발되었다. 아이디어 자체는 반복적으로 등장하는 부분을 더 작은 크기로 치환하여 전체 크기를 줄이는 것으로, 당연히 빈번하게 등장하는 부분을 치환하면 압축률은 높아지게 된다. 이를 빈번하게 등장하는 문자열을 가장 작은 의미의 단위인 Token으로 치환하면 의미를 구성하는 subword 별로 Token화가 가능할 것이라는 아이디어에서 subword 추출 알고리즘(word segmentation algorithm)으로 사용하게 된 것이다(Sennrich(2016)).
우선 Training Set 에 나오는 단어들의 빈도 수를 계산해보았더니 아래와 같았다고 가정해보자.
("hug", 10), ("pug", 5), ("pun", 12), ("bun", 4), ("hugs", 5)
단어를 이루는 기본 단위는 문자(Character) 이므로, 이를 문자 단위로 쪼개어 보면 다음과 같다.
Vocab: ["b", "g", "h", "n", "p", "s", "u"]
Corpus: ("h" "u" "g", 10), ("p" "u" "g", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "u" "g" "s", 5)
이때 가장 많이 등장하는 문자열 Pair 는 "hug", "pug", "hugs" 에서 총 20번에 걸쳐 등장한 "ug" 이다. "ug"를 Vocabulary 에 추가해주고 Corpus 도 아래와 같이 업데이트 해 준다.
Vocab: ["b", "g", "h", "n", "p", "s", "u", "ug"]
Corpus: ("h" "ug", 10), ("p" "ug", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "ug" "s", 5)
다음으로 많이 등장하는 Pair 는 총 16회 등장하는 "un" 이다. 병합해주자.
Vocab: ["b", "g", "h", "n", "p", "s", "u", "ug", "un"]
Corpus: ("h" "ug", 10), ("p" "ug", 5), ("p" "un", 12), ("b" "un", 4), ("h" "ug" "s", 5)
다음은 "hug" 이다.
Vocab: ["b", "g", "h", "n", "p", "s", "u", "ug", "un", "hug"]
Corpus: ("hug", 10), ("p" "ug", 5), ("p" "un", 12), ("b" "un", 4), ("hug" "s", 5)
이런 식으로 계속 Pair 의 빈도를 계산하고 병합하는 식으로 반복함으로써 subword 를 정의하는 것이 BPE 알고리즘이다. 이러한 BPE 알고리즘은 OOV(Out of Vacabulary) 문제에 탁월하다. 즉, 학습 과정에서 본 적 없거나 거의 등장하지 않는 단어(rare and unseen words)들 또한 subword sequence 로 쪼개어 표현함으로써 어느 정도의 의미를 파악하는 데에 도움이 된다는 것이다.
Byte-Level BPE
그런데 GPT-2 에서는 Byte-Level BPE를 사용하였다. Byte-Level BPE 는 말 그대로 문자가 아닌 Byte를 가장 기본 단위로 BPE를 수행하겠다는 것을 의미한다.
과거 ASCII 코드로 문자를 표현할 때에는 모든 문자가 1Byte 로 표현되었으나, Unicode가 보편적으로 사용되는 현대에 들어서는 Encoding 방법에 따라 달라지겠지만 하나의 문자가 가지는 크기가 1Byte 부터 4Byte까지 다양해졌다. 그만큼 표현할 수 있는 문자도 로마자, 한글과 같은 문자는 물론 이모지까지 매우 많아졌다. 문제는 그에 따라 학습 과정에서 한 번도 보지 못한(rare and unseen) 문자들이 있을 확률도 높아졌다는 것이다. 이러한 문제 때문에 GPT-1 에서는 이모지를 비롯한 특수 문자를 Unknown Token으로 처리하였고, 성능 또한 좋지 못했다.
Byte-Level
이라는 표현에서도 알 수 있겠지만, Byte-Level BPE는 기본 단위를 문자가 아닌 Byte로 하여 BPE 를 진행함으로써 이러한 문제를 해결하려 한다. 즉, 더 이상 추가될 가능성이 없는 Byte
를 기본 단위로 Subword를 구성하여 Unknown token의 발생하는 경우의 수 자체를 없애겠다는 것이다.
또한 Byte-Level BPE를 실행할 때에 character category 가 같은 경우에 대해서만 병합하도록 했다고 한다. dog
, dog?
, dog!
는 강아지라는 서로 동일한 의미를 갖지만 등장 빈도에 따라 서로 다른 subword 로 처리되는 경우가 있어 이를 방지하기 위함이라고 한다(효율적인 vocabulary 구성).
Model
모델 면에 있어서는 GPT-1 과 비교하여 개선 사항이 크지 않다. GPT-1 과 동일하게 Transformer 베이스 모델 구조를 사용하였고, 다음과 같은 부분들을 변경하였다.
- Layer Normalization을 각 sub-block 의 input 부분으로 이동
- 마지막 self-attention layer 에 layer normalization 추가
- residual layer 의 깊이()에 따라 으로 스케일링하여 가중치 초기화 진행
- vocabulary, context vector size, batch size 증가
Reference
- Radford, A., Wu, J., Child, R., Luan, D., Amodei, D. and Sutskever, I. (2019). Language Models are Unsupervised Multitask Learners.
- huggingface.co. (n.d.). Byte-Pair Encoding tokenization - Hugging Face NLP Course.
- Sennrich, R., Haddow, B. and Birch, A. (2016). Neural Machine Translation of Rare Words with Subword Units.