# KoBERT, XLM-R 모델 비교
- 작성일: 2021년 7월 14(수)
## 데이터 소개
- ppl계산과 fine-tuning에는 Kornli 데이터를 이용
- kornli는 총 942,854개 train 데이터, 2,490개 val 데이터, 5,010개 test 데이터가 있음.
- 상세 내용은 아래 표 참조

- 출처: https://github.com/kakaobrain/KorNLUDatasets
## KoBERT, XLM-R tokenizer 차이 (intrinsic 비교)
- colab 코드 위치: https://colab.research.google.com/drive/1yLhHEt_Wy1Chq3VR2QNU7Y4kUV5X1cvn?usp=sharing
- 아래 tokenizer 예시를 보면 KoBERT가 문장을 제대로 토큰나이징하지 못하여, XLM-R 모델 대비 [UNK] 토큰이 많이 발생하는 것을 볼 수 있다.
```
원래 문장1: 솔직히 말해서, 정말 두렵다.
kobert : ['▁', '솔', '직', '히', '▁말', '해서', ',', '▁정말', '▁두', '렵', '다', '.']
xlm-r : ['▁솔직', '히', '▁말', '해서', ',', '▁정말', '▁두', '렵', '다', '.']
원래 문장2: 백악관은 FBI를 적절하게 이용하고 있다.
kobert : ['▁백악관', '은', '▁F', 'B', 'I', '를', '▁적절', '하게', '▁이용', '하고', '▁있다', '.']
xlm-r : ['▁백', '악', '관', '은', '▁FBI', '를', '▁적', '절', '하게', '▁이용', '하고', '▁있다', '.']
원래 문장3: 좋은 아침입니다, 라고 그는 말했고, 내가 심하게 실수했다고 덧붙여서 그렇게 했습니다.
kobert : ['▁좋은', '▁아침', '입니다', ',', '▁', '라고', '▁그는', '▁말', '했고', ',', '▁내가', '▁심', '하게', '▁실수', '했다고', '▁', '덧', '붙', '여', '서', '▁그렇게', '▁', '했습니다', '.']
xlm-r : ['▁좋은', '▁아침', '입니다', ',', '▁', '라고', '▁그는', '▁말', '했고', ',', '▁내가', '▁심', '하게', '▁실', '수', '했다고', '▁', '덧', '붙', '여', '서', '▁그렇게', '▁', '했습니다', '.']
원래 문장4: 나도 그 분위기가 좋아.
kobert : ['▁나', '도', '▁그', '▁분위기', '가', '▁좋아', '.']
xlm-r : ['▁나', '도', '▁그', '▁분위기', '가', '▁좋아', '.']
원래 문장5: 그는 그녀보다 훨씬 어렸다.
kobert : ['▁그는', '▁그녀', '보다', '▁훨씬', '▁어', '렸다', '.']
xlm-r : ['▁그는', '▁그녀', '보다', '▁훨씬', '▁어', '렸다', '.']
```
## 구현 내용
1. Kornli 데이터를 대상으로 pre-train 된 BERT와 XLM-R 모델 ppl 계산
- kornli 데이터셋 중 중복된 sentence는 제거하여 사용
- kornli train 데이터 대상으로 ppl 계산
- kornli train 데이터 중 10,000개 데이터 사용하여 ppl 계산 (train 데이터를 전부 사용 시 시간이 지나치게 많이 소요되어 일부 데이터만 이용)
- kornli val 데이터 대상으로 ppl 계산
- 전체 kornli val 데이터 2,490개를 사용하여 ppl 계산
- kornli test 데이터 대상으로 ppl 계산
- 전체 kornli test 데이터 5,010개를 사용하여 ppl 계산
2. KoBERT와 XLM-R 모델을 Kornli 학습데이터로 fine-tuning / 학습 과정의 loss, learning rate, train/val accuracy 시각화
- kornli 학습 데이터는 약 94만개 정도로, colab의 gpu를 이용하여 전체 데이터 학습 시 12시간이상 필요하기 때문에, 전체 데이터셋 중 9만개 데이터를 학습에 사용 1개의 모델에 1~2시간 소요
- 학습 파라미터는 KoBERT와 XLM-R 모델에 동일하게 적용
- max_seq_length: 128
- batch_size: 32
- learning_rate: 2e-5
- num_train_epochs: 3
- eval_steps: 1000
- max_train_samples: 90000
## 결과 정리
### PPL 측정 결과
- Kornli 데이터 별 ppl 측정 값

