반응형


 

자체 데이터로 Bert Training 하기

 

이전 글에서는, Corpus 전처리 하는 방법

2021.07.26 - [Machine Learning/BERT 학습] - [Python / NLTK] 텍스트 파일 문장 단위로 분해하기 (Sentence Tokenize)

 

[Python / NLTK] 텍스트 파일 문장 단위로 분해하기 (Sentence Tokenize)

 NLTK 사용하여 .txt파일 문장 단위로 쪼개기 딥러닝 모델들이 사용하는 Corpus 파일들은 대부분 Sentence 단위로 학습을 진행하고, 이를 위해서라도 Sentence 단위별로 나눠주는 것이 편리하다. NLTK를

cryptosalamander.tistory.com

 

자체 데이터로 BertTokenizer 학습하는 방법

2021.07.25 - [Machine Learning/BERT 학습] - [Pytorch / Huggingface] Custom Dataset으로 BertTokenizer 학습하기

 

[Pytorch / Huggingface] Custom Dataset으로 BertTokenizer 학습하기

자체 데이터셋으로 BertTokenizer 학습하기 이번 게시글에서는 Pretrained Weight를 이용하지 않고, 특정 Domain에 맞도록 직접 Custom Dataset을 통해 BertTokenizer를 학습시키는 방법을 다룬다. 현재 진행하고..

cryptosalamander.tistory.com

 

두가지 내용을 다뤘다. 이제 Sentence 단위로 나눠진 Corpus 파일과, 직접 구현한 BertTokenizer를 통해 BERT를 GPU를 사용하여 학습해보자.

 

Requirements


$git clone https://github.com/huggingface/transformers.git
$cd transformers
$pip install -e .

 

Bert를 학습시키는 코드까지 포함하여 huggingface의 transformer 깃허브 레포지토리를 통째로 다운 받은 후, pip install 을 통해 transformers를 설치시켜준다. 

 

 

Training


transformers 레포지토리 내부에 examples/pytorch/language-modeling/run_mlm.py 통해서 학습을 진행할 수 있다.

하지만 그전에 먼저 체크해야할 것이 있다.

해당 파일의 check_min_version에 dev가 붙어있다면, master branch가 아니라 가장 최근 release 된 Tag를 찾아 다시 다운받아야한다. 

<포스팅 당시의 가장 최근 Release Tag 버전>

 

<master branch로 받았을 때 모습>

마스터 브랜치로 다운받았는데, dev0가 붙어있다면 개발자들이 내부적으로 테스팅을 진행하고 있는 단계로, 정상적으로 동작이 되질 않는다. 이를 방지하기 위해서라도 tag를 확인하도록 하자.

 

그 후, 코드는 바꿀 필요 없이 인자값만 전달하여 학습을 진행하면 된다.

 

 

주요 인자에 대해 설명은 다음과 같다.

--model_name_or_path : 기존 모델의 weight를 불러온 뒤, 전이학습을 할 때 사용된다.

https://huggingface.co/transformers/pretrained_models.html

 

Pretrained models

Here is a partial list of some of the available pretrained models together with a short presentation of each model. For the full list, refer to https://huggi...

huggingface.co

위 링크에 기술된 식별자를 통해서 모델을 불러올 수 있다. 

--model_type : pretrained weight 없이 구조만 가져와서 처음부터 학습을 진행할 시 사용된다. 본 포스팅에서는 bert를 학습하므로, bert를 입력하면 된다.

 

--tokenizer_name: pretrained tokenizer를 불러오거나, tokenizer가 저장된 폴더의 경로를 전달하여 tokenizer를 불러온다. 기본적으로, tokenizer_config.json, vocab.txt, special_tokens_map.json을 불러오며, 이는 이전 포스팅에서 학습한 tokenizer를 저장한 경로에 존재한다.

 

--max_seq_length : input으로 사용될 문장의 길이 한도를 의미한다. bert-based 모델은 512를 사용하므로 512를 입력

 

--train_file : 학습에 사용될 Corpus 데이터를 전달하면 된다.

 

--validation_file : validation 과정에 사용될 Corpus 데이터 경로를 전달하면 된다.

 

--validation_split_percentage : 별도의 validation_file이 없을 경우, train set에서 몇퍼센트를 추출하여 validation_set으로 활용한다. 10정도 입력하면 적절하다.

 

--cache_dir : 전처리된 임시 파일, 로그, checkpoint등이 저장될 경로, 입력하지 않으면 기본값인 nltk_data cache로 가지만, 지정해주면 해당 경로에 저장된다. 생각보다 용량이 커질 수 있으므로 용량이 넉넉한 파티션에 지정하는 것이 좋다.

 

--preprocessing_num_workers : 전처리에 사용할 프로세스의 개수이다. CPU Core수에 맞게 적절히 세팅해주면 좋다. 
기본값으로 돌릴 시 47시간 걸리던 전처리가, num_workers를 16으로 해줬더니 10시간으로 줄어들었다. 하지만 너무 클 경우 CPU와 메모리에 부하가 크므로, CPU 사양을 고려하여 설정해야한다.

 

--line_by_line : 문장이 라인 단위로 쪼개져있는 Corpus에서 사용한다. 기본적으로 False 상태로 되어있다. 기본적으로 huggingface에서는 line_by_line이 꺼져있으면, 문장들을 합친 뒤 512를 넘기지 않도록 적절히 chunks를 만들고 이를 이용해 학습을 진행한다. line_by_line은 왠만하면 키지 않는 것이 좋다. 오용될 경우, Corpus에 불필요한 [PAD]가 매우 많이 발생하기 때문이다.

 

--pad_to_max_length : 512보다 짧은 문장에 padding을 추가하여 512로 만들어준다. 기본적으로 켜주는게 좋지만, 잘못된 방식으로 line_by_line과 함께 사용될 경우, 전체 데이터 단어 1개에 [PAD] 토큰 99개가 붙는 최악의 상황이 발생할 수 있다. 

 

--per_device_train_batch_size : 말 그대로 train batch size

 

--per_device_eval_batch_size : eval batch size

 

--save_steps : 몇 step 마다 저장할 것인지, 기본값은 5000이지만, Corpus가 크다면 넉넉히 설정하는게 좋다. 너무 자주 저장되면 checkpoints 용량도 어마어마하게 크기 때문이다.

 

 

Example 


$python ./examples/pytorch/language-modeling/run_mlm.py \
  --max_seq_length 512 \
  --pad_to_max_length \
  --logging_dir ./tensorboard-metrics \
  --cache_dir /mnt/disks/sdc/cache_dir \
  --train_file ./train.txt \
  --tokenizer_name ./mytokenizer/ \
  --preprocessing_num_workers 8 \
  --do_train \
  --do_eval \
  --model_type bert \
  --validation_split_percentage 10 \
  --overwrite_output_dir \
  --output_dir my-bert \
  --num_train_epochs 3 \
  --per_device_train_batch_size 8 \
  --per_device_eval_batch_size 8 \
  --save_steps 500000

 

위와 같은 방식으로 학습을 진행할 수 있다. 

--tokenizer_name에는 기존 pretrained tokenizer들을 쓸 수도 있지만, 자체 데이터에 가장 잘맞는 tokenizer를 학습한 뒤, 이를 불러와서 사용하는 것이 가장 좋으므로, 이전 포스팅에서 저장한 tokenizer를 불러오도록 하자.

 

Corpus 크기가 크다면, 학습과 전처리에 상당히 많은 시간이 소요되므로 유의하자.

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,