ํํ ๋ฆฌ์ผ: ์คํ์ธ์ด์ฉ RoBERTa ์ธ์ด ๋ชจ๋ธ ํ๋ จ ๋ฐฉ๋ฒ
SpanBERTa: RoBERTa ์คํ์ธ์ด ์ธ์ด ๋ชจ๋ธ์ ์ฒ์๋ถํฐ ํ์ต์ํจ ๋ฐฉ๋ฒ
Skim AI์ ๋จธ์ ๋ฌ๋ ์ฐ๊ตฌ ์ธํด์ธ ํฌ๋ฆฌ์ค ํธ๋์ด ์ฒ์ ๊ฒ์ํ์ต๋๋ค.
์๊ฐ¶
ํธ๋์คํฌ๋จธ ๋ชจ๋ธ์ ์ฌ์ฉํ ์๊ฐ ํ์ต ๋ฐฉ๋ฒ์ ๋๋ถ๋ถ์ NLP ์์ ์์ ์ต์ฒจ๋จ ์ฑ๋ฅ์ ๋ฌ์ฑํ์ต๋๋ค. ๊ทธ๋ฌ๋ ํ๋ จ์๋ ๊ณ์ฐ ๋น์ฉ์ด ๋ง์ด ๋ค๊ธฐ ๋๋ฌธ์ ํ์ฌ ์ฌ์ฉ ๊ฐ๋ฅํ ๋๋ถ๋ถ์ ์ฌ์ ํ๋ จ๋ ํธ๋์คํฌ๋จธ ๋ชจ๋ธ์ ์์ด ์ ์ฉ์ ๋๋ค. ๋ฐ๋ผ์ ์คํ์ธ์ด ํ๋ก์ ํธ์์ NLP ์์ ์ ์ฑ๋ฅ์ ๊ฐ์ ํ๊ธฐ ์ํด ์ ํฌ ํ์ ์คํค๋ฐ AI ํ๋ จํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. RoBERTa ์คํ์ธ์ด์ฉ ์ธ์ด ๋ชจ๋ธ์ ์ฒ์๋ถํฐ ์๋ก ๋ง๋ค์ด์ SpanBERTa๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
SpanBERTa๋ RoBERTa-base์ ํฌ๊ธฐ๊ฐ ๋์ผํฉ๋๋ค. RoBERTa์ ํ๋ จ ์คํค๋ง๋ฅผ ๋ฐ๋ผ 18GB์ OSCAR์ ์คํ์ธ์ด ๋ง๋ญ์น๋ฅผ 4๊ฐ์ ํ ์ฌ๋ผ P100 GPU๋ฅผ ์ฌ์ฉํด 8์ผ ๋ง์ ์์ฑํ์ต๋๋ค.
์ด ๋ธ๋ก๊ทธ ๊ฒ์๋ฌผ์์๋ ๋ค์์ ์ฌ์ฉํ์ฌ BERT์ ์ ์ฌํ ์ธ์ด ๋ชจ๋ธ์ ์ฒ์๋ถํฐ ํ์ตํ๋ ์๋ํฌ์๋ ํ๋ก์ธ์ค๋ฅผ ์๋ดํฉ๋๋ค. ํธ๋์คํฌ๋จธ
๋ฐ ํ ํฐํ ๋๊ตฌ
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด ๊ธ์ ์ฝ๋๋ฅผ ์ง์ ์คํํ ์ ์๋ Google Colab ๋
ธํธ๋ถ๋ ์์ต๋๋ค. ๋
ธํธ๋ถ์ ์ ์ ํ ์์ ํ์ฌ ๋ค๋ฅธ ์ธ์ด์ ๋ํด BERT์ ์ ์ฌํ ๋ชจ๋ธ์ ํ๋ จํ๊ฑฐ๋ ์ฌ์ฉ์ ์ง์ ๋ฐ์ดํฐ ์ธํธ์์ ๋ฏธ์ธ ์กฐ์ ํ ์๋ ์์ต๋๋ค.
๊ณ์ ์งํํ๊ธฐ ์ ์ ๋ชจ๋ ์ฌ๋์ด ์ต์ฒจ๋จ NLP ๋ชจ๋ธ์ ์ด์ฉํ ์ ์๋๋ก ํด์ค Hugging Face ํ์๊ฒ ํฐ ๊ฐ์ฌ๋ฅผ ํํ๊ณ ์ถ์ต๋๋ค.
์ค์ ¶
1. ์ค์น ์ข ์์ฑ¶
0]์ ์ ๋ ฅํฉ๋๋ค:
%pture !.pip uninstall -y tensorflow !.pip ์ค์น ํธ๋์คํฌ๋จธ==2.8.0
2. ๋ฐ์ดํฐ¶
SpanBERTa๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ ๊ต์กํ์ต๋๋ค. OSCAR์ ์คํ์ธ์ด ๋ง๋ญ์น๋ฅผ ์ฌ์ฉํ์ต๋๋ค. ๋ฐ์ดํฐ ์ธํธ์ ์ ์ฒด ํฌ๊ธฐ๋ 150GB์ด๋ฉฐ, ์ด ์ค 18GB์ ์ผ๋ถ๋ฅผ ํ๋ จ์ ์ฌ์ฉํ์ต๋๋ค.
์ด ์์ ์์๋ ๊ฐ๋จํ๊ฒ ํ๊ธฐ ์ํด ๋ค์์ ์คํ์ธ์ด ์ํ ์๋ง ๋ฐ์ดํฐ ์งํฉ์ ์ฌ์ฉํ๊ฒ ์ต๋๋ค. OpenSubtitles. ์ด ๋ฐ์ดํฐ ์ธํธ์ ํฌ๊ธฐ๋ 5.4GB์ด๋ฉฐ ์ฝ 300MB์ ํ์ ์งํฉ์ผ๋ก ํ์ตํ ๊ฒ์ ๋๋ค.
0]์ ์ ๋ ฅํฉ๋๋ค:
๊ฐ์ ธ์ค๊ธฐ # ์ํ ์๋ง ๋ฐ์ดํฐ์ ๋ค์ด๋ก๋ ๋ฐ ์์ถ ํ๊ธฐ os.path.exists('data/dataset.txt')๊ฐ ์๋๋ผ๋ฉด: !.wget "https://object.pouta.csc.fi/OPUS-OpenSubtitles/v2016/mono/es.txt.gz" -O dataset.txt.gz !.gzip -d dataset.txt.gz !.mkdir data !.mv dataset.txt ๋ฐ์ดํฐ
-2020-04-06 15:53:04-- https://object.pouta.csc.fi/OPUS-OpenSubtitles/v2016/mono/es.txt.gz object.pouta.csc.fi ํ์ธ ์ค (object.pouta.csc.fi)... 86.50.254.18, 86.50.254.19 (object.pouta.csc.fi)|86.50.254.18|:443... ์ฐ๊ฒฐ ์ค (object.pouta.csc.fi)์ ์ฐ๊ฒฐ ์ค์ ๋๋ค. HTTP ์์ฒญ ์ ์ก, ์๋ต ๋๊ธฐ ์ค... 200 OK ๊ธธ์ด: 1859673728 (1.7G) [application/gzip] ์ ์ฅ ์์น: 'dataset.txt.gz' dataset.txt.gz 100%[===================>] 1.73G 17.0MB/s in 1m 46s 2020-04-06 15:54:51 (16.8MB/s) - 'dataset.txt.gz' ์ ์ฅ [1859673728/1859673728]
0]์ ์ ๋ ฅํฉ๋๋ค:
# ์ด ํ์ ์ ๋ฐ ์ผ๋ถ ์์ ํ์ ์ !wc -l ๋ฐ์ดํฐ/๋ฐ์ดํฐ์ .txt !shuf -n 5 ๋ฐ์ดํฐ/๋ฐ์ดํฐ์ .txt
179287150 data/dataset.txt ์ ์๊ฐ์๋ ์ ๋จํธ์ ํตํด ์ธ์ธ ์์๋ ๋ ๋ง์ ํ ๋กํธ๊ฐ ์๋ค๊ณ ์๊ฐํ์ต๋๋ค. ์ํ์ ์คํฌ์ ๋ชจ๋ ์ธ์ด์ ๋ด๊ธด ๋ชจ๋ ๋งค๋ ฅ์ ๋๊ปด๋ณด์ธ์. ์ด์ ์๋ ๋ธ๋ฃจ ๋ธ๋ฌ๋์์: ๊ทธ๋ฆฌ๊ณ ๋ค๋์ ์คํํฌ๋์๋ ๊ฑฐ๋ํ์ง ์๊ฒ ๋ค๊ณ ์ฝ์ํ๊ณ ์ถ์ต๋๋ค. ์๊ฒผ์ด์.
0]์ ์ ๋ ฅํฉ๋๋ค:
# ํ๋ จ์ฉ ์ฒซ 1,000,000์ค์ ํ์ ์งํฉ ๊ฐ์ ธ์ค๊ธฐ TRAIN_SIZE = 1000000 #@param {type:"integer"} !(head -n $TRAIN_SIZE data/dataset.txt) > data/train.txt
0]์ ์ ๋ ฅํฉ๋๋ค:
# ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํด ๋ค์ 10,000์ค์ ํ์ ์งํฉ ๊ฐ์ ธ์ค๊ธฐ VAL_SIZE = 10000 #@param {type:"integer"} !(sed -n {TRAIN_SIZE + 1},{TRAIN_SIZE + VAL_SIZE}p data/dataset.txt) > data/dev.txt
3. ํ ํฐํ ํธ๋ ์ด๋¶
์๋์ BERT ๊ตฌํ์ 32K ๊ฐ์ ํ์ ๋จ์ด ๋จ์๋ก ๊ตฌ์ฑ๋ ์ดํ๋ฅผ ๊ฐ์ง WordPiece ํ ํฐํ๊ธฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด ๋ฐฉ๋ฒ์ ํฌ๊ท ๋จ์ด๋ฅผ ์ฒ๋ฆฌํ ๋ "์ ์ ์๋" ํ ํฐ์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
์ด ๊ตฌํ์์๋ 50,265๊ฐ์ ํ์ ๋จ์ด ๋จ์๋ก ๊ตฌ์ฑ๋ ์ดํ๋ฅผ ๊ฐ์ง ๋ฐ์ดํธ ์์ค์ BPE ํ ํฐํ๊ธฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค(RoBERTa-base์ ๋์ผ). ๋ฐ์ดํธ ์์ค์ BPE๋ฅผ ์ฌ์ฉํ๋ฉด "์ ์ ์๋" ํ ํฐ ์์ด ๋ชจ๋ ์ ๋ ฅ์ ์ธ์ฝ๋ฉํ ์ ์๋ ์ ๋นํ ํฌ๊ธฐ์ ํ์ ๋จ์ด ์ดํ๋ฅผ ํ์ตํ ์ ์์ต๋๋ค.
์๋ํ๋ฉด ๋ฐ์ดํธ ๋ ๋ฒจBPETokenizer
2๊ฐ์ ํ์ผ์ ์์ฑํฉ๋๋ค. ["vocab.json", "merges.txt"]
๋์ ๋ฒํธ์๋ํผ์คํ ํฐ๋ผ์ด์
ํ์ผ ํ๋๋ง ์์ฑํฉ๋๋ค. vocab.txt
๋ฅผ ์ฌ์ฉํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋ฒํธ์๋ํผ์คํ ํฐ๋ผ์ด์
๋ฅผ ์ฌ์ฉํ์ฌ BPE ํ ํฐํ๊ธฐ์ ์ถ๋ ฅ์ ๋ก๋ํฉ๋๋ค.
0]์ ์ ๋ ฅํฉ๋๋ค:
%%ํ์ ํ ํฐํ ๋๊ตฌ์์ ByteLevelBPETokenizer๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ๊ฒฝ๋ก = "data/train.txt" # ํ ํฐํ๊ธฐ๋ฅผ ์ด๊ธฐํํฉ๋๋ค. ํ ํฐํ๊ธฐ = ByteLevelBPETokenizer() # ํธ๋ ์ด๋ ์ฌ์ฉ์ ์ง์ tokenizer.train(files=path, vocab_size=50265, min_frequency=2, special_tokens=["", "", "", "", ""])) # ๋์คํฌ์ ํ์ผ ์ ์ฅ !.mkdir -p "models/roberta" tokenizer.save("models/roberta")
CPU ์๊ฐ: ์ฌ์ฉ์ 1๋ถ 37์ด, ์์คํ : 1.02์ด, ์ด 1๋ถ 38์ด ๋ฒฝ ์๊ฐ: 1๋ถ 38์ด
๋งค์ฐ ๋น ๋ฆ ๋๋ค! 1,000๋ง ํ์ ์ ํ๋ จํ๋ ๋ฐ 2๋ถ๋ฐ์ ๊ฑธ๋ฆฌ์ง ์์ต๋๋ค.
์ฒ์๋ถํฐ ํธ๋ ์ด๋ ์ธ์ด ๋ชจ๋ธ¶
1. ๋ชจ๋ธ ์ํคํ ์ฒ¶
RoBERTa๋ BERT์ ์ํคํ ์ฒ๊ฐ ์์ ํ ๋์ผํฉ๋๋ค. ์ ์ผํ ์ฐจ์ด์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- RoBERTa๋ ๋ ํฐ ํ์ ๋จ์ด ์ดํ(50,000๊ฐ ๋ 32,000๊ฐ)๋ฅผ ๊ฐ์ง ๋ฐ์ดํธ ์์ค์ BPE ํ ํฐํ๊ธฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- RoBERTa๋ ๋์ ๋จ์ด ๋ง์คํน์ ๊ตฌํํ๊ณ ๋ค์ ๋ฌธ์ฅ ์์ธก ์์ ์ ์ญ์ ํฉ๋๋ค.
- RoBERTa์ ํธ๋ ์ด๋ ํ์ดํผํ๋ผ๋ฏธํฐ.
๋ค๋ฅธ ์ํคํ ์ฒ ๊ตฌ์ฑ์ ๋ฌธ์์์ ํ์ธํ ์ ์์ต๋๋ค(RoBERTa, BERT).
0]์ ์ ๋ ฅํฉ๋๋ค:
json ๊ฐ์ ธ์ค๊ธฐ config = { "์ํคํ ์ฒ": [ "RobertaForMaskedLM" ], "attention_probs_dropout_prob": 0.1, "hidden_act": "์ ค๋ฃจ", "hidden_dropout_prob": 0.1, "hidden_size": 768, "initializer_range": 0.02, "intermediate_size": 3072, "LAYER_NORM_EPS": 1e-05, "max_position_embedings": 514, "model_type": "๋ก๋ฒ ๋ฅดํ", "num_attention_heads": 12, "num_hidden_layers": 12, "type_vocab_size": 1, "vocab_size": 50265 } open("models/roberta/config.json", 'w') ๋ฅผ fp๋ก ์ฌ์ฉํฉ๋๋ค: json.dump(config, fp) ํ ํฐํ๊ธฐ_์ค์ = {"max_len": 512} with open("models/roberta/tokenizer_config.json", 'w') as fp: json.dump(tokenizer_config, fp)
2. ๊ต์ก ํ์ดํผํ๋ผ๋ฏธํฐ¶
ํ์ดํผํ๋ผ๋ฏธํฐ | BERT ๊ธฐ๋ฐ | RoBERTa-base |
---|---|---|
์ํ์ค ๊ธธ์ด | 128, 512 | 512 |
๋ฐฐ์น ํฌ๊ธฐ | 256 | 8K |
์ต๋ ํ์ต๋ฅ | 1e-4 | 6e-4 |
์ต๋ ๊ฑธ์ ์ | 1M | 500K |
์๋ฐ์ ๋จ๊ณ | 10K | 24K |
๋ฌด๊ฒ ๊ฐ์ | 0.01 | 0.01 |
์๋ด 1TP4ํ ์ค๋ก $ | 1e-6 | 1e-6 |
Adam $beta_1$ | 0.9 | 0.9 |
Adam $beta_2$ | 0.999 | 0.98 |
๊ทธ๋ผ๋ฐ์ด์ ํด๋ฆฌํ | 0.0 | 0.0 |
RoBERTa๋ฅผ ํ๋ จํ ๋ ๋ฐฐ์น ํฌ๊ธฐ๋ 8000๊ฐ์
๋๋ค. ๋ฐ๋ผ์ RoBERTa-base๋ 500๋ง ๊ฑธ์์ผ๋ก ํ๋ จ๋์์ง๋ง ํ๋ จ ๊ณ์ฐ ๋น์ฉ์ BERT-base์ 16๋ฐฐ์ ๋ฌํฉ๋๋ค. ์์ RoBERTa ์ข
์ด๋ฅผ ํตํด ๋๊ท๋ชจ ๋ฐฐ์น๋ก ํ์ตํ๋ฉด ์ต์ข
์์
์ ํ๋๋ฟ๋ง ์๋๋ผ ๋ง์คํฌ ์ธ์ด ๋ชจ๋ธ๋ง ๋ชฉํ์ ๋ํ ๋ํด์ฑ์ด ํฅ์๋๋ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค. ๋ค์์ ์กฐ์ ํ์ฌ ๋ ํฐ ๋ฐฐ์น ํฌ๊ธฐ๋ฅผ ์ป์ ์ ์์ต๋๋ค. ๊ทธ๋ผ๋ฐ์ด์
_๋์ _๋จ๊ณ
.
๊ณ์ฐ์์ ์ ์ฝ์ผ๋ก ์ธํด BERT-base์ ํ๋ จ ์คํค๋ง๋ฅผ ๋ฐ๋ผ 8์ผ ๋์ 4๊ฐ์ Tesla P100 GPU๋ฅผ ์ฌ์ฉํ์ฌ 20๋ง ๋จ๊ณ์ ๊ฑธ์ณ SpanBERTa ๋ชจ๋ธ์ ํ๋ จํ์ต๋๋ค.
3. ๊ต์ก ์์¶
๋ค์์ ์ฌ์ฉํ์ฌ ๋ชจ๋ธ์ ์ฒ์๋ถํฐ ํ๋ จํฉ๋๋ค. run_language_modeling.py
์์ ์ ๊ณตํ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ฒ๋ฆฌ, ๋ง๋ญ์น ํ ํฐํ ๋ฐ ๋ชจ๋ธ ํ์ต์ ์ํํฉ๋๋ค. ๋ง์คํฌ ์ธ์ด ๋ชจ๋ธ๋ง ์์
์ ์ํํฉ๋๋ค. ์ด ์คํฌ๋ฆฝํธ๋ ํ๋์ ๋๊ท๋ชจ ๋ง๋ญ์น์์ ํ์ตํ๋๋ก ์ต์ ํ๋์ด ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ฐ์ดํฐ ์ธํธ๊ฐ ํฌ๊ณ ์ด๋ฅผ ๋ถํ ํ์ฌ ์์ฐจ์ ์ผ๋ก ํ๋ จํ๋ ค๋ฉด ์คํฌ๋ฆฝํธ๋ฅผ ์์ ํ๊ฑฐ๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ง์ ๋ชฌ์คํฐ ๋จธ์ ์ ๊ตฌํ ์ค๋น๊ฐ ๋์ด ์์ด์ผ ํฉ๋๋ค.
0]์ ์ ๋ ฅํฉ๋๋ค:
# ์ ๋ฐ์ดํธ 2020๋ 4์ 22์ผ: ํ๊น ํ์ด์ค๊ฐ run_language_modeling.py ์คํฌ๋ฆฝํธ๋ฅผ ์ ๋ฐ์ดํธํ์ต๋๋ค. # ์ ๋ฐ์ดํธ ์ ์ ์ด ๋ฒ์ ์ ์ฌ์ฉํ์ธ์. !.wget -c https://raw.githubusercontent.com/chriskhanhtran/spanish-bert/master/run_language_modeling.py
-2020-04-24 02:28:21-- https://raw.githubusercontent.com/chriskhanhtran/spanish-bert/master/run_language_modeling.py raw.githubusercontent.com(raw.githubusercontent.com) ํ์ธ ์ค... 151.101.0.133, 151.101.64.133, 151.101.128.133, ... ์ฐ๊ฒฐ ์ค (raw.githubusercontent.com)|151.101.0.133|:443... ์ฐ๊ฒฐ๋จ. HTTP ์์ฒญ ์ ์ก, ์๋ต ๋๊ธฐ ์ค... 200 OK ๊ธธ์ด: 34328 (34K) [ํ ์คํธ/์ผ๋ฐ] ์ ์ฅํ๋ ์ค 'run_language_modeling.py' run_language_modeli 100%[===================>] 33.52K --.-KB/s in 0.003s 2020-04-24 02:28:21 (10.1 MB/s) - 'run_language_modeling.py' ์ ์ฅ [34328/34328]
์ค์ ์ธ์
--LINE_BY_LINE
๋ฐ์ดํฐ ์ธํธ์ ๊ณ ์ ํ ํ ์คํธ ์ค์ ๊ณ ์ ํ ์ํ์ค๋ก ์ฒ๋ฆฌํ ์ง ์ฌ๋ถ์ ๋๋ค. ๋ฐ์ดํฐ ์ธํธ์ ๊ฐ ์ค์ด ๊ธธ๊ณ ํ ํฐ์ด ์ต๋ 512๊ฐ ์ด์์ธ ๊ฒฝ์ฐ ์ด ์ค์ ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ๊ฐ ์ค์ด ์งง์ ๊ฒฝ์ฐ, ๊ธฐ๋ณธ ํ ์คํธ ์ ์ฒ๋ฆฌ๋ ๋ชจ๋ ์ค์ ์ฐ๊ฒฐํ๊ณ ํ ํฐํํ์ฌ ํ ํฐํ๋ ์ถ๋ ฅ์ 512๊ฐ์ ํ ํฐ ๋ธ๋ก์ผ๋ก ๋ถํ ํฉ๋๋ค. ๋ฐ์ดํฐ ์ธํธ๋ฅผ ์์ ๋ฉ์ด๋ฆฌ๋ก ๋ถํ ํ์ฌ ๊ฐ๋ณ์ ์ผ๋ก ์ฌ์ ์ฒ๋ฆฌํ ์๋ ์์ต๋๋ค. 3GB์ ํ ์คํธ๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐ ์ฝ 50๋ถ์ด ์์๋ฉ๋๋ค.ํ ์คํธ ๋ฐ์ดํฐ ์ธํธ
ํด๋์ค.--should_continue
output_dir์ ์ต์ ์ฒดํฌํฌ์ธํธ์์ ๊ณ์ํ ์ง ์ฌ๋ถ์ ๋๋ค.--๋ชจ๋ธ_์ด๋ฆ_๋๋_๊ฒฝ๋ก
๊ฐ์ค์น ์ด๊ธฐํ๋ฅผ ์ํ ๋ชจ๋ธ ์ฒดํฌํฌ์ธํธ์ ๋๋ค. ๋ชจ๋ธ์ ์ฒ์๋ถํฐ ํ์ต์ํค๋ ค๋ฉด ์์์ผ๋ก ๋ก๋๋ค.--mlm
์ธ์ด ๋ชจ๋ธ๋ง ๋์ ๋ง์คํน๋ ์ธ์ด ๋ชจ๋ธ๋ง ์์ค๋ก ํ์ตํฉ๋๋ค.--config_name, --tokenizer_name
๋ชจ๋ธ_์ด๋ฆ_๋๋_๊ฒฝ๋ก์ ๊ฐ์ง ์์ ๊ฒฝ์ฐ ์ฌ์ ํ์ต๋ ๊ตฌ์ฑ ๋ฐ ํ ํฐํ๊ธฐ ์ด๋ฆ ๋๋ ๊ฒฝ๋ก(์ ํ ์ฌํญ). ๋ ๋ค None์ธ ๊ฒฝ์ฐ ์ ๊ตฌ์ฑ์ ์ด๊ธฐํํฉ๋๋ค.--per_gpu_train_batch_size
ํธ๋ ์ด๋์ ์ํ GPU/CPU๋น ๋ฐฐ์น ํฌ๊ธฐ. GPU์ ๋ง์ถ ์ ์๋ ๊ฐ์ฅ ํฐ ์ซ์๋ฅผ ์ ํํ์ธ์. ๋ฐฐ์น ํฌ๊ธฐ๊ฐ ๋๋ฌด ํฌ๋ฉด ์ค๋ฅ๊ฐ ํ์๋ฉ๋๋ค.--gradient_accumulation_steps
๋ค๋ก/์ ๋ฐ์ดํธ ํจ์ค๋ฅผ ์ํํ๊ธฐ ์ ์ ๋์ ํ ์ ๋ฐ์ดํธ ๋จ๊ณ ์์ ๋๋ค. ์ด ํธ๋ฆญ์ ์ฌ์ฉํ์ฌ ๋ฐฐ์น ํฌ๊ธฐ๋ฅผ ๋๋ฆด ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐper_gpu_train_batch_size = 16
๋ฐgradient_accumulation_steps = 4
๋ฅผ ์ ๋ ฅํ๋ฉด ์ด ์ด์ฐจ ๋ฐฐ์น ํฌ๊ธฐ๋ 64๊ฐ ๋ฉ๋๋ค.--overwrite_output_dir
์ถ๋ ฅ ๋๋ ํฐ๋ฆฌ์ ์ฝํ ์ธ ๋ฅผ ๋ฎ์ด์๋๋ค.--no_cuda, --fp16, --fp16_opt_level
GPU/CPU ํธ๋ ์ด๋์ ์ํ ์ธ์์ ๋๋ค.- ๋ค๋ฅธ ์ธ์๋ ๋ชจ๋ธ ๊ฒฝ๋ก์ ํ์ต ํ์ดํผํ๋ผ๋ฏธํฐ์ ๋๋ค.
์คํฌ๋ฆฝํธ์์๋ ๋ชจ๋ธ ๊ฒฝ๋ก์ ๋ชจ๋ธ ์ ํ(์: "roberta", "bert", "gpt2" ๋ฑ)์ ํฌํจํ ๊ฒ์ ์ ๊ทน ๊ถ์ฅํฉ๋๋ค. ์๋ ๋ชจ๋ธ
ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ ๊ณต๋ ๊ฒฝ๋ก์์ ํจํด ๋งค์นญ์ ์ฌ์ฉํ์ฌ ๋ชจ๋ธ์ ๊ตฌ์ฑ์ ์ถ์ธกํฉ๋๋ค.
0]์ ์ ๋ ฅํฉ๋๋ค:
# ๋ชจ๋ธ ๊ฒฝ๋ก MODEL_TYPE = "roberta" #@param ["roberta", "bert"] MODEL_DIR = "models/roberta" #@param {type: "๋ฌธ์์ด"} OUTPUT_DIR = "models/roberta/output" #@param {type: "๋ฌธ์์ด"} TRAIN_PATH = "data/train.txt" #@param {type: "๋ฌธ์์ด"} EVAL_PATH = "data/dev.txt" #@param {type: "๋ฌธ์์ด"}
์ด ์์ ์์๋ Colab์์ ์ ๊ณตํ๋ Tesla P4 GPU๋ฅผ ์ฌ์ฉํ์ฌ 25๋จ๊ณ๋ง ํ๋ จํ๊ฒ ์ต๋๋ค.
0]์ ์ ๋ ฅํฉ๋๋ค:
!.nvidia-smi
์ Apr 6 15:59:35 2020 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 440.64.00 ๋๋ผ์ด๋ฒ ๋ฒ์ : 418.67 CUDA ๋ฒ์ : 10.1 | |-------------------------------+----------------------+----------------------+ | GPU ์ด๋ฆ ์ง์์ฑ-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | ํฌ ์จ๋ ํผํ Pwr:์ฌ์ฉ๋/์บก| ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ | GPU-Util Compute M. | |===============================+======================+======================| 0 Tesla P4 Off | 00000000:00:04.0 Off | 0 | | | N/A 31C P8 7W / 75W | 0MiB / 7611MiB | 0% ๊ธฐ๋ณธ๊ฐ | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | ํ๋ก์ธ์ค: GPU ๋ฉ๋ชจ๋ฆฌ | | GPU PID ์ ํ ํ๋ก์ธ์ค ์ด๋ฆ ์ฌ์ฉ | |=============================================================================| ์คํ ์ค์ธ ํ๋ก์ธ์ค ์์ | | +-----------------------------------------------------------------------------+
0]์ ์ ๋ ฅํฉ๋๋ค:
# ๋ช ๋ น์ค cmd = """python run_language_modeling.py --output_dir {output_dir} --model_type {model_type} --mlm --config_name {config_name} --tokenizer_name {ํ ํฐ๋ผ์ด์ _์ด๋ฆ} {line_by_line} {SHOULD_CONTINUE} {๋ชจ๋ธ_์ด๋ฆ_๋๋_๊ฒฝ๋ก} --train_data_file {train_path} --eval_data_ํ์ผ {eval_path} --do_train {do_eval} {evaluate_during_training} --overwrite_output_dir --block_size 512 --max_step 25 --warmup_steps 10 --learning_rate 5e-5 --per_gpu_train_batch_size 4 --gradient_accumulation_steps 4 --weight_decay 0.01 --์๋ด_์ก์ค๋ก 1e-6 --max_grad_norm 100.0 --save_total_limit 10 --save_steps 10 --logging_steps 2 --seed 42 """
0]์ ์ ๋ ฅํฉ๋๋ค:
# ์ฒ์๋ถํฐ ํ๋ จ์ ์ํ ์ธ์. ํ๊ฐ_์ค_ํ๋ จ์ ๋๋๋ค, # line_by_line, should_continue, model_name_or_path๋ฅผ ๋๋๋ค. train_params = { "output_dir": OUTPUT_DIR, "model_type": MODEL_TYPE, "config_name": MODEL_DIR, "ํ ํฐํ๊ธฐ_์ด๋ฆ": MODEL_DIR, "train_path": TRAIN_PATH, "EVAL_PATH": EVAL_PATH, "do_eval": "--do_eval", "evaluate_during_training": "", "LINE_BY_LINE": "", "SHOULD_CONTINUE": "", "๋ชจ๋ธ_์ด๋ฆ_๋๋_๊ฒฝ๋ก": "", }
๊ฐ์ ๋จธ์ ์์ ๊ต์กํ๋ ๊ฒฝ์ฐ ํ ์๋ณด๋๋ฅผ ์ค์นํ์ฌ ๊ต์ก ๊ณผ์ ์ ๋ชจ๋ํฐ๋งํ ์ ์์ต๋๋ค. ์ฌ๊ธฐ ํ ์๋ณด๋ ์คํฌ๋ฒํ ๊ต์ก์ฉ.
pip install tensorboard==2.1.0 tensorboard dev upload --logdir runs
20๋ง ๊ฑธ์ ํ ์์ค์ 1.8, ๋นํน๊ฐ์ 5.2์ ๋ฌํ์ต๋๋ค.
์ด์ ๊ต์ก์ ์์ํ๊ฒ ์ต๋๋ค!
In [ ]:
!{cmd.format(**train_params)}
04/06/2020 15:59:55 - INFO - __main__ - ๋ฐ์ดํฐ์์ ๋ฐ์ดํฐ ์ธํธ ํ์ผ์์ ๊ธฐ๋ฅ ๋ง๋ค๊ธฐ
04/06/2020 16:04:43 - INFO - __main__ - ์บ์๋ ํ์ผ data/roberta_cached_lm_510_train.txt์ ๊ธฐ๋ฅ ์ ์ฅ ์ค
04/06/2020 16:04:46 - INFO - __main__ - ***** ํธ๋ ์ด๋ ์คํ *****
04/06/2020 16:04:46 - INFO - __main__ - ์์ ์ = 165994
04/06/2020 16:04:46 - INFO - __main__ - Num Epochs = 1
04/06/2020 16:04:46 - INFO - __main__ - GPU๋น ์๊ฐ ๋ฐฐ์น ํฌ๊ธฐ = 4
04/06/2020 16:04:46 - INFO - __main__ - ์ด ํธ๋ ์ธ ๋ฐฐ์น ํฌ๊ธฐ(๋ณ๋ ฌ, ๋ถ์ฐ ๋ฐ ๋์ ํฌํจ) = 16
04/06/2020 16:04:46 - INFO - __main__ - ๊ทธ๋ผ๋ฐ์ด์
๋์ ๋จ๊ณ = 4
04/06/2020 16:04:46 - INFO - __main__ - ์ด ์ต์ ํ ๋จ๊ณ = 25
์ํฌํฌ: 0% 0/1 [00:00<?, ?it/s]
๋ฐ๋ณต: 0% 0/41499 [00:00<?, ?it/s]
๋ฐ๋ณต 0% 1/41499 [00:01<13:18:02, 1.15s/it]
๋ฐ๋ณต: 0% 2/41499 [00:01<11:26:47, 1.01it/s]
๋ฐ๋ณต: 0% 3/41499 [00:02<10:10:30, 1.13it/s]
๋ฐ๋ณต 0% 4/41499 [00:03<9:38:10, 1.20it/s]
๋ฐ๋ณต 0% 5/41499 [00:03<8:52:44, 1.30it/s]
๋ฐ๋ณต 0% 6/41499 [00:04<8:22:47, 1.38it/s]
๋ฐ๋ณต: 0% 7/41499 [00:04<8:00:55, 1.44it/s]
๋ฐ๋ณต: 0% 8/41499 [00:05<8:03:40, 1.43it/s]
๋ฐ๋ณต: 0% 9/41499 [00:06<7:46:57, 1.48it/s]
๋ฐ๋ณต: 0% 10/41499 [00:06<7:35:35, 1.52it/s]
๋ฐ๋ณต: 0% 11/41499 [00:07<7:28:29, 1.54it/s]
๋ฐ๋ณต: 0% 12/41499 [00:08<7:41:41, 1.50it/s]
๋ฐ๋ณต 0% 13/41499 [00:08<7:34:28, 1.52it/s]
๋ฐ๋ณต: 0% 14/41499 [00:09<7:28:46, 1.54it/s]
๋ฐ๋ณต: 0% 15/41499 [00:10<7:23:29, 1.56it/s]
๋ฐ๋ณต 0% 16/41499 [00:10<7:38:06, 1.51it/s]
๋ฐ๋ณต: 0% 17/41499 [00:11<7:29:13, 1.54it/s]
๋ฐ๋ณต: 0% 18/41499 [00:12<7:24:04, 1.56it/s]
๋ฐ๋ณต: 0% 19/41499 [00:12<7:21:59, 1.56it/s]
๋ฐ๋ณต: 0% 20/41499 [00:13<7:38:06, 1.51it/s]
04/06/2020 16:06:23 - INFO - __main__ - ***** ์คํ ํ๊ฐ *****
04/06/2020 16:06:23 - INFO - __main__ - ์์ ์ = 156
04/06/2020 16:06:23 - INFO - __main__ - ๋ฐฐ์น ํฌ๊ธฐ = 4
ํ๊ฐ ์ค์
๋๋ค: 100% 39/39 [00:08<00:00, 4.41it/s]
04/06/2020 16:06:32 - INFO - __main__ - ***** ํ๊ฐ ๊ฒฐ๊ณผ *****
04/06/2020 16:06:32 - INFO - __main__ - perplexity = tensor(6077.6812)
4. ๋ง์คํฌ๋ ๋จ์ด ์์ธก¶
์ธ์ด ๋ชจ๋ธ์ ํ์ตํ ํ์๋ ๋ชจ๋ธ์ ์ ๋ก๋ํ๊ณ ์ปค๋ฎค๋ํฐ์ ๊ณต์ ํ ์ ์์ต๋๋ค. SpanBERTa ๋ชจ๋ธ์ Hugging Face ์๋ฒ์ ์ ๋ก๋ํ์ต๋๋ค. ๋ค์ด์คํธ๋ฆผ ์์ ์์ ๋ชจ๋ธ์ ํ๊ฐํ๊ธฐ ์ ์ ๋ชจ๋ธ์ด ์ฃผ์ด์ง ๋ฌธ๋งฅ์์ ๊ฐ๋ ค์ง ๋จ์ด๋ฅผ ์ฑ์ฐ๋ ๋ฐฉ๋ฒ์ ์ด๋ป๊ฒ ํ์ตํ๋์ง ์ดํด๋ด ์๋ค.
0]์ ์ ๋ ฅํฉ๋๋ค:
%%์บก์ณ %%์๊ฐ ํธ๋์คํฌ๋จธ์์ ํ์ดํ๋ผ์ธ ๊ฐ์ ธ์ค๊ธฐ fill_mask = ํ์ดํ๋ผ์ธ( "fill-mask", model="chriskhanhtran/spanberta", tokenizer="chriskhanhtran/spanberta" )
์ฝ๋ก๋19์ ๊ดํ Wikipedia์ ๊ธฐ์ฌ์์ ํ ๋ฌธ์ฅ์ ๊ณจ๋ผ๋ด ๋๋ค.
์๋ ๋ฌธ์ฅ์ "๋ฌผ๊ณผ ์ ๊ฐ๋ฝ์ผ๋ก ์์ ์์ฃผ ์ป์ผ์ธ์," ์๋ฏธ "๋น๋์ ๋ฌผ๋ก ์์ ์์ฃผ ์ป์ผ์ธ์.“
๋ง์คํฌ๋ ๋จ์ด๋ "์๋ด"(๋น๋) ์์ 5๊ฐ์ง ์์ธก์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๋น๋, ์๊ธ, ์คํ, ๋ ๋ชฌ ๋ฐ ์์ด. ๋ชจ๋ธ์ด ๋ฐํ ๋ฆฌ์๋ฅผ ์ฃฝ์ด๊ฑฐ๋ ์ฐ์ ํจ์ ํ ์์๋ ๋ฌผ๊ฑด์ผ๋ก ์์ ์ป์ด์ผํ๋ค๋ ๊ฒ์ ์ด๋ป๊ฒ ๋ ๋ฐฐ์ด๋ค๋ ๊ฒ์ด ํฅ๋ฏธ ๋กญ์ต๋๋ค.
0]์ ์ ๋ ฅํฉ๋๋ค:
fill_mask("๋ฌผ๊ณผ ๋ก ์์ ์์ฃผ ๋ฆ์์ฃผ์ธ์.")
Out[0]:
[{'score': 0.6469631195068359, 'sequence': '๋ฌผ๊ณผ ์ ๊ฐ๋ฝ์ผ๋ก ์์ ์์ฃผ ์ป์ผ์ญ์์ค.', 'token': 18493}, {'score': 0.06074320897459984, 'sequence': '๋ฌผ๊ณผ ์๊ธ์ผ๋ก ์์ ์์ฃผ ์ป์ผ์ญ์์ค.', 'ํ ํฐ': 619}, {'score': 0.029787985607981682, 'sequence': '๋ฌผ๊ณผ ์ฆ๊ธฐ๋ก ์์ ์์ฃผ ์ป์ผ์ญ์์ค.', 'token': 11079}, {'score': 0.026410052552819252, 'sequence': '๋ฌผ๊ณผ ๋ ๋ชฌ์ผ๋ก ์์ ์์ฃผ ์ป์ผ์ญ์์ค.', 'token': 12788}, {'score': 0.017029203474521637, 'sequence': '๋ฌผ๊ณผ ์๊ธ์ผ๋ก ์์ ์์ฃผ ์ป์ผ์ญ์์ค.', 'token': 18424}]
๊ฒฐ๋ก ¶
์คํ์ธ์ด์ ๋ํ BERT ์ธ์ด ๋ชจ๋ธ์ ์ฒ์๋ถํฐ ํ๋ จํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ณ , ์ฃผ์ด์ง ๋ฌธ๋งฅ์์ ๋ง์คํฌ๋ ๋จ์ด๋ฅผ ์์ธกํ์ฌ ๋ชจ๋ธ์ด ์ธ์ด์ ์์ฑ์ ํ์ตํ๋ ๊ฒ์ ํ์ธํ์ต๋๋ค. ์ด ๋ฌธ์์ ๋ฐ๋ผ ์ฌ์ฉ์ ์ง์ ๋ฐ์ดํฐ ์ธํธ์์ ๋ฏธ๋ฆฌ ํ์ต๋ BERT์ ์ ์ฌํ ๋ชจ๋ธ์ ๋ฏธ์ธ ์กฐ์ ํ ์๋ ์์ต๋๋ค.
๋ค์์ผ๋ก ์ํ์ค ๋ถ๋ฅ, NER, POS ํ๊น , NLI๋ฅผ ํฌํจํ ๋ค์ด์คํธ๋ฆผ ์์ ์์ ์ฌ์ ํ์ต๋ ๋ชจ๋ธ์ ๊ตฌํํ๊ณ ๋ชจ๋ธ์ ์ฑ๋ฅ์ ์ผ๋ถ ๋น-BERT ๋ชจ๋ธ๊ณผ ๋น๊ตํด ๋ณด๊ฒ ์ต๋๋ค.
๋ค์ ํฌ์คํ ๋ ๊ธฐ๋ํด์ฃผ์ธ์!