[๐ค ๊ฐ์ข 6.6] Byte-Pair Encoding (BPE) ํ ํฐํ
BPE(Byte-Pair Encoding)๋ ์ด๊ธฐ์ ํ ์คํธ๋ฅผ ์์ถํ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๊ฐ๋ฐ๋ ํ, GPT ๋ชจ๋ธ์ ์ฌ์ ํ์ตํ ๋ ํ ํฐํ๋ฅผ ์ํด OpenAI์์ ์ฌ์ฉ๋์์ต๋๋ค. GPT, GPT-2, RoBERTa, BART ๋ฐ DeBERTa๋ฅผ ํฌํจํ ๋ง์ ํธ๋์คํฌ๋จธ ๋ชจ๋ธ์์ ์ฌ์ฉ๋ฉ๋๋ค.
๐ก ์ด ์น์ ์์๋ ์ ์ฒด ๊ตฌํ ๊ณผ์ ์ ๋ณด์ฌ์ฃผ๋ ๊ฒ๊น์ง๋ฅผ ํฌํจํ์ฌ BPE๋ฅผ ์ฌ์ธต์ ์ผ๋ก ๋ค๋ฃน๋๋ค. ํ ํฐํ ์๊ณ ๋ฆฌ์ฆ์ ๋ํ ์ผ๋ฐ์ ์ธ ๊ฐ์๋ง์ ์ํ๋ ๊ฒฝ์ฐ ์ด ์ฅ์ ๊ฑด๋๋ฐ์ด๋ ๋ฉ๋๋ค.
ํ์ต ์๊ณ ๋ฆฌ์ฆ
BPE ํ์ต์ ์ ๊ทํ ๋ฐ ์ฌ์ ํ ํฐํ ๋จ๊ณ๊ฐ ์๋ฃ๋ ํ, ๋ง๋ญ์น์ ์ฌ์ฉ๋ ๊ณ ์ ํ ๋จ์ด ์งํฉ์ ๊ณ์ฐํ๋ ๊ฒ์ผ๋ก ์์๋ฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ด๋ฌํ ๋จ์ด๋ค์ ๊ตฌ์ฑํ๋๋ฐ ์ฌ์ฉ๋ ๋ชจ๋ ๊ธฐํธ(๊ธ์)๋ฅผ ๋ฐํ์ผ๋ก vocabulary๋ฅผ ๊ตฌ์ถํฉ๋๋ค. ์์ฃผ ๊ฐ๋จํ ์๋ก์ ๋ง๋ญ์น๊ฐ ๋ค์ ๋ค์ฏ ๋จ์ด๋ฅผ ์ฌ์ฉํ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค:
"hug", "pug", "pun", "bun", "hugs"
๊ธฐ๋ณธ vocabulary๋ ["b", "g", "h", "n", "p", "s", "u"]๊ฐ ๋ฉ๋๋ค. ์ค์ ๋ก๋ ๊ธฐ๋ณธ vocabulary์๋ ์ต์ํ ๋ชจ๋ ASCII ๋ฌธ์์ ์ผ๋ถ ์ ๋์ฝ๋ ๋ฌธ์๊ฐ ํฌํจ๋ ๊ฒ์ ๋๋ค. ํ ํฐํํ๋ ๋์์ด ํ์ต ๋ง๋ญ์น์ ์๋ ๋ฌธ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ํด๋น ๋ฌธ์๋ "์ ์ ์๋ ํ ํฐ(unknown token)"์ผ๋ก ๋ณํ๋ฉ๋๋ค. ๋ง์ NLP ๋ชจ๋ธ์ด ์ด๋ชจํฐ์ฝ์ด ํฌํจ๋ ์ฝํ ์ธ ๋ฅผ ๋ถ์ํ๋๋ฐ ์ฌ๊ฐํ ์ด๋ ค์์ ๊ฒช๋ ์ด์ ์ ๋๋ค.
GPT-2 ๋ฐ RoBERTa ํ ํฌ๋์ด์ ๋ ์ด ๋ฌธ์ ๋ฅผ ๋งค์ฐ ์๋ฆฌํ๊ฒ ์ฒ๋ฆฌํฉ๋๋ค. ๋จ์ด๋ฅผ ์ ๋์ฝ๋ ๋ฌธ์๊ฐ ์๋ ๋ฐ์ดํธ ๋จ์๋ก ๊ตฌ์ฑ๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผํฉ๋๋ค. ์ด ๋ฐฉ๋ฒ์ผ๋ก ๊ธฐ๋ณธ vocabulary๋ ์์ ํฌ๊ธฐ(256)๋ฅผ ๊ฐ์ง๋ง ์๊ฐํ ์ ์๋ ๋ชจ๋ ๋ฌธ์๋ค์ด ์ฌ์ ํ ํฌํจ๋ ์ ์์ผ๋ฉฐ ์ ์ ์๋ ํ ํฐ์ผ๋ก ๋ณํ๋์ง ์์ต๋๋ค. ์ด ํธ๋ฆญ(trick)์ byte-level BPE ๋ผ๊ณ ํฉ๋๋ค.
์ด ๊ธฐ๋ณธ vocabulary๋ฅผ ๊ตฌํ ํ, ๊ธฐ์กด vocabulary์ ๋ ์์๋ฅผ ์๋ก์ด ๊ฒ์ผ๋ก ๋ณํฉํ๋ ๊ท์น์ธ merges ๋ฅผ ํ์ตํจ์ผ๋ก์จ ์ํ๋ vocabulary ํฌ๊ธฐ์ ๋๋ฌํ ๋๊น์ง ์ ํ ํฐ์ ์ถ๊ฐํฉ๋๋ค. ๋ฐ๋ผ์ ์ฒ์์๋ ์ด๋ฌํ ๋ณํฉ์ผ๋ก ๋ ๊ฐ์ ๋ฌธ์๊ฐ ์๋ ํ ํฐ์ด ์์ฑ๋๊ณ ํ์ต์ด ์งํ๋จ์ ๋ฐ๋ผ ๋ ๊ธด ํ์ ๋จ์ด(subwords)๊ฐ ์์ฑ๋ฉ๋๋ค.
ํ ํฌ๋์ด์ ํ์ต ๊ณผ์ ์์ ์ด๋ค ๋จ๊ณ์์๋ BPE ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ์ฅ ๋น๋ฒํ๊ฒ ์ถํํ๋ ํ ํฐ ์์ ๊ฒ์ํฉ๋๋ค(์ฌ๊ธฐ์ "์"์ ํ ๋จ์ด์์ ๋ ๊ฐ์ ์ฐ์ ํ ํฐ์ ์๋ฏธํ๊ณ ํ ํฐ์ ์ฒ์์๋ ๋จ์ผ ๋ฌธ์์ ๋๋ค). ๊ฒ์๋ ๊ณ ๋น๋ ํ ํฐ ์์ด ๋ณํฉ๋๋ฉฐ ์ด๋ฌํ ๊ณผ์ ์ด ๊ณ์ ๋ฐ๋ณต๋ฉ๋๋ค.
์ด์ ์์ ๋ก ๋์๊ฐ์ ๊ฐ ๋จ์ด๋ค์ ์ถํ๋น๋๊ฐ ๋ค์๊ณผ ๊ฐ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค:
("hug", 10), ("pug", 5), ("pun", 12), ("bun", 4), ("hugs", 5)
๋ง๋ญ์น ๋ด์ "hug"๊ฐ 10๋ฒ, "pug"๊ฐ 5๋ฒ, "pun"์ด 12๋ฒ, "bun"์ด 4๋ฒ, "hugs"๊ฐ 5๋ฒ ์ถํํ๋ค๋ ์๋ฏธ์ ๋๋ค. ๊ฐ ๋จ์ด๋ฅผ ํ ํฐ์ ๋ชฉ๋ก์ผ๋ก ๋ณผ ์ ์๋๋ก ๊ฐ ๋จ์ด๋ฅผ ๋ฌธ์(์ด๊ธฐ vocabulary๋ฅผ ๊ตฌ์ฑํ๋ ๋ฌธ์)๋ก ๋ถํ ํ์ฌ ํ์ต์ ์์ํฉ๋๋ค:
("h" "u" "g", 10), ("p" "u" "g", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "u" "g" "s", 5)
๊ทธ๋ฐ ๋ค์ ๊ฐ ๋ฌธ์ ์๋ค์ ์ดํด๋ด ์๋ค. ("h", "u")์ "hug" ๋ฐ "hugs"๋ผ๋ ๋จ์ด์ ์กด์ฌํ๋ฏ๋ก ๋ง๋ญ์น์์ ์ด 15๋ฒ ์ถํํ์ต๋๋ค. ๊ฐ์ฅ ๋น๋ฒํ ์์ ์๋๋๋ค. ๊ฐ์ฅ ๋น๋ฒํ๊ฒ ์ถํํ๋ ์์ "hug", "pug" ๋ฐ "hugs"์ ์๋ ("u", "g")์ด๋ฉฐ ์ด 20๋ฒ ์ถํํ์ต๋๋ค.
๋ฐ๋ผ์ ํ ํฌ๋์ด์ ๊ฐ ํ์ตํ ์ฒซ ๋ฒ์งธ ๋ณํฉ ๊ท์น์ ("u", "g") -> "ug"์ด๋ฉฐ, ์ด๋ "ug"๊ฐ vocabulary์ ์ถ๊ฐ๋๊ณ ์ฝํผ์ค ๋ด์ ๋ชจ๋ ๋จ์ด์์ "u"์ "g"๊ฐ ๋ณํฉ๋์ด์ผ ํจ์ ์๋ฏธํฉ๋๋ค. ์ด ๋จ๊ณ๊ฐ ๋๋๋ฉด vocabulary์ ๋ง๋ญ์น๊ฐ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝ๋ฉ๋๋ค:
Vocabulary: ["b", "g", "h", "n", "p", "s", "u", "ug"]
Corpus: ("h" "ug", 10), ("p" "ug", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "ug" "s", 5)
์ด์ 2๊ฐ์ ๋ฌธ์๋ณด๋ค ๋ ๊ธด ํ ํฐ์ด ์์ฑ๋๋ ๋ช ๊ฐ์ง ์์ด ์ฝํผ์ค ๋ด์ ์กด์ฌํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ("h", "ug")(๋ง๋ญ์น์ 15๋ฒ ์ถํ)๊ฐ ๊ทธ๊ฒ์ ๋๋ค. ์ด ๋จ๊ณ์์ ๊ฐ์ฅ ๋น๋ฒํ๊ฒ ์ถํ๋ ์์ ("u", "n")๋ก์ ๋ง๋ญ์น์ 16๋ฒ ๋ํ๋๋ฏ๋ก ํ์ต๋ ๋ ๋ฒ์งธ ๋ณํฉ ๊ท์น์ ("u", "n") -> "un"์ ๋๋ค. ์ด๋ฅผ vocabulary์ ์ถ๊ฐํ๊ณ ๊ธฐ์กด์ ๋ชจ๋ ํญ๋ชฉ์ ๋ณํฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ฉ๋๋ค:
Vocabulary: ["b", "g", "h", "n", "p", "s", "u", "ug", "un"]
Corpus: ("h" "ug", 10), ("p" "ug", 5), ("p" "un", 12), ("b" "un", 4), ("h" "ug" "s", 5)
์ด์ ๊ฐ์ฅ ๋น๋ฒํ ์์ ("h", "ug")์ด๋ฏ๋ก ๋ณํฉ ๊ท์น("h", "ug") -> "hug"์ ํ์ตํฉ๋๋ค. ์ฒ์์ผ๋ก 3๊ธ์๋ก ๊ตฌ์ฑ๋ ํ ํฐ์ด ๋ง๋ค์ด์ง๋๋ค. ๋ณํฉ ํ ์ฝํผ์ค๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Vocabulary: ["b", "g", "h", "n", "p", "s", "u", "ug", "un", "hug"]
Corpus: ("hug", 10), ("p" "ug", 5), ("p" "un", 12), ("b" "un", 4), ("hug" "s", 5)
์ํ๋ vocabulary ํฌ๊ธฐ์ ๋๋ฌํ ๋๊น์ง ์ด ์์ ์ ๊ณ์ํฉ๋๋ค.
โ๏ธ Now your turn! ๋ค์ ๋ณํฉ ๊ท์น์ ๋ฌด์์ผ๊น์?
ํ ํฐํ ์๊ณ ๋ฆฌ์ฆ
ํ ํฐํ๋ ๋ค์ ๋จ๊ณ๋ฅผ ์ ์ฉํ์ฌ ์๋ก์ด ์ ๋ ฅ์ ํ ํฐํํ๋ค๋ ์ ์์ ์์์ ์ดํด๋ณธ ํ์ต ํ๋ก์ธ์ค์ ๋ฐ์ ํ๊ฒ ์ฐ๊ด๋์ด ์์ต๋๋ค:
-
์ ๊ทํ (Normalization)
-
์ฌ์ ํ ํฐํ (Pre-tokenization)
-
๋จ์ด๋ฅผ ๊ฐ๋ณ ๋ฌธ์๋ค๋ก ๋ถํ
-
ํด๋น ๋ถํ ์ ์์๋๋ก ํ์ต๋ ๋ณํฉ ๊ท์น ์ ์ฉ
์์์ ํ์ต๋ 3๊ฐ์ง ๋ณํฉ ๊ท์น์ ์ ์ฉํ์ฌ ์๋ฅผ ๋ค์ด ๋ณด๊ฒ ์ต๋๋ค:
("u", "g") -> "ug"
("u", "n") -> "un"
("h", "ug") -> "hug"
"bug"๋ผ๋ ๋จ์ด๋ ["b", "ug"]๋ก ํ ํฐํ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ "mug"๋ ๊ธฐ๋ณธ vocabulary์ ๋ฌธ์ "m"์ด ์์๊ธฐ ๋๋ฌธ์ ["[UNK]", "ug"]๋ก ํ ํฐํ๋ฉ๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก "thug"๋ผ๋ ๋จ์ด๋ ["[UNK]", "hug"]๋ก ํ ํฐํ๋ฉ๋๋ค. ๋ฌธ์ "t"๋ ๊ธฐ๋ณธ vocabulary์ ์์ผ๋ฉฐ ๋ณํฉ ๊ท์น์ ์ ์ฉํ๋ฉด ๋จผ์ "u"์ "g"๊ฐ ๋ณํฉ๋ ๋ค์ "hu"์ "g"๊ฐ ๋ณํฉ๋ฉ๋๋ค.
โ๏ธ Now your turn! "unhug"๋ผ๋ ๋จ์ด๊ฐ ์ด๋ป๊ฒ ํ ํฐํ๋ ๊น์?
BPE ๊ตฌํ
์ด์ BPE ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์๋์์ ์ค๋ช ํ๋ ์ฝ๋๋ ๋๊ท๋ชจ ๋ง๋ญ์น์์ ์ค์ ๋ก ์ฌ์ฉํ ์ ์๋ ์ต์ ํ๋ ๋ฒ์ ์ด ์๋๋๋ค. ์๊ณ ๋ฆฌ์ฆ์ ์ฝ๊ฒ ์ดํดํ ์ ์๋๋ก ๊ตฌ์ฑ๋ ์ฝ๋์ ๋๋ค.
๋จผ์ ๋ง๋ญ์น๊ฐ ํ์ํ๋ฏ๋ก ๋ช ๋ฌธ์ฅ์ผ๋ก ๊ฐ๋จํ ๋ง๋ญ์น๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค:
corpus = [
"This is the Hugging Face course.",
"This chapter is about tokenization.",
"This section shows several tokenizer algorithms.",
"Hopefully, you will be able to understand how they are trained and generate tokens.",
]
๋ค์์ผ๋ก, ์ ๋ง๋ญ์น๋ฅผ ๋จ์ด ๋จ์๋ก ์ฌ์ ํ ํฐํ(pre-tokenize)ํด์ผ ํฉ๋๋ค. GPT-2์์ ์ฌ์ฉ๋ BPE ํ ํฌ๋์ด์ ๋ฅผ ๊ตฌํํ๊ณ ์์ผ๋ฏ๋ก ์ฌ์ ํ ํฐํ(pre-tokenization)์ gpt2
ํ ํฌ๋์ด์ ๋ฅผ ์ฌ์ฉํฉ๋๋ค:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
๊ทธ๋ฐ ๋ค์ ์ฌ์ ํ ํฐํ๋ฅผ ์ํํ๋ฉด์ ๋ง๋ญ์น์ ์๋ ๊ฐ ๋จ์ด์ ๋น๋๋ฅผ ํจ๊ป ๊ณ์ฐํฉ๋๋ค:
from collections import defaultdict
word_freqs = defaultdict(int)
for text in corpus:
words_with_offsets = tokenizer.backend_tokenizer.pre_tokenizer.pre_tokenize_str(text)
new_words = [word for word, offset in words_with_offsets]
for word in new_words:
word_freqs[word] += 1
print(word_freqs)
๋ค์ ๋จ๊ณ๋ ๋ง๋ญ์น์ ์ฌ์ฉ๋ ๋ชจ๋ ๋ฌธ์๋ก ๊ตฌ์ฑ๋ ๊ธฐ๋ณธ vocabulary๋ฅผ ๊ตฌํ๋ ๊ฒ์ ๋๋ค:
alphabet = []
for word in word_freqs.keys():
for letter in word:
if letter not in alphabet:
alphabet.append(letter)
alphabet.sort()
print(alphabet)
์ถ๊ฐ์ ์ผ๋ก ํด๋น vocabulary์ ์์ ๋ถ๋ถ์ ๋ชจ๋ธ์ด ์ฌ์ฉํ๋ ํน์ ํ ํฐ์ ์ถ๊ฐํฉ๋๋ค. GPT-2์ ๊ฒฝ์ฐ ์ ์ผํ ํน์ ํ ํฐ์ "<|endoftext|>"์ ๋๋ค:
vocab = ["<|endoftext|>"] + alphabet.copy()
์ด์ ํ์ต์ ์์ํ ์ ์๋๋ก ๊ฐ ๋จ์ด๋ฅผ ๊ฐ๋ณ ๋ฌธ์๋ก ๋ถํ ํด์ผ ํฉ๋๋ค:
splits = {word: [c for c in word] for word in word_freqs.keys()}
์ด์ ํ์ตํ ์ค๋น๊ฐ ๋์์ผ๋ฏ๋ก ๊ฐ ์์ ๋น๋๋ฅผ ๊ณ์ฐํ๋ ํจ์๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค. ํ์ต์ ๊ฐ ๋จ๊ณ์์ ์ด๊ฒ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค:
def compute_pair_freqs(splits):
pair_freqs = defaultdict(int)
for word, freq in word_freqs.items():
split = splits[word]
if len(split) == 1:
continue
for i in range(len(split) - 1):
pair = (split[i], split[i+1])
pair_freqs[pair] += freq
return pair_freqs
์ด๊ธฐ ๋ถํ ํ ์ด ๋์
๋๋ฆฌ(pair-freqs
)์ ์ผ๋ถ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
pair_freqs = compute_pair_freqs(splits)
for i, key in enumerate(pair_freqs.keys()):
print(f"{key}: {pair_freqs[key]}")
if i > 5:
break
์ด์ ๊ฐ๋จํ ๋ฃจํ๋ฅผ ์ด์ฉํด์ ๊ฐ์ฅ ๋น๋ฒํ๊ฒ ์ถํํ๋ ์์ ์ฐพ์๋ณด๊ฒ ์ต๋๋ค:
best_pair = ""
max_freq = None
for pair, freq in pair_freqs.items():
if max_freq is None or max_freq < freq:
best_pair = pair
max_freq = freq
print(best_pair, max_freq)
๋ฐ๋ผ์ ํ์ตํ ์ฒซ ๋ฒ์งธ ๋ณํฉ์ ('ฤ ', 't') -> 'ฤ t'์ด๊ณ vocabulary์ 'ฤ t'๋ฅผ ์ถ๊ฐํฉ๋๋ค:
merges = {("ฤ ", "t"): "ฤ t"}
vocab.append("ฤ t")
๊ณ์ํ๋ ค๋ฉด splits
๋์
๋๋ฆฌ์ ํด๋น ๋ณํฉ์ ์ ์ฉํด์ผ ํฉ๋๋ค. ์ด๋ฅผ ์ํด ๋ค๋ฅธ ํจ์๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค:
def merge_pair(a, b, splits):
for word in word_freqs:
split = splits[word]
if len(split) == 1:
continue
i = 0
while i < len(split) - 1:
if split[i] == a and split[i + 1] == b:
split = split[:i] + [a + b] + split[i + 2 :]
else:
i += 1
splits[word] = split
return splits
์ด์ ์ฒซ๋ฒ์งธ ๋ณํฉ์ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ ์์ต๋๋ค:
splits = merge_pair("ฤ ", "t", splits)
print(splits["ฤ trained"])
์ด์ ์ํ๋ ๋ชจ๋ ๋ณํฉ์ ํ์ตํ ๋๊น์ง ๋ฐ๋ณตํ๋ ๋ชจ๋์ ๊ตฌ์ฑํ ์ ์์ต๋๋ค. Vocabulary์ ํฌ๊ธฐ๋ฅผ 50์ผ๋ก ์ง์ ํด๋ด ์๋ค:
vocab_size = 50
while len(vocab) < vocab_size:
pair_freqs = compute_pair_freqs(splits)
best_pair = ""
max_freq = None
for pair, freq in pair_freqs.items():
if max_freq is None or max_freq < freq:
best_pair = pair
max_freq = freq
splits = merge_pair(*best_pair, splits)
merges[best_pair] = best_pair[0] + best_pair[1]
vocab.append(best_pair[0] + best_pair[1])
๊ฒฐ๊ณผ์ ์ผ๋ก 19๊ฐ์ง ๋ณํฉ ๊ท์น์ ํ์ตํ์ต๋๋ค(์ด๊ธฐ vocabulary์ ํฌ๊ธฐ๋ ์ํ๋ฒณ 31 - 30์, ํน์ ํ ํฐ ํฌํจ):
print(merges)
๊ทธ๋ฆฌ๊ณ vocabulary๋ ํน์ ํ ํฐ, ์ด๊ธฐ ์ํ๋ฒณ ๋ฐ ๋ณํฉ์ ๋ชจ๋ ๊ฒฐ๊ณผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค:
print(vocab)
๐ก ๋์ผํ ๋ง๋ญ์น์์
train_new_from_iterator()
๋ฅผ ์ฌ์ฉํ๋ฉด ๋๊ฐ์ vocabulary๊ฐ ๋์ถ๋์ง ์์ต๋๋ค. ์ด๋ ๊ฐ์ฅ ๋น๋ฒํ๊ฒ ์ถํํ ์์ ์ ํํ ๋ ๊ฐ์ฅ ๋จผ์ ๋ง์ฃผ์น๋ ์์ ์ ํํ๋ ๋ฐ๋ฉด์, ๐คTokenizers ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ด๋ถ IDs๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ฒซ ๋ฒ์งธ ์์ ์ ํํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์๋ก์ด ํ ์คํธ๋ฅผ ํ ํฐํํ๊ธฐ ์ํด์๋ ์ฐ์ ์ฌ์ ํ ํฐํ(pre-tokenize)ํ๊ณ ๋ถํ (split)ํ ๋ค์ ํ์ตํ ๋ชจ๋ ๋ณํฉ ๊ท์น(merge rules)์ ์ ์ฉํ๋ฉด ๋ฉ๋๋ค:
def tokenize(text):
pre_tokenize_result = tokenizer._tokenizer.pre_tokenizer.pre_tokenize_str(text)
pre_tokenized_text = [word for word, offset in pre_tokenize_result]
splits = [[l for l in word] for word in pre_tokenized_text]
for pair, merge in merges.items():
for idx, split in enumerate(splits):
i = 0
while i < len(split) - 1:
if split[i] == pair[0] and split[i + 1] == pair[1]:
split = split[:i] + [merge] + split[i + 2 :]
else:
i += 1
splits[idx] = split
return sum(splits, [])
์ํ๋ฒณ ๋ฌธ์๋ก ๊ตฌ์ฑ๋ ๋ชจ๋ ํ ์คํธ๋ฅผ ํ ํฐํํ ์ ์์ต๋๋ค:
tokenize("This is not a token.")
โ ๏ธ ์์ธ ์ฒ๋ฆฌ๋ฅผ ํ์ง ์์๊ธฐ ๋๋ฌธ์ ์ ์ ์๋ ๋ฌธ์(unknown character)๊ฐ ์์ผ๋ฉด ๊ตฌํ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. GPT-2์๋ ์ค์ ๋ก ์ ์ ์๋ ํ ํฐ์ด ์์ง๋ง(๋ฐ์ดํธ ์์ค BPE๋ฅผ ์ฌ์ฉํ ๋ ์ ์ ์๋ ๋ฌธ์๋ฅผ ์ป๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํฉ๋๋ค), ์ฌ๊ธฐ์๋ ์ด๊ธฐ vocabulary์ ๊ฐ๋ฅํ ๋ชจ๋ ๋ฐ์ดํธ๋ฅผ ํฌํจํ์ง ์์๊ธฐ ๋๋ฌธ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด ๋ถ๋ถ์ ์ด ์น์ ์ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ฏ๋ก ์ธ๋ถ ์ฌํญ์ ์๋ตํ์ต๋๋ค.
BPE ์๊ณ ๋ฆฌ์ฆ์ ๋ํ ๋ด์ฉ์ด ๋๋ฌ์ต๋๋ค! ๋ค์์ผ๋ก WordPiece๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ([๐ค ๊ฐ์ข 6.6] Byte-Pair Encoding (BPE) ํ ํฐํ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@spasis/๊ฐ์ข-6.6-Byte-Pair-Encoding-BPE-ํ ํฐํ์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค