๋ฐ์ํ
Tokenization - ํ ํฐํํ๊ธฐ
1๋จ๊ณ: ์ฝ๋ฉ ๋ ธํธ๋ถ ์ด๊ธฐํ
ํจํค์ง๋ฅผ ์ค์นํด์ค๋๋ค.
!pip install ratsnlp
๊ตฌ๊ธ ๋๋ผ์ด๋ธ ์ฐ๋ํ๊ธฐ
- ํํ ๋ฆฌ์ผ์์ ๊ตฌ์ถํ ์ดํ ์งํฉ์ ์ ์ฅํด ๋ ๊ตฌ๊ธ ๋๋ผ์ด๋ธ๋ฅผ ์ฐ๊ฒฐํฉ๋๋ค.
from google.colab import drive
drive.mount('/gdrive', force_remount=True)
2๋จ๊ณ: GPT ์ ๋ ฅ๊ฐ ๋ง๋ค๊ธฐ
- GPT ๋ชจ๋ธ ์ ๋ ฅ๊ฐ์ ๋ง๋ค๋ ค๋ฉด Byte-level Byte Pair Encoding ์ดํ์งํฉ ๊ตฌ์ถ ๊ฒฐ๊ณผ(`vocab.json`, `merges.txt`)๊ฐ ์์ ์ ๊ตฌ๊ธ ๋๋ผ์ด๋ธ ๊ฒฝ๋ก(`/gdrive/My Drive/nlpbook/wordpiece`)์ ์์ด์ผ ํฉ๋๋ค.
- ์๋ ์ฝ๋๋ฅผ ์ํํด ์ด๋ฏธ ๋ง๋ค์ด ๋์ BBPE ์ดํ์งํฉ์ ํฌํจํ GPT ํ ํฌ๋์ด์ ๋ฅผ `tokenizer_gpt`๋ผ๋ ๋ณ์๋ก ์ ์ธํฉ๋๋ค.
from transformers import GPT2Tokenizer
tokenizer_gpt = GPT2Tokenizer.from_pretrained("/gdrive/My Drive/nlpbook/bbpe")
tokenizer_gpt.pad_token = "[PAD]"
ํ๋ฒ ์์ ๋ฌธ์ฅ 3๊ฐ๋ฅผ ๊ฐ๊ฐ ํ ํฐํ ํด๋ณด๊ฒ ์ต๋๋ค.
sentences = [
"์ ๋๋น.. ์ง์ง ์ง์ฆ๋๋ค์ ๋ชฉ์๋ฆฌ",
"ํ ...ํฌ์คํฐ๋ณด๊ณ ์ด๋ฉ์ํ์ค....์ค๋ฒ์ฐ๊ธฐ์กฐ์ฐจ ๊ฐ๋ณ์ง ์๊ตฌ๋",
"๋ณ๋ฃจ ์๋ค..",
]
tokenized_sentences = [tokenizer_gpt.tokenize(sentence) for sentence in sentences]
์๋ ์ฝ๋๋ฅผ ์คํ์์ผ์ ํ ํฐํ ๊ฒฐ๊ณผ๋ฅผ ํ์ธ ํด๋ณด์ธ์.
tokenized_sentences
์ด๋ฒ์๋ Batch_size๊ฐ 3์ด๋ผ๊ณ ๊ฐ์ ํ๊ณ ์ด๋ฒ ๋ฐฐ์น์ ์ ๋ ฅ๊ฐ์ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
batch_inputs = tokenizer_gpt(
sentences,
padding="max_length", # ๋ฌธ์ฅ์ ์ต๋ ๊ธธ์ด์ ๋ง์ถฐ ํจ๋ฉ
max_length=12, # ๋ฌธ์ฅ์ ํ ํฐ ๊ธฐ์ค ์ต๋ ๊ธธ์ด
truncation=True, # ๋ฌธ์ฅ ์๋ฆผ ํ์ฉ ์ต์
)
- ์ฝ๋ ์คํ ๊ฒฐ๊ณผ๋ก ๋ ๊ฐ์ง์ ์ ๋ ฅ๊ฐ์ด ๋ง๋ค์ด์ง๋๋ค.
- ํ๋๋ input_ids์ ๋๋ค. batch_inputs['input_ids']๋ฅผ ์ฝ๋ฉ์์ ์คํํด ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํด๋ณด๋ฉด input_ids์ ์คํ ๊ฒฐ๊ณผ์ ๊ฐ์ต๋๋ค
batch_input์ ๋ด์ฉ์ ํ๋ฒ ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.
batch_inputs.keys()
dict_keys(['input_ids', 'attention_mask'])
- input_ids๋ ํ ํฐํ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง๊ณ ๊ฐ ํ ํฐ๋ค์ ์ธ๋ฑ์ค(index)๋ก ๋ฐ๊พผ ๊ฒ์ ๋๋ค.
- ์ดํ ์งํฉ(vocab.json)์ ํ์ธํด ๋ณด๋ฉด ๊ฐ ์ดํ๊ฐ ์์๋๋ก ๋์ด๋ ํ์ธํ ์ ์๋๋ฐ์. ์ด ์์๊ฐ ๋ฐ๋ก ์ธ๋ฑ์ค์ ๋๋ค.
- ์ด๊ฐ์ด ๊ฐ ํ ํฐ์ ์ธ๋ฑ์ค๋ก ๋ณํํ๋ ๊ณผ์ ์์ธ๋ฑ์ฑ(indexing)>์ด๋ผ๊ณ ํฉ๋๋ค.
batch_inputs['input_ids']
[[334, 2338, 263, 581, 4055, 464, 3808, 0, 0, 0, 0, 0], [3693, 336, 2876, 758, 2883, 356, 806, 422, 9875, 875, 2960, 7292], [4957, 451, 3653, 263, 0, 0, 0, 0, 0, 0, 0, 0]]
- attention_mask๋ ์ผ๋ฐ ํ ํฐ์ด ์๋ฆฌํ ๊ณณ(1)๊ณผ ํจ๋ฉ ํ ํฐ์ด ์๋ฆฌํ ๊ณณ(0)์ ๊ตฌ๋ถํด ์๋ ค์ฃผ๋ ์ฅ์น์ ๋๋ค
batch_inputs['attention_mask']
[[1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
3๋จ๊ณ: BERT ์ ๋ ฅ๊ฐ ๋ง๋ค๊ธฐ
- ์ด๋ฒ์ BERT ๋ชจ๋ธ์ ์ ๋ ฅ๊ฐ์ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค. BERT Tokenizer ์ ์ธํ๋ ์ฝ๋๋ฅผ ์ํํ๋ฉด BERT ๋ชจ๋ธ์ด ์ฌ์ฉํ๋ ํ ํฌ๋์ด์ ๋ฅผ ์ด๊ธฐํํ ์ ์์ต๋๋ค.
- ๊ทธ์ ์ ์์ ์ ๊ตฌ๊ธ ๋๋ผ์ด๋ธ ๊ฒฝ๋ก(/gdrive/My Drive/nlpbook/wordpiece)์๋ BERT์ฉ ์๋ํผ์ค ์ดํ ์งํฉ(vocab.txt)์ด ์์ด์ผ ํฉ๋๋ค. ๋ง์ฝ vocab.txt๋ฅผ ์์ฑํ์ง ์์๋ค๋ฉด ๊ผญ ์์ฑํด์ฃผ์ธ์!
from transformers import BertTokenizer
tokenizer_bert = BertTokenizer.from_pretrained("/gdrive/My Drive/nlpbook/wordpiece", do_lower_case=False)
์ด์ ํ๋ฒ ์์ ๋ฌธ์ฅ 3๊ฐ๋ฅผ ๊ฐ๊ฐ ํ ํฐํ ํด๋ณด๊ฒ ์ต๋๋ค.
sentences = [
"์ ๋๋น.. ์ง์ง ์ง์ฆ๋๋ค์ ๋ชฉ์๋ฆฌ",
"ํ ...ํฌ์คํฐ๋ณด๊ณ ์ด๋ฉ์ํ์ค....์ค๋ฒ์ฐ๊ธฐ์กฐ์ฐจ ๊ฐ๋ณ์ง ์๊ตฌ๋",
"๋ณ๋ฃจ ์๋ค..",
]
tokenized_sentences = [tokenizer_bert.tokenize(sentence) for sentence in sentences]
- ์ฝ๋๋ฅผ ์คํ์ํค๊ณ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด๋ฉด, ํ ํฐ ์ผ๋ถ์ '##' ์ด๋ ๊ฒ ์๋ ํ ํฐ์ด ์์๊ฒ๋๋ค.
- ์ด ํ ํฐ์ ์ด์ (๋์ด์ฐ๊ธฐ ๊ธฐ์ค)์ ์์์ด ์๋์ ๋ํ๋ ๋๋ค.>
- ์๋ฅผ ๋ค์ด '##๋ค์' ๋ ์ด ํ ํฐ์ด ์์ ํ ํฐ >์ง์ฆ๋์ ๊ฐ์ ์ด์ ์ ์์นํ๋ฉฐ ์ด์ ๋ด์์ ์ฐ์๋๊ณ ์์์ ํ์ํฉ๋๋ค.>
์๋ ์ฝ๋๋ BERT ๋ชจ๋ธ์ ์ค์ ์ฝ๋ ์ ๋ ฅ ๊ฐ์ ๋๋ค.
batch_inputs = tokenizer_bert(
sentences,
padding="max_length",
max_length=12,
truncation=True,
)
์ฝ๋๋ฅผ ์คํ์ํค๋ฉด ์ธ ๊ฐ์ง์ ์ ๋ ฅ๊ฐ์ด ๋ง๋ค์ด์ง๋๋ค.
batch_inputs.keys()
dict_keys(['input_ids', 'token_type_ids', 'attention_mask'])
- ํ๋๋ GPT ๋ชจ๋ธ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ํ ํฐ ์ธ๋ฑ์ค ์ํ์ค๋ฅผ ๋ํ๋ด๋ input_ids์ ๋๋ค.
batch_inputs['input_ids']๋ฅผ ์ ๋ ฅํ๊ณ ์ด๋ฅผ ์ถ๋ ฅํด ๋ณด๊ฒ ์ต๋๋ค.
[[2, 621, 2631, 16, 16, 1993, 3678, 1990, 3323, 3, 0, 0], [2, 997, 16, 16, 16, 2609, 2045, 2796, 1981, 1224, 16, 3], [2, 3274, 9508, 16, 16, 3, 0, 0, 0, 0, 0, 0]]
- ํ๋ฒ ๋ณด๋ฉด ๋ชจ๋ ๋ฌธ์ฅ ์์ 2, ๋์ 3์ด ๋ถ์ ๊ฑธ ํ์ธํ ์ ์์ต๋๋ค.
- ์ด๋ ๊ฐ๊ฐ [CLS], [SEP]๋ผ๋ ํ ํฐ์ ๋์ํ๋ ์ธ๋ฑ์ค์ธ๋ฐ์.
- BERT๋ ๋ฌธ์ฅ ์์๊ณผ ๋์ ์ด ๋ ๊ฐ ํ ํฐ์ ๋ง๋ถ์ด๋ ํน์ง์ด ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ attention_mask๋ ๋ง๋ค์ด์ง๋๋ค.
- BERT์ attention_mask๋ GPT์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ผ๋ฐ ํ ํฐ์ด ์๋ฆฌํ ๊ณณ(1)๊ณผ ํจ๋ฉ ํ ํฐ์ด ์๋ฆฌํ ๊ณณ(0)์ ๊ตฌ๋ถํด ์๋ ค์ค๋๋ค.
- ํ๋ฒ ์ฝ๋๋ฅผ ์คํ์์ผ์ ํ์ธํด ๋ณด๊ฒ ์ต๋๋ค.
batch_inputs['attention_mask']
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0]]
๋ง์ง๋ง์ผ๋ก token_type_ids ๋ผ๋ ์ ๋ ฅ๊ฐ๋ ๋ง๋ค์ด์ง๋๋ค. ์ด๋ ์ธ๊ทธ๋จผํธ(segment)์ ํด๋น ํฉ๋๋ค.
- ์ธ๊ทธ๋จผํธ(segment)์ ํด๋นํ๋ ๊ฐ์ 0์ ๋๋ค.
- ์ธ๊ทธ๋จผํธ ์ ๋ณด๋ฅผ ์ ๋ ฅํ๋ ๊ฑด BERT ๋ชจ๋ธ์ ํน์ง์ ๋๋ค.
- BERT ๋ชจ๋ธ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฌธ์(ํน์ ๋ฌธ์ฅ) 2๊ฐ๋ฅผ ์ ๋ ฅ๋ฐ๋๋ฐ์, ๋์ token_type_ids ๋ก ๊ตฌ๋ถํฉ๋๋ค.
- ์ฒซ ๋ฒ์งธ ์ธ๊ทธ๋จผํธ(๋ฌธ์ ํน์ ๋ฌธ์ฅ)์ ํด๋นํ๋ token_type_ids๋ 0, ๋ ๋ฒ์งธ ์ธ๊ทธ๋จผํธ๋ 1์ ๋๋ค.
batch_inputs['token_type_ids']
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
- ์ฌ๊ธฐ์๋ ๋ฌธ์ฅ์ ํ๋์ฉ ๋ฃ์์ผ๋ฏ๋ก token_type_ids๊ฐ ๋ชจ๋ 0์ผ๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค.
๋ฐ์ํ
'๐ NLP (์์ฐ์ด์ฒ๋ฆฌ) > ๐ Natural Language Processing' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[NLP] Seq2Seq, Encoder & Decoder (0) | 2024.01.19 |
---|---|
[NLP] Pre-Trained Language Model - ๋ฏธ๋ฆฌ ํ์ต๋ ์ธ์ด๋ชจ๋ธ (0) | 2024.01.18 |
[NLP] Building a vocabulary set - ์ดํ ์งํฉ ๊ตฌ์ถํ๊ธฐ (0) | 2024.01.18 |
[NLP] Tokenization - ํ ํฐํ๋? (0) | 2024.01.16 |
[NLP] ์ฒ์ ๋ง๋๋ ์์ฐ์ด ์ฒ๋ฆฌ & Transfer Learning (0) | 2024.01.16 |