12주차(2) - BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

2019. 4. 9. 20:21풀잎스쿨 NLP Bootcamp

논문링크: https://arxiv.org/abs/1810.04805

 

BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

We introduce a new language representation model called BERT, which stands for Bidirectional Encoder Representations from Transformers. Unlike recent language representation models, BERT is designed to pre-train deep bidirectional representations by jointl

arxiv.org

참고자료: http://docs.likejazz.com/bert/

 

BERT 톺아보기 · The Missing Papers

BERT 톺아보기 17 Dec 2018 어느날 SQuAD 리더보드에 낯선 모델이 등장했다. BERT라는 이름의 이 모델은 싱글 모델로도 지금껏 state-of-the-art 였던 앙상블 모델을 가볍게 누르며 1위를 차지했다. 마치 ELMo를 의식한 듯한 BERT라는 생소한 이름 그리고 구글. 모두가 궁금해하고 있을때, BERT의 등장을 알리는 논문이 공개됐다. 2019년 1월 24일 KorQuAD 리더보드 추가 2018년 12월 31일 시각화 추가 201

docs.likejazz.com

참고자료2: http://jalammar.github.io/illustrated-bert/

 

The Illustrated BERT, ELMo, and co. (How NLP Cracked Transfer Learning)

Discussions: Hacker News (98 points, 19 comments), Reddit r/MachineLearning (164 points, 20 comments) Translations: Chinese (Simplified), Persian The year 2018 has been an inflection point for machine learning models handling text (or more accurately, Natu

jalammar.github.io

(발표자료의 경우 발표자님의 개인사정으로 인해 업로드가 되지 않을 듯 합니다.)

 

Abstract

이전 논문(GPT-1)에서 우리는 NLP Task에 사용할 수 있는 Pre-trained 모델을 살펴봤다. 해당 구조는 Pre-training과 Fine-tuning으로 나눠서 살펴볼 수 있다. Pre-training에서는 Unsupervised Learning을 이용하여 Language Model을 구축하고 있고, Fine-tuning에서는 주요 Task와 보조 Task(Auxiliary Objective)를 이용하여 성능을 개선하고자 했다.

 

하지만 GPT-1에도 단점은 존재하는데, 바로 Left to Right, 즉 단방향으로만 진행되는 구조의 모델인 점이다. 이러한 점이 왜 단점인지에 대해서는 이전 논문들에서 다양하게 살펴봤고, 우리는 이미 Bi-direction 구조의 모델이 더 좋은 성능을 이끌어내는 것을 다양한 방법으로 살펴본 바 있다.

 

이 논문에서는 단방향 Transformer를 사용했던 GPT-1과는 달리 Bidirectional Transformer를 사용해서 Pre-training을 더욱 효과적으로 하고, 이를 통해 NLP Task에 적용하는 방식을 훨씬 쉽게 할 수 있도록 하는 방법을 제시한다.

 

Contribution

Before you begin...

사실 BERT에 대해 이야기 할 것이 생각보다는 많이 없다. 의외라고 생각할 수도 있겠지만, 이미 GPT-1(이전 글 참조)에서 설명해놓은 부분도 많고, 여러 컨셉들이 여태 리뷰한 내용들과 상당수 겹치는 것들이 많기 때문이다. 사실 상세한 리뷰는 참조자료 링크에서 훨씬 잘 설명하고 있는것이 사실이다. (BERT 톺아보기에서 이러한 부분들을 친절하고 상세하게 잘 설명한다)

 

따라서 이 리뷰에서는 BERT에 대한 세부 구성 위주의 설명보다는 지난 논문에서 설명한 GPT-1과 이번 논문에서 다루고 있는 BERT가 서로 지향하는 바의 차이점을 위주로 설명하고자 한다. 이를 통해 왜 BERT가 이런 구성을 할 수 밖에 없었는지에 대한 이해를 돕고자 한다.

 

Architecture

일단 Multi-head Attention, Scaled Dot-product Attention과 같이 기존 Transformer에서 이미 언급된 내용은 생략하고자 한다.

 

일단 Input부터 살펴보자. GPT-1에서는 BPE(BytePair Encoding)을 Input Encoding으로 사용했다. 이는 이미 BPE가 Context에 대해 충분한 정보를 포함할 수 있다는 전제하에 진행하는 것이다. 때문에 GPT-1에서는 Transformer 모델 중 Decoder 부분만 사용하여 Context의 정보를 추출하고자 했다.

 

BERT에서는 Transformer구조 중 Encoder만 사용하고 있다. (Base모델: 12개, Large모델: 24개) 조금 더 자세하게 설명하자면, Input으로 Word-piece Model을 사용하여 Encoding을 한다. 이러한 Word-piece encoding은 Transformer에 그대로 입력으로 들어가게 되고, Encoder를 이용해서 Context와 연관이 있는 정보만 남기고자 하는 의도이다.

 

GPT-1에서 BPE가 쓰인 이유가 사용되는 어휘의 갯수를 줄이고자 하는 것과 마찬가지로 BERT에서는 Word-piece Model을 사용하여 subword를 통해 어휘의 갯수를 줄이고자 한다. 실제로 업무에 BERT를 사용할때 이 부분에서 많은 고민을 할 수 있는데, 구글에서 직접 배포하고있는 Sentencepiece 패키지(https://github.com/google/sentencepiece)를 이용하면 될 것이다. (한글 기준으로는 다른 방법을 적용해야 된다는 점을 명심하자!)

 

BERT에서의 Input구조

또한 Input에 대해 조금 더 설명하자면, Transformer에서 Positional Encoding을 통해 위치에 대한 정보를 남겼다면, BERT에서는 Positional Embedding을 사용한다. Positional Encoding과 Positional Embedding의 차이라고 하면 Encoding의 경우 학습되는 Parameter가 아니고 확정적으로 주어지는 정보이며, Embedding의 경우 Random initialize 후 학습을 통해 Position 정보를 Parameter로서 가진다는 점이다.

 

그리고 Input은 아래 3가지의 Embedding으로 구성된다.

  • Token Embedding: 토큰 정보(Embedding)
  • Segment Embedding: 토큰 타입
  • Position Embedding: 각 토큰의 위치 정보

일단 Input을 넣을 때는 문장 단위로 넣게 되는데, 여기서 문장의 최대 길이는 512 Token으로 제한된다. 이 부분에 대해 자세히 기술되어 있지는 않지만, Padding과 Truncate를 통해 문장의 길이를 맞춰준다고 이해하면 편하다. 이러한 구조를 취하는 것은, 특정 길이에 Overfitting이 나오는 것을 방지하기 위함이다.

 

Input Masking

위에서 사용되는 Input은 그대로 사용되는 것은 아니다. Masked Attention이라는 방법을 통해 문장의 Attention을 올바르게 예측하고자 한다. 위 캡쳐에서도 설명하고 있는 방식으로, 3가지의 다른 Masking을 적용한다.

  1. Input중 80%: 특정 토큰을 [MASK]로 대체한다. 이는 [MASK]부분의 토큰을 정확히 Predict하기 위함이다.
  2. Input중 10%: 특정 토큰을 무작위 토큰으로 대체한다. 이 부분에서는 올바르지 않은 문장을 예측하는 경우를 줄이고 올바른 문장을 예측하기 위함이다.
  3. Input중 10%: 특정 토큰을 그대로 유지한다. 올바른 문장을 예측할 경우, 이것이 올바른 문장이라는 경우에 대해 학습하기 위함이다.

주의해야 할 점은, 언급한 Masking은 모든 Input에 대해 적용하는 것은 아니며, 전체 Input 데이터 중 15% 정도의 Token에만 적용한다.

 

이런식의 Masked LM이 잘 이해가 되지 않는다면 Cloze Task와 유사하다는 점만 기억하면 조금 더 이해하기 쉬울 것이다.

 

BERT vs GPT-1 vs ELMo

BERT에서는 Bi-direction 구조를 사용하고 있다. 즉, Forward 방향과, Backward 방향을 모두 Propagate하는 구조를 사용한다. 이는 지금까지 리뷰했던 여러 논문들에서 볼 수 있듯이, Context 내 이전 단어와 다음 단어에 대한 정보를 모두 고려하는 것이 예측에 더 용이하기 때문이다. (몇몇 논문들에서는 Backward 방향에서 취합되는 정보가 Forward 방향에서 취합되는 정보보다 더 유용하다는 결과를 보인바 있다)

 

LTR vs Masked LM

BERT에서 GPT-1과 같이 Unidirectional한 구조 대신 Bidirectional한 구조를 가져가는 이유는 당연히 모델의 성능 때문이다. 하지만 이러한 이유 이외에도, Unidirectional 모델은 수렴(Converge)이 빨리 된다는 이점을 가져갈 수 있는데, 이는 학습 시간을 단축시킬 수 있다는 뜻이다. 하지만 Bidirectional 모델은 학습에 시간이 더 오래걸리는데, BERT는 학습 시간을 조금 더 사용하더라도 성능을 개선시키고자 하는 의도를 보인다.

 

여기서 착각하기 쉬운 것은, 'NLP에서 Bi-directional구조가 당연히 되는구나'라는 생각이다. NLP의 많은 Task들은 이후 출현하는 단어의 확률을 이전 단어에 기반하여 순차적으로 예측해야 하는 특성을 가지고 있다. 따라서 Statistical LM은 Bidirectional하게 구축할 수 없다는 특성을 가지게 되는데, BERT에서는 이를 다른 형태로 전환해서 Bidirectional이 가능하게 한다.

 

NSP(Next Sentence Prediction) 예시

첫번째는 앞서 언급했던 방식인 Masked Language Model이다. Masked LM이 우선적으로 진행되는 것을 Forward라고 이해해도 좋으며, 이 부분에서 하는 것은 위에서 앞서 설명한 그대로이다.

 

두번째는 Next Sentence Prediction이다. 여기서는 두개의 문장이 주어지며, 현재 Sentence와 비교할 Sentence를 가 주어진다. 현재 Sentence와 비교할 Sentence 모두 Mask는 그대로 유지하며, 추가로 [CLS]와 [SEP]가 주어진다. [CLS]는 Class를 뜻하며, 분류 문제를 해결하는데 사용된다. 또한 [CLS]는 두 문장의 유사도를 판별하는데도 사용된다. [SEP]는 Seperator를 뜻하며, 문장의 끝을 나타내는 식별자이다.

 

여태까지 설명했던 구조를 통해 BERT를 구성하면, General한 Feature를 뽑는 작업은 마무리된다. 나머지는 Fine-tuning에서 Task-specific한 학습을 진행하게 되게 되는데, 이 방법이 굉장히 간편하다는 점이 BERT의 가장 큰 장점으로 꼽힌다. 위 그림들을 살펴보면 BERT 모델은 그대로 가져가고 모델의 Output을 그대로 받아 Layer를 딱 하나만 붙여주면 된다. 이러한 down-stream구조는 Pre-trained 모델을 사용하기에 매우 용이하다는 이점을 가질 수 있다.

 

마지막으로 Transformer가 돌아가는 과정을 짤방으로 만들어놓은 것이 있어서 남겨놓는다.

왼쪽: 업데이트 되는 위치, 오른쪽: Attention 받는 위치

 

Activation

사족으로 모델에서 사용한 activation에 대해서 언급하고 싶다. 보통 모델을 학습할 때는 ReLU나 Tanh를 사용하는 방법이 널리 알려져 있는데, GPT-1과 BERT에서는 GeLU라는 activation을 사용하고 있다. 여기서 GeLU를 사용한 이유는 다른 activation에 비해 좋은 성능을 보여주기 때문인데, 이에 대해서 Searching for Activation Functions(https://arxiv.org/abs/1710.05941)라는 논문에서는 각 Activation function마다의 성능을 자세히 기술하고 있다.

 

Machine Translation에서의 각 Activation 함수의 성능

 

Result & Conclusion

Result

같은 크기의 모델에 대한 성능 비교를 위해 GPT-1과 BERT-base모델을 비교해보면, BERT에서는 상당한 성능 개선이 이루어진 것을 확인할 수 있다.

 

Ablation Study: Pre-training

여기서는 NSP(Next Sentence Prediction)과 LTR구조를 사용할 때의 결과를 보여주고 있다. 특히 No NSP의 경우 GPT-1과의 성능 비교를 하기 위해 성능을 측정하고자 했으나 GPT-1을 동일하게 구현할 수 없었기에 이러한 구조를 통해 비교하고자 했다는 의견도 있다. 만약 여기서 GPT-1과 비교하고자 했다면, No NSP & LTR에 대한 성능이 가장 가깝다고 할 수 있다.

 

BERT 모델 크기/Hyperparameter별 성능

BERT의 모델 크기에 대한 성능을 보여주고 있다. (#L: Layer갯수, #H: Hidden size, #A: Attention head 갯수) 표에서도 볼 수 있듯이, 모델의 크기가 크면 클수록 성능이 증가하는 것을 알 수 있다.

 

사용된 Layer별 성능에 대해서도 흥미로운 결과가 나와있다. 결국 모든 Layer를 사용하는 것이 성능은 가장 좋지만, 마지막 4개의 Layer에서 나온 Output을 Concatenate한 후 사용하는 것과 비교해봤을때, 큰 차이가 없다는 점이 특이한 점으로 꼽을 수 있을 것이다.

 

Conclusion

이번 NLP Bootcamp의 마지막 논문이었던 만큼 내용도 이전 논문들에서 다뤘던 내용이 상당수 있었고, 때문에 BERT를 이해하기에 한결 더 낫다는 느낌이 들었다.

 

사실 현업에서 NLP 관련으로 작업할 일이 있다면, 이전 논문들은 다 잊고 BERT 하나만 파는 것이 낫다. (이전 논문들에서 사용되었던 방법은 대부분 현재는 쓰이지 않는 방법이다.) 하지만 과거에 사용되는 방법을 배우는 것을 통해 BERT보다 더 나은 성능을 낼 수 있는 방법을 찾을 수도 있기에, NLP 논문들을 리뷰한 것은 좋은 경험이라고 생각한다.

 

사족으로 GPT-2에 대해서도 들을 수 있는 이야기가 있는데, GPT-2를 구현했던 코드 자체가 논문에서의 성능을 그대로 구현하기 어려워서 그럴 것이라는 의견도 있다. 이건 사실 믿거나 말거나 하는 이야기지만...

 

아무튼 논문 리뷰할때마다 블로그 글을 쓰는것이 상당히 오래걸리고 귀찮은(!) 작업이었지만, 돌이켜보면 그만큼 남는 것이 많았다는 보람을 느끼게 한다.