SKT-AI / KoGPT2

Korean GPT-2 pretrained cased (KoGPT2)
Other
532 stars 98 forks source link

Using PreTrainedTokenizer instead of PreTrainedTokenizerFast #40

Closed jucho2725 closed 3 years ago

jucho2725 commented 3 years ago

안녕하세요 먼저 ver2 모델을 공유해주셔서 감사합니다

공개하신 모델을 사용해보고 있는데, PreTrainedTokenizerFast 대신 PreTrainedTokenizer 로 변경이 가능한지 문의 드리고 싶습니다

제가 아는 한 add_prefix_space는 토크나이저에서 encoding 을 수행할 때 space 를 part of a token이라고 표현하는 방식입니다. 이로인해 공백 여부에 따라서 토큰 인덱스가 달라질 수 있고, 만약 그럴시 모델의 성능에 영향을 미칩니다.

관련하여 간단한 코드 실행 예시를 첨부합니다 image

현재 PreTrainedTokenizerFast 에선 _batch_encode_plus() 에서 **kwargs 가 없습니다. 따라서 GPT2Tokenizer 와 달리 add_prefix_space 인자를 넘겨주질 못하고 이와 같은 오류가 발생합니다.

  File "test.py", line 392, in <listcomp>
    [tokenizer.encode(word.strip(), add_prefix_space=True)]
  File "/root/.local/lib/python3.8/site-packages/transformers/tokenization_utils_base.py", line 2059, in encode
    encoded_inputs = self.encode_plus(
  File "/root/.local/lib/python3.8/site-packages/transformers/tokenization_utils_base.py", line 2378, in encode_plus
    return self._encode_plus(
  File "/root/.local/lib/python3.8/site-packages/transformers/tokenization_utils_fast.py", line 458, in _encode_plus
    batched_output = self._batch_encode_plus(
TypeError: _batch_encode_plus() got an unexpected keyword argument 'add_prefix_space'

제 생각에는 add_prefix_space 가 애초에 False 또는 애초에 없는 토크나이저(PreTrainedTokenizerFast)를 사용해 학습한 현재 모델 'skt/kogpt2-base-v2'가 나중에 특정 목적으로 토크나이저로 사용할 시 문제가 생기리라고 생각합니다.

예상되는 하나의 문제는 토크나이저를 encode 할때 가장 처음 오는 토큰은 이것이 하나의 단어인지 아니면 뒤에 어미가 붙는 형태의 동사인지를 알수 없다는 것입니다. 아래 예시를 첨부합니다

만약 제 생각이 맞다면 PreTrainedTokenizer또는 이를 상속받는 GPT2Tokenizer로 대체시킬 수 있을까요?

haven-jeon commented 3 years ago

https://huggingface.co/skt/kogpt2-base-v2/raw/main/tokenizer.json 보시면 아래와 같은 add_prefix_space 옵션이 적용되어 있습니다.

image

jucho2725 commented 3 years ago

빠른 답변 감사드립니다! 제가 json 형식의 파일을 보는 방법을 몰랐군요. add_prefix_space 가 True 인 것을 확인하였습니다.

위 글 하단에 예상되는 문제라는 부분을 보시면 예시를 첨부하려고 했는데, 추가하는 것을 깜빡했네요. 따라서 아래 예시를 첨부합니다.

from transformers import PreTrainedTokenizerFast
fast = 'skt/kogpt2-base-v2'
tokenizer1 = PreTrainedTokenizerFast.from_pretrained(fast)
print(tokenizer1.tokenize("마름모")) 
print(tokenizer1.tokenize("마름"))   
>> ['▁마름', '모']
>> ['▁마름']
from transformers import PreTrainedTokenizerFast
fast = 'gpt2-medium'
tokenizer= GPT2Tokenizer.from_pretrained(fast)
print(tokenizer.tokenize("misinformation", add_prefix_space=True))    # 
print(tokenizer.tokenize("misinformation", add_prefix_space=False))  # 
print(tokenizer.tokenize("mis", add_prefix_space=False))
>> ['Ġmisinformation']     
>> ['mis', 'information']
>> ['mis']

1번째 예시를 보시면 "마름모" 와 "마름"을 같은 "_마름"로 인식하는 것을 알 수 있습니다. 이를 add_prefix_space 에 따라 2번째 예시와 같이 하나의 토큰으로 만들어줄 수 있습니다. 이와 같은 옵션이 링크와 같은 방식으로 사용되는 경우가 있기 때문에 이슈를 열었습니다. 그러나 찾아보니 다른 한국어 토크나이저들도 모두 fast 를 사용하고 이에 대한 문제제기가 딱히 없는 것 같네요.

모델의 문제가 아니므로 이슈를 닫아주셔도 됩니다 그래도 관련하여 의견을 남겨주시면 큰 도움이 될 것 같습니다 :)

haven-jeon commented 3 years ago

네 감사합니다. ^^