[NLP] Subword Tokenization
Subword Tokenization
이번 포스팅에서는 본격적으로 Pretrained models를 살펴보기 전에, 그러한 모델들에 기본적으로 사용되는 Subword tokenization 방법들을 몇 가지 알아보고자 합니다. 그냥 단어나 character 단위로 그대로 Tokenization을 하게 되면 이후 다양한 Text를 분석하는 데 있어 OOV (Out Of Vocabulary) 문제에 직면하여 모델의 정확도가 크게 하락할 가능성이 있습니다. 따라서 우리는 적절한 Subword tokenization 방법을 사용하여 Computational cost가 너무 높지 않으면서 OOV 문제는 완화할 수 있도록 해야 합니다.
Subword Tokenization에는 여러 가지 방법이 있을 수 있겠지만 일단 대표적인 방법인 1) Byte Pair Encoding (BPE), 2) WordPiece, 3) Unigram Language model , 이렇게 3가지를 소개해드리도록 하겠습니다.
Byte Pair Encoding (BPE)
BPE는 Sennrich et al. (2016) 이 제안한 방법으로, Subword dictionary를 형성하는 방법 중 하나입니다. BPE는 2019년 GPT-2에도 사용되었다고 합니다. 대략적인 알고리즘을 살펴보자면 아래와 같습니다.
1) 충분한 크기의 Training data를 준비한 후, 바람직하다고 여겨지는 Subword vocabulary size를 정해준다
2) Corpus 내 단어들을 character-level로 나누어준 뒤 각 단어당 빈도수(frequency)를 세고 suffix </w> 와 빈두소를 단어 뒤에 붙여 rephrase 한다 (ex) low -> l o w </w> :5)
3) 위 step 에서 만들어진 것들을 바탕으로 높은 빈도수를 가지는 새로운 subword를 만들고 Vocabulary를 update 한다
4) Step 1에서 미리 정해준 vocab size에 도달하거나 next highest frequency pair가 1이 될 때까지 Step 3를 반복한다
- **Ex) **Input words : “low: 5”, “lower: 2”, “newest: 6”, “widest: 3”
- Let Subword vocab size = 50.
- Input 단어들을 분석했을 때 가장 높은 빈도수를 갖는 Subword pair는 e와 s 입니다 (“newest”와 “widest”에 각각 6번, 3번씩 포함). 그럼 우리는 이 “es” 라는 새로운 subword를 Vocabulary candidate에 추가합니다.
- “es”를 추가한 뒤 다시 Step 3를 수행해보면, 이번엔 “es”와 “t”가 가장 높은 빈도수를 가지는 Subword pair가 됩니다. 이제 우리는 또다시 “est”를 Vocabulary candidate에 추가하고, 이러한 과정을 Vocab size가 50이 되거나 highest frequency pair가 1이 될 때까지 반복합니다.
- 이렇게 해서 최종적으로 도출되는 Vocabulary candidate 를 바탕으로 우리는 Test 과정에서의 OOV 문제를 완화할 수 있습니다. 예를 들어 Test 과정에서 “wider”라는 단어가 등장하면 기존 단어 set에서는 OOV에 직면했겠지만, BPE를 통해 만든 Vocab candidate을 통해서는 “wid”+”e”+”r” 이런 식으로 나눠서 OOV 문제를 해결할 수 있는 것입니다.
WordPiece
WordPiece 는 사실 앞서 설명한 BPE의 변형 버전이라고 보시면 되겠습니다. 알고리즘 자체는 BPE와 유사하나, 차이점이 있다면 가장 빈도수 가 높은 pair를 기준으로 하는 BPE와 달리 WordPiece는 Likelihood 를 기준으로 한다는 점입니다. 대략적인 알고리즘은 아래와 같습니다.
1) Training data 준비 및 바람직한 Subword vocabulary size 지정
2) Data 내 단어들을 character 단위로 나눠준 뒤, 그것들을 바탕으로 Language model 구축
3) 가능한 unit 조합들 가운데 모델에 추가되었을 때 Likelihood 를 가장 높여줄 수 있는 Pair를 구하고 Vocab candidate에 추가
4) Step 1에서 정한 Vocab size에 도달하거나 Likelihood 증가분이 일정 threshold 밑으로 떨어질 때까지 Step 3 반복
위 알고리즘을 보면 알겠지만 WordPiece는 BPE 와 과정이 매우 유사합니다. Likelihood 를 기준으로 한다는 점과 Underbar( _ ) 를 사용하여 _문장 복원_을 용이하게 한다는 점이 WordPiece의 특징이라고 할 수 있습니다.
WordPiece는 구글 번역기에 사용되기도 하였으며, 너무나도 유명한 BERT 훈련에 쓰이기도 하였습니다.
(Ex) ‘Jet makers are all over’ -> ‘_J et _makers _are _all _over’)
Unigram Language Model Tokenizer
Unigram Language Model Tokenizer 도 알고리즘 자체와 Language model을 활용한다는 점에서 WordPiece 와 비슷하지만 이번엔 Likelihood 를 감소시키는 Subword를 찾는다는 점에서 차이가 있습니다.
1) Training data 준비 및 바람직한 Subword vocabulary size 지정
2) Language model과 주어진 word sequence를 바탕으로 word occurrence에 대한 확률을 최적화
3) 각 Subword (Character-level recommended)에 대한 Loss (해당 Subword가 집합에서 제거되었을 경우 Likelihood가 얼마나 감소하는지)를 계산하여, 가장 안 좋은 영향을 주는 10~20% 정도의 Subword를 제거
4) Step 1에서 지정해준 Vocab size에 도달하거나 Step 3에서의 Likelihood 변화가 없을 때까지 Step 2~3을 반복
결국 Unigram Language Model Tokenizer와 WordPiece는 유사하지만 Likelihood 의 증감 여부 가 가장 큰 차이라고 보시면 되겠습니다.
이번 포스팅에서는 Preprocessing의 기본이 되는 Tokenization에 쓰이는 여러 방법들에 대해 살펴보았습니다. Python에서는 SentencePiece라는 라이브러리를 통해 이러한 Text preprocessing을 비교적 쉽게 진행할 수 있습니다. 자세한 코드는 이곳 을 참조해주세요!