호돌찌의 AI 연구소
article thumbnail

https://youtu.be/kNw9dpzp5RU

NLP에서 데이터를 모델에 바로 집어넣는 것이 아닌 tokenization을 반드시 거쳐주어야 합니다. 문장 속 단어들은 여러 단어가 결합되어 나타나기 때문에, 반드시 이 것을 나누어서 컴퓨터가 더 이해하기 쉽게 작업을 거쳐주어야 합니다. 

 

 

기호(괄호, 따옴표, 마침표 등)을 나누는 것은 기본이고 NLP에서 난이도가 최상위권인 한국어 같은 경우에는, Mecab과 같은 형태소 분석기를 활용하여 어미와 접사를 분리를 해주는 것이 일반적인 것으로 알려져 있습니다. 왜 이 작업이 필수인 이유는 가장 NLP 하면서 스트레스를 많이 받게 되는 OoV(Out of Vocabulary) 문제이기 때문입니다. 

 

 

1. OoV(Out of Vocabulary)

- 여러 단어가 결합되어 있을 때, 이를 나누지 않으면 Corpus에 출현 빈도가 낮아지며 Test Data가 학습 시에 나타나지 않을 수 있음("00교육대학원"라는 단어를 "00", "교육", "대학원"을 나누어 줘야 함. "00교육대학원"이라는 단어가 상당히 Corpus 내에서 비중이 작을 수 있기 때문입니다.)

- 완전 처음 보는 신조어지만, 알고있는 어절들을 이용해 의미 유추를 해볼 수 있습니다.

- 입력 데이터에서 OoV가 발생할 경우 <UNK> 스페셜 토큰으로 대체하여 모델에 입력. 학습할 때 일부로 Vocab 수를 줄여서 학습하기도 함. 하지만, 이전 단어들을 바탕으로 다음 단어를 예측하는 NLG Task에서는 치명적인 문제가 존재합니다.

 

 

2. Token 평균 길이의 특징

특징 Token 길이가 짧은 경우 Token 길이가 긴 경우
Vocab 크기 감소, Sparse 문제 감소 증가, Sparse 문제 증가
OoV OoV 줄어듬 OoV 늘어남
Sequence 길이 길어짐, 모델의 부담 증가 짧아짐, 모델의 부담 감소

Token 길이가 짧을 수록 극단적으로 Character 단위로 까지 나타내기도 합니다. 그래서 Sequence가 길어지면 모델은 굉장히 피곤해합니다. 즉, Token 길이에 따라 Trade-off가 각 특징마다 존재함을 알 수 있습니다.

 

 

3. Byte Pair Encoding(BPE) Motivation

특정 Token의 빈도가 높을 경우에는 하나의 Token으로 나타내는 것이 굉장히 좋을 수 있습니다. 특정 Corpus에 아주 많이 나타나서 중요한 단어일 수 있기 때문입니다. 반대로, 빈도가 낮을 경우에는 더 잘게 쪼개어 빈도가 높은 Token으로 만들어 주면 됩니다. Character 단위보다 Byte 단위까지 더 잘게 쪼개는 경우가 있습니다. 언어는 특정 단어는 더 작은 의미 단위의 의미들이 모여 단어가 형성됩니다. 따라서 단어보다 더 작은 의미 단위로 쪼개어 줄 수 있다면 좋을 것입니다. 이러한 역할을 해주는 알고리즘이 있습니다.

 

 

4. Byte Pair Encoding(BPE) Algorithm

학습 Corpus를 활용해 또 다른 전처리용 모델을 하나 만든다고 생각하면 됩니다. BPE 모델을 학습하여 train/test Corpus에 적용을 하는 것 입니다. 장단점과 학습 순서는 다음과 같습니다.

 

<장점>

- 언어별 특성에 대한 정보가 크게 없이, 더 작은 의미 단위로 쪼갤 수 있습니다.

- Sparse한 것을 Corpus 내에서 통계 기반하여 효과적으로 낮출 수 있습니다. 

- 영어 Corpus가 있는데 갑자기 아랍어 문자가 튀어나오는 것 아닌 이상, 우리가 본 문자 안에서 OoV를 없앨 수 있습니다. 

 

<단점>

- General 한 언어가 아닌, 내가 가진 학습 데이터 별로 BPE 모델을 생성해야 합니다. 모델도 반드시 들고 있어야 하는 문제가 있습니다. 

 

<학습 순서>

① 단어 사전 생성을 합니다.

② 위의 그림과 같이 Character 단위로 쪼갠 후 (위 그림 SEQUENCES 단계)

③ 위의 그림과 같이 Pair 별 빈도 Count를 합니다. (위 그림 DICTIONARY 단계)

④ 그 후, 최 빈도 Pair를 골라서 Merge를 수행합니다. (위 그림 DICTIONARY 단계)

⑤ Pair 별 빈도 Count를 업데이트 합니다.

⑥ ④ 과정을 반복합니다. 

이제 새 Text에 대한 적용은 각 단어를 Character 단위로 분절하여 단어 내에서 Train 과정에서 Merge에 활용된 Pair의 순서대로 Merge를 수행하면 됩니다.

 

5. 정리

BPE 압축 알고리즘을 통해 통계적으로 더 작은 의미 단위로 쪼개는 행위를 수행합니다. 이를 통해서 성능도 올리면서 OoV를 없앨 수 있습니다. 영어 같은 경우에는 바로 BPE를 쓰고, 다른 컨퍼런스 발표했을 때 봤었 던 것은 한국어 같은 경우에는 Mecab + BPE 조합을 사용한다고 합니다. 물론 한국어 같은 경우에도 바로 BPE를 쓰기도 합니다. 이 부분은 경험상 Corpus 별로 다 성능이 다 달랐으며 Mecab과 조합한 경우가 좋을 때 보다 그냥 BPE만 썼을 때 더 좋았던 경험이 더 많았습니다.

 

<Reference>

위의 그림은 NLP에서 상당한 유튜브라고 할 수 있는 Rasa 유튜브에서 일부 캡처하여 사용했음을 알립니다. 코딩하는 것도 영상에 나옵니다. 

 

https://youtu.be/-0IjF-7OB3s

https://youtu.be/kNw9dpzp5RU

 

profile

호돌찌의 AI 연구소

@hotorch's AI Labs

포스팅이 도움이 되셨다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!