## Kornli 학습 시각화 정리
- eval accuracy

- eval loss

- train loss

- train learning rate

## 코드 실행 방법
### 사전 준비
- colab에 프로젝트 생성 및 런타임 유형 gpu로 설정
- colab 연결 유지 및 출력 삭제 설정
- https://hanryang1125.tistory.com/31
- requirements.txt, run_ppl.py, run_kornli.py, run_tokenizer 파일 업로드
### ppl 계산
- colab 코드 위치: https://colab.research.google.com/drive/1OJ_LqZ47l2iuWgWbTCzVb5UUJj4zxxmc?usp=sharing
- 위 코드 실행 후, ppl_result.png의 실행 결과 확인
### kornli 학습
- colab 코드 위치: https://colab.research.google.com/drive/1bGHUbTM4OSU6czjROPNnYq6itxQDKHXP?usp=sharing
- 위 코드 실행 후, 다운로드 되는 파일을 로컬에서 tensorboard로 학습 과정 시각화
- tensorboard 실행 방법
```
tensorboard --logdir={output 파일 디렉토리 위치}
```
- tensorboard 실행 후, http://localhost:6006 로 접속
<!-- ## 구현방식
- Pre-train 된 KoBERT, XLM-R 모델을 대상으로
- Kornli 학습
- KoBERT
```
- 안되는 거 (패팅 때문에)
python run_kornli.py \
--model_name_or_path skt/kobert-base-v1 \
--do_train \
--do_predict \
--max_seq_length 128 \
--per_device_train_batch_size 1 \
--learning_rate 2e-5 \
--num_train_epochs 3 \
--output_dir ./output/ \
--cache_dir ./cache/
- 테스트
python run_kornli.py \
--model_name_or_path monologg/kobert \
--do_train \
--do_eval \
--do_predict \
--max_seq_length 128 \
--per_device_train_batch_size 1 \
--per_device_eval_batch_size 1 \
--learning_rate 2e-5 \
--num_train_epochs 2 \
--output_dir ./output/kobert/ \
--cache_dir ./cache/kobert/ \
--report_to tensorboard \
--evaluation_strategy steps \
--eval_steps 5 \
--metric_for_best_model accuracy \
--logging_steps 5 \
--seed 4 \
--max_train_samples 10 \
--load_best_model_at_end true
- 진짜
python run_kornli.py \
--model_name_or_path monologg/kobert \
--do_train \
--do_predict \
--max_seq_length 128 \
--per_device_train_batch_size 32 \
--per_device_eval_batch_size 32 \
--learning_rate 2e-5 \
--num_train_epochs 3 \
--output_dir ./output/ \
--cache_dir ./cache/ \
--report_to tensorboard \
--evaluation_strategy steps \
--eval_steps 1000 \
--save_steps 10000 \
--logging_steps 1000
--seed 4
python run_kornli.py \
--model_name_or_path monologg/kobert \
--do_train \
--do_predict \
--max_seq_length 128 \
--per_device_train_batch_size 1 \
--per_device_eval_batch_size 1 \
--learning_rate 2e-5 \
--num_train_epochs 3.0 \
--output_dir ./output-test/ \
--cache_dir ./cache/ \
--report_to tensorboard \
--save_steps 10 \
--evaluation_strategy epoch \
--logging_steps 10 \
--seed 4 \
--load_best_model_at_end true
- tensorboard
tensorboard --logdir=./output/runs
```
- XLM-R
```
-진짜
python run_kornli.py \
--model_name_or_path xlm-roberta-base \
--do_train \
--do_predict \
--max_seq_length 128 \
--per_device_train_batch_size 32 \
--per_device_eval_batch_size 32 \
--learning_rate 2e-5 \
--num_train_epochs 3 \
--output_dir ./output/xlm-r/ \
--cache_dir ./cache/xlm-r/ \
--report_to tensorboard \
--evaluation_strategy steps \
--eval_steps 1000 \
--save_steps 10000 \
--logging_steps 1000
--seed 4
python run_kornli.py \
--model_name_or_path xlm-mlm-tlm-xnli15-1024 \
--do_train \
--do_predict \
--max_seq_length 128 \
--per_device_train_batch_size 16 \
--learning_rate 2e-5 \
--num_train_epochs 3 \
--output_dir ./output/xlm/ \
--cache_dir ./cache/xlm \
--report_to tensorboard \
--evaluation_strategy steps \
--eval_steps 1000 \
--save_steps 1000 \
--logging_steps 1000 \
--seed 4
python run_kornli.py \
--model_name_or_path xlm-roberta-base \
--do_train \
--do_eval false\
--do_predict false\
--max_seq_length 128 \
--per_device_train_batch_size 1 \
--per_device_eval_batch_size 1 \
--learning_rate 2e-5 \
--num_train_epochs 2 \
--output_dir ./output/xlm-r/ \
--cache_dir ./cache/xlm/ \
--report_to tensorboard \
--evaluation_strategy steps \
--eval_steps 5 \
--metric_for_best_model accuracy \
--logging_steps 5 \
--seed 4 \
--max_train_samples 10 \
--load_best_model_at_end true
python run_kornli.py \
--model_name_or_path xlm-mlm-tlm-xnli15-1024 \
--do_train \
--do_eval \
--do_predict \
--max_seq_length 128 \
--per_device_train_batch_size 5 \
--per_device_eval_batch_size 5 \
--learning_rate 2e-5 \
--num_train_epochs 2 \
--output_dir ./output/xlm/ \
--cache_dir ./cache/xlm/ \
--report_to tensorboard \
--evaluation_strategy steps \
--eval_steps 5 \
--metric_for_best_model accuracy \
--logging_steps 5 \
--seed 4 \
--max_train_samples 10 \
--load_best_model_at_end true
python glue-xnli.py \
--exp_name test_xnli_mlm_tlm \
--dump_path ./dumped/ \
--model_path mlm_tlm_xnli15_1024.pth \
--data_path ./data/processed/XLM15 \
--transfer_tasks XNLI \
--optimizer_e adam,lr=0.000025 \
--optimizer_p adam,lr=0.000025 \
--finetune_layers "0:_1" \
--batch_size 8 \
--n_epochs 250 \
--epoch_size 20000 \
--max_len 256 \
--max_vocab 95000
```
- ppl

```
- kobert
- xlm
```
개발 내용 공유 드립니다.
일단 저는 huggingface에서 xnli 데이터를 사용하여 BERT를 fine-tuning하는 코드를 kornli에 맞게 수정하여 사용했습니다.
huggingface에서 xnli를 학습하는 코드 보면, xnli 학습 시에 train/val loss, accuracy는 학습 중 측정되지만, ppl은 측정되지 않습니다. 그리고 xnli, kornli fine-tuning task에는 ppl이 측정되지 않는 게 정상입니다. ppl은 pretrain task에서 측정되는데, pretrain을 위해서는 10GB이상의 대량의 학습을 TPU에서 1달이상을 학습시켜야 합니다.
그래서 저는 이미 pretrain되어 있는 모델을 대상으로 ppl을 계산하게끔 했고, 모델과 kornli 데이터를 넣으면, 해당 모델의 ppl 값이 측정되게 했습니다.
kobert와 xlm-r 성능을 비교하실 거면, 이미 pre-train된 모델을 대상으로 측정한 ppl 값과, fine-tuning시의 train/val loss, accuracy를 비교하면 될 거 같습니다.
내일 오전에 학습 파라미터 등 추가 공유사항이나 소스코드도 공유 드리겠습니다.
-->