본문 바로가기
Pytorch

Huggingface 토크나이저 학습 실험

by 객잔주인 2024. 2. 25.

Gemini가 그린 tokenizer

Huggingface의 transformers 라이브러리에서는 사전학습된 토크나이저를 불러올 수 있습니다

from transformers import AutoTokenizer

checkpoint = 'klue/bert-base'
tokenizer = AutoTokenizer.from_pretrained(checkpoint)

 

또한 사전학습된 토크나이저를 다시 재학습 시키는 것 또한 가능합니다

new_tokenizer = tokenizer.train_new_from_iterator(training_corpus, 32000)

 

tokenizer의 train_new_from_iterator 메서드를 사용해서 데이터 이터레이터와 vocab size를 전달하면 원하는 데이터에 맞게 토크나이저를 재학습할 수 있습니다

 

(iterator 전달하는 방법, 더보기 참조)

더보기
def get_training_corpus():
    return (
        raw_datasets["train"][i : i + 1000]["whole_func_string"]
        for i in range(0, len(raw_datasets["train"]), 1000)
    )


training_corpus = get_training_corpus()

 

기계독해 프로젝트를 진행하면서 우리가 모은 데이터셋에 더 맞게 토크나이저를 학습시키면 독해 성능이 더 올라가지 않을까? 하는 생각을 하게되었습니다

 

약 7.5만개의 context 데이터데 대해 사전학습을 진행했고 덕분에 UNK 토큰 비율은 약 5%에서 0.0%로 하락했습니다

 

그래서 우리가 사용하는 데이터셋에 더 적합한 토크나이저를 얻었다고 생각했고 evaluation을 했으나 성능은 f1 스코어 기준으로 약 1/5까지 하락했고, Exact Match는 1/8까지 하락했습니다

 

그 이유를 분석하기 위해 새로 학습한 new_tokenizer의 vocab을 살펴본 결과 같은 어근을 가지는 단어들이 서로 다른 토큰으로 존재했습니다.

 

예를 들어, '받아', '받고', '받으니', '받자'와 같이 어근은 같고 접사가 다른 단어들이 독립적으로 토큰으로 인정되는 것이었습니다.

 

그에 반해 기존의 토크나이저는 어근인 '받'과 접사인 '##아', '##고', '##으니', '##자'를 따로 토크나이징 합니다

 

이 둘의 차이는 모델학습을 할 때에 나타납니다. 설명을 위해 임의로 만든 문장 4개를 예시로 사용하겠습니다

1. 옆집에서 소금을 받아 어머니께 건넸다
2. 돈을 받고 물건을 건넸다
3. 월급을 받으니 기분이 상쾌하고 좋아졌다
4. 주무관의 전화를 받자 선임의 표정이 굳었다

 

모델 학습을 위해 위 네 문장을 사용한다고 할 때 새로 학습된 토크나이저를 사용하는 경우 '받아', '받고', '받으니', '받자'에 대한 가중치는 각각 한 번씩 업데이트 됩니다.

 

그러나 기존 토크나이저를 사용하는 경우 '받'에 대한 가중치는 네 번 업데이트 되고 '##아', '##으니', '##자'는 각각 한 번씩, '##고는' 2번과 3번 문장에서 한 번씩 업데이트 되어 두 번 업데이트 됩니다.

 

즉, 더 단어를 작은 단위로 분절시킬 수 있는 기존 토크나이저를 사용할 때 어근과 접사는 더 많은 학습 기회를 가지게 되고 더 풍부한 표현력을 가지게 됩니다

 

따라서 토크나이저 재학습은 학습에 활용될 데이터셋의 크기가 충분히 크고, 특정한 분야에 특화된 토크나이저가 필요할 때에만 하는 게 좋다는 결론을 내리게 되었습니다

'Pytorch' 카테고리의 다른 글

Tensor 연산에서 dimension을 지정하는 것에 관하여  (0) 2023.12.29