[Pytorch / Huggingface] Custom Dataset으로 Bert 학습하기 - GPU
Machine Learning/BERT 학습 2021. 7. 26. 06:10
자체 데이터로 Bert Training 하기
이전 글에서는, Corpus 전처리 하는 방법
2021.07.26 - [Machine Learning/BERT 학습] - [Python / NLTK] 텍스트 파일 문장 단위로 분해하기 (Sentence Tokenize)
자체 데이터로 BertTokenizer 학습하는 방법
두가지 내용을 다뤘다. 이제 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를 찾아 다시 다운받아야한다.
마스터 브랜치로 다운받았는데, dev0가 붙어있다면 개발자들이 내부적으로 테스팅을 진행하고 있는 단계로, 정상적으로 동작이 되질 않는다. 이를 방지하기 위해서라도 tag를 확인하도록 하자.
그 후, 코드는 바꿀 필요 없이 인자값만 전달하여 학습을 진행하면 된다.
주요 인자에 대해 설명은 다음과 같다.
--model_name_or_path : 기존 모델의 weight를 불러온 뒤, 전이학습을 할 때 사용된다.
https://huggingface.co/transformers/pretrained_models.html
위 링크에 기술된 식별자를 통해서 모델을 불러올 수 있다.
--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 크기가 크다면, 학습과 전처리에 상당히 많은 시간이 소요되므로 유의하자.