- 본 글은 Tokenization에 대한 간단한 소개 및 예시를 다룹니다.
Tokenization(이후 토큰화)은 자연어 텍스트(corpus)를 토큰(token)이라는 단위로 쪼개는 작업을 의미합니다. 자연어처리와 관련된 대부분의 언어 모델들은 모두 토큰화을 활용합니다. 토큰화 방법에는 여러가지가 있습니다. Word Tokenization, Character Tokenization이 가장 기본적인 토큰화 방법입니다. 하지만, 두 방법 모두 단점이 명확해 최근에는 Subword Tokenization을 주로 사용합니다.
위에서 언급했듯 토큰화의 종류는 대표적으로 3가지가 존재합니다. 이 때 종류를 나누는 기준은 토큰으로 설정한 단위입니다. 대표적으로 Word, Character 그리고 그 중간 단계인 Subword가 있습니다. 먼저 3가지 토큰화에 대해 예시와 함께 간단히 설명하겠습니다.
먼저 Word Tokenizer에 대해 알아보겠습니다. 입력 데이터는 "The cat sat on the mat." 이라는 문장입니다. 단어 단위로 토큰화하면 "the", "cat", "sat", "on", "the", "mat", "."으로 나누어집니다.
다음으로 Character Tokenizer입니다. 입력 데이터로 "This is Tokenizing." 이라는 문장이 들어온다면, 모든 언어를Character 단위로 문장을 잘라 토큰화할 것입니다. 영어는 알파벳 한개씩 나누어 지고, 한국어는 음절로 나누거나 혹은 초성, 중성, 종성으로 나눕니다.
마지막으로 Subword Tokenizer입니다. Subword는 word와 character의 중간에 있는 단위입니다. 그림과 같이 Subword Level에서 "tokenizing"은 "token"과 "izing"으로 분리됩니다. 이 때 Subword를 어떻게 구성하는가에 대한 알고리즘이 다수 존재하며, 최근까지 많은 연구가 진행되고 있습니다.
위에서 설명 했듯이 Word, Character 단위의 토큰화는 문제가 있습니다. 먼저, Word를 기준으로 Tokenization를 할 때 생기는 대표적인 문제는 Out-Of-Vocabulary입니다. 주어진 모든 문장의 단어에 대해 단어사전을 형성하기 때문에 상당히 큰 메모리 공간이 필요합니다. 또한 신조어와 같이 단어사전을 형성할 때 존재하지 않았던 단어를 토큰화할 경우 <Unknown> 토큰으로 처리를 하게 됩니다.
다음으로 Character 기준으로 토큰화를 할 경우에는 성능의 문제가 발생합니다. 어떤 단어가 들어오더라도 단어를 Character Level로 이해하려고 하기때문입니다. 또한 긴 문장이 입력 데이터로 주어지면 Vanishing Gradient나 Memory문제가 발생할 수 있습니다.
Word와 Character의 문제를 해결하기 위해 나온 것이 Subword라는 개념입니다. Character level로 토큰화 할 때보다 Sequence가 짧고, Word level로 토큰화 할 때 보다 OOV문제가 감소듭니다. 예를 들어, "알잘딱깔센"이라는 단어는 Word level에서 <unknoun> 토큰으로 처리가 되겠지만, Subword level에서는 '알/잘/딱/깔/센/'으로 토큰화되어, '알다'의 '알', '잘하다'의 '잘', '딱 그랬다'의 '딱' 등으로 해석하여 처리할 것입니다. 이런 이유로 최근 대부분의 모델은 Subword level의 tokenizer를 사용합니다.
토큰화의 종류에 대해 대략적으로 살펴 보았으니, 이번에는 그 중 가장 중요하게 사용되는 Subword Tokenization에 대해 살펴보겠습니다.
Subword tokenization은 그림과 같이 다양한 알고리즘이 존재합니다. 가장 대표적으로 알려져 있는 알고리즘은 GPT등에 사용된 Byte-pair Encoding, BERT 등에 사용된 WordPiece, T5 등에 사용된 SentencePiece가 있습니다. 알고리즘 간 차이는 크게 없는 것으로 알려져 있습니다만, 필요하다면 관련 정보를 찾아보시길 바랍니다. 오늘 본 글에서는 Byte-pair Encoding에 대해 알아보겠습니다.
Byte-pair Encoding의 예시를 통해 한번 이해해보겠습니다. "aaabdaaabac"라는 문자열이 있습니다. 가장 많이 등장한 Pair인 'aa'를 'Z'로 바꾸어 줍니다. 그러면 문자열은 "ZabdZabac"가 됩니다. 다음으로 반복적으로 등장하는 pair는 'ab'이고, 이를 'Y'로 바꾸어주면 "ZYdZYac"가 됩니다. 다시 'ZY'를 'X'로 바꾸어주면 'XdXac'로 변화됩니다. 더 이상 반복되는 pair가 없으므로 최종적인 결과물은 'XdXac'이며 X= ZY, Y = ab, Z = aa가 됩니다. 이름으로 돌아가 Byte-pair Encoding의 Byte는 하나의 Character를 의미하고, 하나의 글자를 쌍으로 구성하기 때문에 Byte-pair라고 합니다.
위에서 설명한 내용을 토대로 Byte-pair Encoding을 구현한 것을 살펴보겠습니다. BPE 알고리즘은 두 가지 함수로 이루어져 있습니다. 문장에서 2개 character로 이루어진 pair의 개수를 계산하는 함수와 자주 등장한 pair를 합쳐 새로운 vocab을 생성하는 함수입니다. 위의 예시에서 단어 쌍 중 가장 많은 단어 쌍은 (e,s)입니다. 따라서 각 단어 'n_e_w_e_s_t', 'w_i_d_e_s_t'는 'n_e_w_es_t', 'w_i_d_es_t'로 바뀝니다. 반복을 통해 vocab = {'low', 'low_er', 'new _est', 'wid_est'}로 업데이트될 것입니다. 만약 새로운 단어 'lowest'가 입력된다면 <unknoun> 토큰 대신 {'low', 'est'}로 표현될 것입니다.
BERT (0) | 2023.01.09 |
---|---|
Transformer (0) | 2023.01.06 |
Normalization and Pre-Tokenization (0) | 2023.01.03 |
LSTM 연습 (0) | 2023.01.01 |
Word2Vec Practice (0) | 2022.12.27 |
댓글 영역