SKTBrain / KoBERT

Korean BERT pre-trained cased (KoBERT)
Apache License 2.0
1.3k stars 368 forks source link

save_pretrained() 에 NotImplemented Error 발생 #65

Closed seunggyu-42maru closed 3 years ago

seunggyu-42maru commented 3 years ago

안녕하세요. 먼저 좋은 모델을 공개해주셔서 감사합니다.

모델의 토크나이저를 사용하는 도중 에러가 발생하여 이슈를 남깁니다.

환경

오류가 발생한 코드

(일부 불필요한 내용은 생략하였습니다)

import kobart
from transformers import AutoTokenizer
if not os.path.exists("./kobart_tokenizer"):
    os.makedirs("./kobart_tokenizer")
dummy_tokenizer = kobart.get_kobart_tokenizer() 
dummy_tokenizer.save_pretrained("./kobart_tokenizer/") # 이곳에서 에러 발생
tokenizer = AutoTokenizer.from_pretrained("./kobart_tokenizer")

오류 내용

Traceback (most recent call last):
  File "misc.py", line 23, in <module>
    dummy_tokenizer.save_pretrained("./kobart_tokenizer/")
  File ".../venv/lib/python3.6/site-packages/transformers/tokenization_utils_base.py", line 1992, in save_pretrained
    filename_prefix=filename_prefix,
  File ".../venv/lib/python3.6/site-packages/transformers/tokenization_utils_fast.py", line 535, in _save_pretrained
    vocab_files = self.save_vocabulary(save_directory, filename_prefix=filename_prefix)
  File ".../venv/lib/python3.6/site-packages/transformers/tokenization_utils_base.py", line 2044, in save_vocabulary
    raise NotImplementedError
NotImplementedError

추가 설명

이 오류는 다음과 같은 코드에서 발생한 pickle 에러를 해결하려던 도중 발견하였습니다.

tokenizer = kobart.get_kobart_tokenizer()
def preprocess(sample):
    global tokenizer
    return tokenizer(sample)

# 생략

def main():
    # 생략
    dataset = dataset.map(preprocess, batched=True)

를 진행할 시, map 이 있는 라인에서 pickling Error가 발생합니다. (에러 내용이 너무 길어 일부 생략하고 마지막 부분만 기입합니다)

File ".../venv/lib/python3.6/pickle.py", line 927, in save_global
    (obj, module_name, name))
_pickle.PicklingError: Can't pickle <class 'transformers.tokenization_utils_fast.PreTrainedTokenizerFast'>: it's not the same object as transformers.tokenization_utils_fast.PreTrainedTokenizerFast

이 문제를 회피하는 방법 중에 하나로, preprocess(sample) 안에서 get_kobart_tokenizer()를 하는 방법이 있었습니다만 매번 토크나이저를 불러오게 되어 굉장히 느리고 비효율적이라고 판단되었습니다. huggingface에서 제공하는 다른 tokenizer의 경우, 위와 같이 하나의 토크나이저를 미리 선언해둔 후 map에서 사용하여도 아무런 문제가 발생하지 않았습니다. 이를 해결하려고 tokenizer를 일단 불러온 후, save_pretrained() 를 하고 다시 AutoTokenizer.from_pretrained() 로 가져와서 실행해보려던 중 NotImplementedError가 발생하였습니다. 맥락이 다를 수는 있지만 아무래도 not the same object as ...PreTrainedTokenizerFast 부분이, 토크나이저의 일부가 구현되지 않아 생기는 오류일 수 있다는 생각에 이슈에 같이 기입하였습니다.

haven-jeon commented 3 years ago

KoBART쪽 이슈로 보입니다.

seunggyu-42maru commented 3 years ago

앗 죄송합니다 😅 탭을 여러개 띄우다 보니 햇갈렸네요. 내용 정리하여 KoBART로 올려두겠습니다. 실례했습니다!