[NLP] Tokenizer

JAsmine_log·2025년 11월 20일

Tokenizer

BPE, WordPiece, Unigram(=SentencePiece Unigram) 세 가지 토크나이저를 같은 코퍼스, 같은 문장으로 비교

Python 예제

  • BPE vs WordPiece vs Unigram 비교
from tokenizers import Tokenizer, models, trainers, pre_tokenizers

# --------------------------
# 1. 샘플 코퍼스 준비
# --------------------------
corpus = [
    "Machine learning is fascinating.",
    "Deep learning models improve with data.",
    "Large language models are powerful.",
    "Tokenization affects model performance."
]

# ==========================
# 2. BPE Tokenizer
# ==========================
bpe_tokenizer = Tokenizer(models.BPE())
bpe_tokenizer.pre_tokenizer = pre_tokenizers.Whitespace()

bpe_trainer = trainers.BpeTrainer(
    vocab_size=60,
    special_tokens=["[PAD]", "[UNK]", "[CLS]", "[SEP]"]
)
bpe_tokenizer.train_from_iterator(corpus, bpe_trainer)

# ==========================
# 3. WordPiece Tokenizer
# ==========================
wp_tokenizer = Tokenizer(models.WordPiece(unk_token="[UNK]"))
wp_tokenizer.pre_tokenizer = pre_tokenizers.Whitespace()

wp_trainer = trainers.WordPieceTrainer(
    vocab_size=60,
    special_tokens=["[PAD]", "[UNK]", "[CLS]", "[SEP]"]
)
wp_tokenizer.train_from_iterator(corpus, wp_trainer)

# ==========================
# 4. Unigram Tokenizer (SentencePiece Unigram)
# ==========================
uni_tokenizer = Tokenizer(models.Unigram())
uni_tokenizer.pre_tokenizer = pre_tokenizers.Whitespace()

uni_trainer = trainers.UnigramTrainer(
    vocab_size=60,
    special_tokens=["[PAD]", "[UNK]", "[CLS]", "[SEP]"]
)
uni_tokenizer.train_from_iterator(corpus, uni_trainer)

# --------------------------
# 5. 비교 문장
# --------------------------
text = "Tokenization improves language models"

print("=== BPE ===")
print(bpe_tokenizer.encode(text).tokens)

print("\n=== WordPiece ===")
print(wp_tokenizer.encode(text).tokens)

print("\n=== Unigram ===")
print(uni_tokenizer.encode(text).tokens)

결과

=== BPE ===
['To', 'k', 'en', 'i', 'z', 'at', 'i', 'o', 'n', 'i', 'm', 'p', 'r', 'o', 'v', 'e', 's', 'l', 'an', 'g', 'u', 'age', 'models']

=== WordPiece ===
['T', '##o', '##k', '##e', '##n', '##i', '##z', '##at', '##i', '##o', '##n', 'i', '##m', '##p', '##r', '##o', '##v', '##e', '##s', 'l', '##a', '##n', '##g', '##u', '##a', '##g', '##e', 'model', '##s']

=== Unigram ===
['T', 'o', 'k', 'e', 'ni', 'z', 'ati', 'o', 'n', 'i', 'm', 'p', 'r', 'o', 'v', 'e', 's', 'l', 'a', 'ng', 'u', 'a', 'g', 'e', 'model', 's']

세 방식 비교표

핵심 비교 요약

항목BPEWordPieceUnigram (SentencePiece)
학습 방식자주 등장하는 byte pair 병합확률 기반 최대 우도 서브워드 조합전체 단어 분해 후보 세트를 만들고 확률적으로 최적화
서브워드 분해 특징직관적, 병합 기반'##' 접두사로 subword 표시가장 가능성 높은 조합 선택 (probabilistic)
OOV 처리잘 처리함잘 처리함가장 강함 (여러 분해 후보 중 선택)
장점빠르고 직관적안정적, BERT류에서 사용소형 vocab으로도 강력, 다양한 분해 가능
단점일부 비직관적 분해 발생deterministic이라 변화 적음학습 난이도 약간 높음
대표 모델GPT 계열BERT, RoBERTaSentencePiece(알파벳/한글 다 지원), T5

Tokenization 비교

BPE

자주 등장하는 쌍을 계속 합쳐 나감

Token | ization | im | prove | s | language | models

WordPiece

접두사 ##로 “중간 조각” 표시

Token | ##ization | im | ##proves | language | models

Unigram

여러 후보 중 가장 확률 높은 조합을 선택

Token | ization | impro | ves | language | models

Tokenizer 결과 요약

1) BPE 결과

['To', 'k', 'en', 'i', 'z', 'at', ...]

자주 등장하는 문자 쌍만 병합됨
✔ 코퍼스가 너무 작아서 대부분 문자 단위 토큰
✔ 단어 내부에서 빈번한 조합만 조금씩 합쳐짐
→ BPE의 본질: 통계적으로 자주 나오는 조합부터 합친다


2) WordPiece 결과

['T', '##o', '##k', '##e', '##n', ...]

✔ 대부분 문자 단위
✔ WordPiece는 “OOV를 피하도록” 가장 작은 단위로 나누는 경향
✔ 뒤에 붙은 ##이전 토큰의 연속(subword)
→ WordPiece의 본질: 안정적이고 규칙적인 분해, 항상 단어 시작/중간 구분 유지


3) Unigram 결과 의미

['T', 'o', 'k', 'e', 'ni', 'z', 'ati', ...]

확률 기반 선택 모델 → 가장 가능성이 높은 subword 선택
✔ 그래서 문자 단위 + 2~3글자 subword가 섞여 있음
✔ 다양한 분해 후보 중 “전체 문장의 우도를 최대로 만드는 조합” 선택
→ Unigram의 본질: 확률적으로 가장 자연스러운 분해 선택 (가장 flexible)


요약

  • BPE는 자주 나오는 조합을 합치고,
  • WordPiece는 규칙적으로 글자를 잘게 나누고,
  • Unigram은 확률적으로 가장 자연스러운 subword를 선택한다.
profile
Everyday Research & Development

0개의 댓글