[๐ค ๊ฐ์ข 6.7] WordPiece ํ ํฐํ
WordPiece๋ Google์ด BERT๋ฅผ ์ฌ์ ํ์ตํ๊ธฐ ์ํด ๊ฐ๋ฐํ ํ ํฐํ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ๊ทธ ์ดํ๋ก DitilBERT, MobileBERT, Funnel Transformers ๋ฐ MPNET๊ณผ ๊ฐ์ BERT ๊ธฐ๋ฐ์ ์๋นํ ๋ง์ Transformer ๋ชจ๋ธ์์ ์ฌ์ฌ์ฉ๋์์ต๋๋ค. ํ์ต ์ธก๋ฉด์์ BPE์ ๋งค์ฐ ์ ์ฌํ์ง๋ง ์ค์ ํ ํฐํ๋ ๋ค๋ฅด๊ฒ ์ํ๋ฉ๋๋ค.
๐ก ์ด ์น์ ์์๋ WordPiece๋ฅผ ์ฌ์ธต์ ์ผ๋ก ๋ค๋ฃจ๋ฉฐ ์ ์ฒด ๊ตฌํ ๊ณผ์ ์ ๋ณด์ฌ์ค๋๋ค. ํ ํฐํ ์๊ณ ๋ฆฌ์ฆ์ ๋ํ ์ผ๋ฐ์ ์ธ ๊ฐ์๋ฅผ ์ํ๋ ๊ฒฝ์ฐ ์๋ตํด๋ ์ข์ต๋๋ค.
ํ์ต ์๊ณ ๋ฆฌ์ฆ
โ ๏ธ Google์ WordPiece์ ํ์ต ์๊ณ ๋ฆฌ์ฆ ๊ตฌํ์ ์คํ ์์ค๋ก ๊ณต๊ฐํ์ง ์์์ผ๋ฏ๋ก ์ด๋ฒ ์น์ ์์๋ ๋ฐํ๋ ๋ ผ๋ฌธ ๋ด์ฉ์ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํ ๊ณผ์ ์ ์ค๋ช ํฉ๋๋ค. ๊ฑฐ์ 100% ์ ํํ ๊ฒ์ ๋๋ค.
BPE์ ๋ง์ฐฌ๊ฐ์ง๋ก WordPiece๋ ๋ชจ๋ธ์์ ์ฌ์ฉํ๋ ํน์ ํ ํฐ๊ณผ ์ด๊ธฐ ์ํ๋ฒณ์ ํฌํจํ ์์ vocabulary์์ ์์ํฉ๋๋ค. ์ ๋์ฌ(์: BERT์ ##)๋ฅผ ์ถ๊ฐํ์ฌ ํ์ ๋จ์ด(subwords)๋ฅผ ์๋ณํ๊ธฐ ๋๋ฌธ์ ๊ฐ ๋จ์ด๋ ์ฒ์์ ํด๋น ์ ๋์ฌ๋ฅผ ๋จ์ด ๋ด๋ถ์ ๋ชจ๋ ๋ฌธ์์ ์ถ๊ฐํ์ฌ ๋ถํ ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด "word"๋ ๋ค์๊ณผ ๊ฐ์ด ๋ถํ ๋ฉ๋๋ค.
w ##o ##r ##d
๋ฐ๋ผ์ ์ด๊ธฐ ์ํ๋ฒณ์๋ ๋จ์ด์ ์์ ๋ถ๋ถ์ ์๋ ๋ชจ๋ ๋ฌธ์๋ค(์: 'w')๊ณผ WordPiece ์ ๋์ฌ๊ฐ ์ ํํ๋ ๋จ์ด ๋ด๋ถ์ ์๋ ๋ฌธ์(์: 'o', 'r', 'd')๊ฐ ํฌํจ๋ฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ BPE์ ๋ง์ฐฌ๊ฐ์ง๋ก WordPiece๋ ๋ณํฉ ๊ท์น์ ํ์ตํฉ๋๋ค. ์ฃผ์ ์ฐจ์ด์ ์ ๋ณํฉํ ์์ด ์ ํ๋๋ ๋ฐฉ์์ ๋๋ค. ๊ฐ์ฅ ๋น๋ฒํ๊ฒ ์ถํํ๋ ์์ ์ ํํ๋ ๋์ WordPiece๋ ๋ค์ ๊ณต์์ ์ฌ์ฉํ์ฌ ๊ฐ ์์ ๋ํ ์ ์๋ฅผ ๊ณ์ฐํฉ๋๋ค:
์์ ๋น๋๋ฅผ ๊ฐ ๋ถ๋ถ์ ๋น๋์ ๊ณฑ์ผ๋ก ๋๋์ผ๋ก์จ, ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ ๊ฐ๋ณ ๋ถ๋ถ๋ค์ ๋น๋๊ฐ ๋ฎ์ ์์ ๋ณํฉ์ ๋์ ์ฐ์ ์์๋ฅผ ๋ถ์ฌํฉ๋๋ค. ์๋ฅผ ๋ค์ด, vocabulary ๋ด์์์ ์ถํ ๋น๋๊ฐ ๋์ ("un", "##able") ์์ ๊ตณ์ด ๋ณํฉํ ํ์๋ ์๋๋ฐ, ๊ทธ ์ด์ ๋ "un"๊ณผ "##able" ๊ฐ๊ฐ์ด ๋ค๋ฅธ ๋จ์ด ๋ด์์ ๋งค์ฐ ๋น๋ฒํ๊ฒ ์ถํํ์ฌ ๋์ ๋น๋๋ฅผ ๋ํ๋ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ฐ๋ฉด์, "hu"์ "##gging"์ ๊ฐ๊ฐ์ด ์์ฃผ ์ฌ์ฉ๋์ง ์๊ธฐ ๋๋ฌธ์ ("hu", "##gging")๊ณผ ๊ฐ์ ์์ ์๋ง๋ ๋ ๋นจ๋ฆฌ ๋ณํฉ๋ ๊ฒ์ ๋๋ค("hugging"์ด๋ผ๋ ๋จ์ด๊ฐ ์ดํ์ ์์ฃผ ๋ฑ์ฅํ๋ค๊ณ ๊ฐ์ ).
์์ BPE ํ์ต ์์์์ ์ฌ์ฉํ ๊ฒ๊ณผ ๋์ผํ vocabulary๋ฅผ ์ฌ์ฉํด์ ์ค๋ช ํ๊ฒ ์ต๋๋ค:
("hug", 10), ("pug", 5), ("pun", 12), ("bun", 4), ("hugs", 5)
๋ถํ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
("h" "##u" "##g", 10), ("p" "##u" "##g", 5), ("p" "##u" "##n", 12), ("b" "##u" "##n", 4), ("h" "##u" "##g" "##s", 5)
๋ฐ๋ผ์ ์ด๊ธฐ vocabulary๋ ["b", "h", "p", "##g", "##n", "##s", "##u"]๊ฐ ๋ฉ๋๋ค(ํน์ ํ ํฐ์ ์ผ๋จ ์์ด๋ฒ๋ฆฝ์๋ค). ๊ฐ์ฅ ๋น๋ฒํ ์์ ("##u", "##g")(ํ์ฌ 20ํ)์ด์ง๋ง "##u"์ ๊ฐ๋ณ ๋น๋๊ฐ ๋งค์ฐ ๋์ ์ ์๊ฐ ๊ฐ์ฅ ๋์ง๋ ์์ต๋๋ค(1/36). "##u"๊ฐ ํฌํจ๋ ๋ชจ๋ ์์ ์ค์ ๋ก ๋์ผํ ์ ์(1/36)๋ฅผ ๊ฐ์ง๋ฏ๋ก ๊ฐ์ฅ ์ข์ ์ ์๋ ("##g", "##s")์ด ๊ฐ์ง๊ณ ์์ต๋๋ค(1/20). ์ด๋ "##u"๊ฐ ์๋ ์ ์ผํ ์์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ํ์ต๋ ์ฒซ ๋ฒ์งธ ๋ณํฉ์ ("##g", "##s") -> ("##gs")์ ๋๋ค.
๋ณํฉํ ๋ ๋ ํ ํฐ ์ฌ์ด์ ##์ ์ ๊ฑฐํ๋ฏ๋ก vocabulary์ "##gs"๋ฅผ ์ถ๊ฐํ๊ณ ๋ง๋ญ์น์ ๋ชจ๋ ๋จ์ด์ ํด๋น ๋ณํฉ์ ์ ์ฉํฉ๋๋ค:
Vocabulary: ["b", "h", "p", "##g", "##n", "##s", "##u", "##gs"]
Corpus: ("h" "##u" "##g", 10), ("p" "##u" "##g", 5), ("p" "##u" "##n", 12), ("b" "##u" "##n", 4), ("h" "##u" "##gs", 5)
์ด ์์ ์์ "##u"๋ ๊ฐ๋ฅํ ๋ชจ๋ ์์ ์์ผ๋ฏ๋ก ๋ชจ๋ ๋์ผํ ์ ์๋ฅผ ๊ฐ์ง๋๋ค. ์ด ๊ฒฝ์ฐ ์ฒซ ๋ฒ์งธ ์์ด ๋ณํฉ๋๋ฏ๋ก ("h", "##u") -> "hu"๊ฐ ํ์ต๋ฉ๋๋ค. ๊ทธ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
Vocabulary: ["b", "h", "p", "##g", "##n", "##s", "##u", "##gs", "hu"]
Corpus: ("hu" "##g", 10), ("p" "##u" "##g", 5), ("p" "##u" "##n", 12), ("b" "##u" "##n", 4), ("hu" "##gs", 5)
์ด์ ์ต๊ณ ์ ์๋ ("hu", "##g") ๋ฐ ("hu", "##gs")๊ฐ ๋์ผํ๊ฒ ๊ณ์ฐ๋๋ฏ๋ก(๋ค๋ฅธ ๋ชจ๋ ์์ ๊ฒฝ์ฐ 1/21์ด๊ณ ์ด ๋ ์์ 1/15) ๊ฐ์ฅ ํฐ ์ ์๋ฅผ ๊ฐ์ง ์ฒซ ๋ฒ์งธ ์์ด ๋ณํฉ๋ฉ๋๋ค.
Vocabulary: ["b", "h", "p", "##g", "##n", "##s", "##u", "##gs", "hu", "hug"]
Corpus: ("hug", 10), ("p" "##u" "##g", 5), ("p" "##u" "##n", 12), ("b" "##u" "##n", 4), ("hu" "##gs", 5)
์ํ๋ ์ดํ ํฌ๊ธฐ์ ๋๋ฌํ ๋๊น์ง ์ด ๋จ๊ณ๊ฐ ๊ณ์ ๋ฐ๋ณต๋ฉ๋๋ค.
โ๏ธ Now your turn! ๋ค์ ๋ณํฉ ๊ท์น์ ๋ฌด์์ผ๊น์?
ํ ํฐํ ์๊ณ ๋ฆฌ์ฆ
ํ ํฐํ๋ WordPiece๊ฐ ํ์ต๋ ๋ณํฉ ๊ท์น์ ์ ์ธํ๊ณ ์ต์ข vocabulary๋ง ์ ์ฅํ๋ค๋ ์ ์์ BPE์๋ ๋ค๋ฆ ๋๋ค. ํ ํฐํํ ๋จ์ด์์ ์์ํ์ฌ WordPiece๋ vocabulary์ ์๋ ๊ฐ์ฅ ๊ธด ํ์ ๋จ์ด๋ฅผ ์ฐพ์ ๋ค์ ๋ถํ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์์ ์์์ ํ์ตํ vocabulary๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ๋จ์ด "hugs"์ ๊ฒฝ์ฐ ์ฒ์๋ถํฐ ์์ํ๋ ๊ฐ์ฅ ๊ธด ํ์ ๋จ์ด๋ vocabulary ๋ด๋ถ์ ์๋ "hug"์ด๋ฏ๋ก ๊ฑฐ๊ธฐ์์ ๋ถํ ํ์ฌ ["hug", "##s"]๋ก ๋ถํ ๋ฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ "##s"๊ฐ vocabulary์ ์กด์ฌํ๊ณ ์ด๋ฅผ ๊ณ์ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก "hugs"์ ํ ํฐํ ๊ฒฐ๊ณผ๋ ["hug", "##s"]์ ๋๋ค.
BPE๋ฅผ ์ฌ์ฉํ๋ฉด ํ์ต๋ ๋ณํฉ(merges)์ ์์๋๋ก ์ ์ฉํ๊ณ ์ด๋ฅผ ["hu", "##gs"]๋ก ํ ํฐํํ๋ฏ๋ก ์ธ์ฝ๋ฉ์ด ๋ค๋ฅด๊ฒ ๋ฉ๋๋ค.
๋ ๋ค๋ฅธ ์๋ก "bugs"๋ผ๋ ๋จ์ด๊ฐ ์ด๋ป๊ฒ ํ ํฐํ๋๋์ง ๋ด ์๋ค. "b"๋ vocabulary์ ์กด์ฌํ๋ ๋จ์ด์ ์์ ๋ถ๋ถ์์ ์์ํ๋ ๊ฐ์ฅ ๊ธด ํ์ ๋จ์ด์ด๋ฏ๋ก ๊ฑฐ๊ธฐ์ ๋ถํ ํ์ฌ ["b", "##ugs"]๋ผ๋ ์ค๊ฐ ๊ฒฐ๊ณผ๊ฐ ๋์ถ๋ฉ๋๋ค. ๋ค์์ผ๋ก "##u"๋ vocabulary์ ์๋ "##ugs"์ ์์ ๋ถ๋ถ์์ ์์ํ๋ ๊ฐ์ฅ ๊ธด ํ์ ๋จ์ด์ด๋ฏ๋ก ๊ฑฐ๊ธฐ์์ ๋ถํ ํ์ฌ ["b", "##u, "##gs"]๋ฅผ ์ป์ต๋๋ค. ๋ง์ง๋ง์ผ๋ก "##gs"๊ฐ vocabulary์ ์์ผ๋ฏ๋ก ["b", "##u, "##gs"]์ด "bugs"์ ํ ํฐํ ๊ฒฐ๊ณผ์ ๋๋ค.
ํ ํฐํ๊ฐ vocabulary์์ ํ์ ๋จ์ด(subword)๋ฅผ ๋์ด์ ์ฐพ์ ์ ์๋ ๋จ๊ณ์ ๋๋ฌํ๋ฉด ์ ์ฒด ๋จ์ด๋ฅผ "unknown"์ผ๋ก ํ ํฐํํฉ๋๋ค. ์๋ฅผ ๋ค์ด "mug"๋ "bum"๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ["[UNK]"]๋ก ํ ํฐํ๋ฉ๋๋ค("b"์ "##u"๋ก ์์ํ ์ ์๋๋ผ๋ "##m"์ด vocabulary์ ์กด์ฌํ์ง ์์ผ๋ฏ๋ก ๊ฒฐ๊ณผ ํ ํฐํ๋ ["b", "##u", "[UNK]"]๊ฐ ์๋๋ผ ["[UNK]"]์ ๋๋ค). ์ด๊ฒ์ vocabulary์ ์๋ ๊ฐ๋ณ ๋ฌธ์๋ง "unknwon"์ผ๋ก ๋ถ๋ฅํ๋ BPE์์ ๋ ๋ค๋ฅธ ์ฐจ์ด์ ์ ๋๋ค.
โ๏ธ Now your turn! "pugs"๋ผ๋ ๋จ์ด๋ ์ด๋ป๊ฒ ํ ํฐํ๋ ๊น์?
WordPiece ๊ตฌํ
์ด์ WordPiece ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. 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-tokenization)ํด์ผ ํฉ๋๋ค. BERT์ ๊ฐ์ WordPiece ํ ํฌ๋์ด์ ๋ฅผ ๊ตฌํํ๊ณ ์์ผ๋ฏ๋ก ์ฌ์ ํ ํฐํ์ bert-base-cased
ํ ํฌ๋์ด์ ๋ฅผ ์ฌ์ฉํฉ๋๋ค:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
๊ทธ๋ฐ ๋ค์ ์ฌ์ ํ ํฐํ ์ํ ๊ณผ์ ์์ ๋ง๋ญ์น์ ์๋ ๊ฐ ๋จ์ด์ ๋น๋๋ฅผ ๊ณ์ฐํฉ๋๋ค:
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
word_freqs
์ด์ ์ ๋ณด์๋ฏ์ด ์ํ๋ฒณ์ ๋จ์ด์ ๋ชจ๋ ์ฒซ ๊ธ์์ ## ์ ๋์ฌ๊ฐ ๋ถ์ ๋จ์ด์ ๋ํ๋๋ ๋ค๋ฅธ ๋ชจ๋ ๊ธ์๋ก ๊ตฌ์ฑ๋ ๊ณ ์ ํ ์งํฉ์ ๋๋ค:
alphabet = []
for word in word_freqs.keys():
if word[0] not in alphabet:
alphabet.append(word[0])
for letter in word[1:]:
if f"##{letter}" not in alphabet:
alphabet.append(f"##{letter}")
alphabet.sort()
alphabet
print(alphabet)
๋ํ ํด๋น vocabulary์ ์์ ๋ถ๋ถ์ ๋ชจ๋ธ์ด ์ฌ์ฉํ๋ ํน์ ํ ํฐ์ ์ถ๊ฐํฉ๋๋ค. BERT์ ๊ฒฝ์ฐ ["[PAD]", "[UNK]", "[CLS]", "[SEP]", "[MASK]"]์ ๋๋ค:
vocab = ["[PAD]", "[UNK]", "[CLS]", "[SEP]", "[MASK]"] + alphabet.copy()
๋ค์์ผ๋ก vocabulary์ ์กด์ฌํ๋ ์ ๋์ฌ๊ฐ ##์ด ์๋ ๋ชจ๋ ๋ฌธ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ ๋จ์ด๋ฅผ ๋ถํ ํด์ผ ํฉ๋๋ค:
splits = {
word: [c if i == 0 else f"##{c}" for i, c in enumerate(word)]
for word in word_freqs.keys()
}
์ด์ ํ์ตํ ์ค๋น๊ฐ ๋์์ผ๋ฏ๋ก ๊ฐ ์์ ์ ์๋ฅผ ๊ณ์ฐํ๋ ํจ์๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค. ํ์ต์ ๊ฐ ๋จ๊ณ์์ ์ด ํจ์๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค:
def compute_pair_scores(splits):
letter_freqs = defaultdict(int)
pair_freqs = defaultdict(int)
for word, freq in word_freqs.items():
split = splits[word]
if len(split) == 1:
letter_freqs[split[0]] += freq
continue
for i in range(len(split) - 1):
pair = (split[i], split[i + 1])
letter_freqs[split[i]] += freq
pair_freqs[pair] += freq
letter_freqs[split[-1]] += freq
scores = {
pair: freq / (letter_freqs[pair[0]] * letter_freqs[pair[1]])
for pair, freq in pair_freqs.items()
}
return scores
์ด๊ธฐ ๋ถํ ํ pair_scores
์ ์ผ๋ถ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
pair_scores = compute_pair_scores(splits)
for i, key in enumerate(pair_scores.keys()):
print(f"{key}: {pair_scores[key]}")
if i >= 5:
break
์ด์ ์ต๊ณ ์ ์ ์๋ฅผ ๊ฐ์ง ์์ ์ฐพ๋ ๊ฐ๋จํ ๋ฃจํ๋ฅผ ๊ตฌํํฉ๋๋ค:
best_pair = ""
max_score = None
for pair, score in pair_scores.items():
if max_score is None or max_score < score:
best_pair = pair
max_score = score
print(best_pair, max_score)
๋ฐ๋ผ์ ํ์ตํ ์ฒซ ๋ฒ์งธ ๋ณํฉ์ ('a', '##b') -> 'ab'์ด๊ณ vocabulary์ 'ab'๋ฅผ ์ถ๊ฐํฉ๋๋ค:
vocab.append("ab")
๊ณ์ํ๋ ค๋ฉด 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:
merge = a + b[2:] if b.startswith("##") else a + b
split = split[:i] + [merge] + split[i + 2 :]
else:
i += 1
splits[word] = split
return splits
์ด์ ์ฒซ ๋ฒ์งธ ๋ณํฉ์ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ ์์ต๋๋ค:
splits = merge_pair("a", "##b", splits)
splits["about"]
์ด์ ์ํ๋ ๋ชจ๋ ๋ณํฉ์ ๋ชจ๋ ํ์ตํ ๋ ๊น์ง ๋ฐ๋ณตํ๋๋ฐ ํ์ํ ๋ชจ๋ ๊ฒ์ ๊ตฌํํ์ต๋๋ค. ๋ชฉํ vocabulary ํฌ๊ธฐ๋ฅผ 70์ผ๋ก ํฉ์๋ค:
vocab_size = 70
while len(vocab) < vocab_size:
scores = compute_pair_scores(splits)
best_pair, max_score = "", None
for pair, score in scores.items():
if max_score is None or max_score < score:
best_pair = pair
max_score = score
splits = merge_pair(*best_pair, splits)
new_token = (
best_pair[0] + best_pair[1][2:]
if best_pair[1].startswith("##")
else best_pair[0] + best_pair[1]
)
vocab.append(new_token)
์์ฑ๋ vocabulary๋ฅผ ๋ณผ ์ ์์ต๋๋ค:
print(vocab)
๋ณด์๋ค์ํผ BPE์ ๋นํด ์ด ํ ํฌ๋์ด์ ๋ ๋จ์ด์ ์ผ๋ถ๋ฅผ ํ ํฐ์ผ๋ก ๋ ๋นจ๋ฆฌ ํ์ตํฉ๋๋ค.
๐ก ๋์ผํ ๋ง๋ญ์น์์
train_new_from_iterator()
๋ฅผ ์ฌ์ฉํ๋ฉด ๋๊ฐ์ vocabulary๊ฐ ๋์ค์ง ์์ต๋๋ค. ๐คTokenizers ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํ์ต์ ์ํด WordPiece๋ฅผ ๊ตฌํํ์ง ์๊ณ (๋ด๋ถ์ ๋ํด ์์ ํ ํ์ ํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์) ๋์ BPE๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์๋ก์ด ํ ์คํธ๋ฅผ ํ ํฐํํ๊ธฐ ์ํด ์ฌ์ ํ ํฐํํ๊ณ (pre-tokenization), ๋ถํ ํ ๋ค์(split), ๊ฐ ๋จ์ด์ ํ ํฐํ ์๊ณ ๋ฆฌ์ฆ์ ์ ์ฉํฉ๋๋ค. ์ฆ, ์ฒซ๋ฒ์งธ ๋จ์ด์ ์์ ๋ถ๋ถ์์ ์์ํ๋ ๊ฐ์ฅ ํฐ ํ์ ๋จ์ด๋ฅผ ์ฐพ์ ๋ถํ ํ ๋ค์, ๋๋ฒ์งธ ๋ถ๋ถ์์ ํ๋ก์ธ์ค๋ฅผ ๋ฐ๋ณตํ๊ณ ๋๋จธ์ง ๋จ์ด์ ํ ์คํธ์ ๋ค์ ๋จ์ด์ ๋ํด ๊ณ์ ๋ฐ๋ณตํฉ๋๋ค:
def encode_word(word):
tokens = []
while len(word) > 0:
i = len(word)
while i > 0 and word[:i] not in vocab:
i -= 1
if i == 0:
return ["[UNK]"]
tokens.append(word[:i])
word = word[i:]
if len(word) > 0:
word = f"##{word}"
return tokens
Vocabulary์ ์กด์ฌํ๋ ๋จ์ด์ ๊ทธ๋ ์ง ์์ ๋จ์ด์ ๋ํด ํ ์คํธํด ๋ณด๊ฒ ์ต๋๋ค:
print(encode_word("Hugging"))
print(encode_word("HOgging"))
์ด์ ํ ์คํธ๋ฅผ ํ ํฐํํ๋ ํจ์๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค:
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]
encoded_words = [encode_word(word) for word in pre_tokenized_text]
return sum(encoded_words, [])
์ด์ ์ด๋ค ํ ์คํธ๋ฅผ ๊ฐ์ง๊ณ ๋ ํ ์คํธํด๋ณผ ์ ์์ต๋๋ค:
tokenize("This is the Hugging Face course!")
WordPiece ์๊ณ ๋ฆฌ์ฆ์ ๋ํ ์ค๋ช ์ ์ฌ๊ธฐ๊น์ง์ ๋๋ค! ์ด์ Unigram์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค.
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ([๐ค ๊ฐ์ข 6.7] WordPiece ํ ํฐํ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@spasis/๊ฐ์ข-6.7-WordPiece-ํ ํฐํ์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค