🤖 AI/ML

Tokenizer

토크나이저

텍스트를 토큰(token)으로 분할하는 NLP 전처리 도구입니다. BPE, WordPiece, SentencePiece 등 다양한 알고리즘을 사용하여 텍스트를 모델이 처리할 수 있는 숫자 ID 시퀀스로 변환합니다.

📖 상세 설명

토크나이저(Tokenizer)는 자연어 처리(NLP)의 첫 번째 단계로, 원시 텍스트를 모델이 이해할 수 있는 형태로 변환합니다. 텍스트 -> 토큰 -> 토큰 ID의 과정을 거치며, 모델 출력 시에는 역으로 토큰 ID -> 토큰 -> 텍스트로 디코딩합니다. 각 언어 모델은 학습 시 사용한 특정 토크나이저에 종속되어 있습니다.

현대 NLP에서 가장 널리 사용되는 토큰화 알고리즘은 서브워드(subword) 기반입니다. BPE(Byte Pair Encoding)는 가장 빈번한 문자 쌍을 반복적으로 병합하여 어휘를 구축합니다. GPT 계열이 이를 사용합니다. WordPiece는 BERT에서 사용하며, BPE와 유사하지만 가능도(likelihood) 기반으로 병합을 결정합니다. Unigram은 큰 어휘에서 시작해 확률이 낮은 토큰을 제거하는 방식입니다.

SentencePiece는 Google이 개발한 언어 독립적 토크나이저로, 공백을 특수 문자(_)로 치환하여 처리합니다. 이를 통해 일본어, 중국어처럼 공백이 없는 언어도 일관되게 처리할 수 있습니다. LLaMA, T5 등 많은 현대 모델이 SentencePiece를 채택하고 있습니다. 특히 다국어 모델에서 효과적입니다.

토크나이저 선택은 모델 성능에 직접적인 영향을 미칩니다. 어휘 크기(vocabulary size)가 크면 OOV(Out of Vocabulary) 문제가 줄지만 모델 크기가 증가합니다. 반대로 어휘가 작으면 같은 텍스트도 더 많은 토큰으로 분할됩니다. 최근에는 tiktoken(OpenAI), Hugging Face tokenizers 라이브러리가 빠른 토큰화를 제공하며, 특히 Rust로 구현된 tokenizers는 기존 Python 구현 대비 수십 배 빠릅니다.

💻 코드 예제

다양한 토크나이저 알고리즘과 사용법을 보여주는 예제입니다.

from transformers import AutoTokenizer
import tiktoken

# =============================================
# 1. Hugging Face AutoTokenizer (다양한 모델 지원)
# =============================================

# GPT-2 토크나이저 (BPE)
tokenizer_gpt2 = AutoTokenizer.from_pretrained("gpt2")

# BERT 토크나이저 (WordPiece)
tokenizer_bert = AutoTokenizer.from_pretrained("bert-base-uncased")

# LLaMA 토크나이저 (SentencePiece)
tokenizer_llama = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-hf")

text = "Hello, how are you doing today?"
text_ko = "안녕하세요, 오늘 기분이 어떠세요?"

# 토크나이저 비교
print("=== 영어 텍스트 토큰화 비교 ===")
for name, tok in [("GPT-2", tokenizer_gpt2), ("BERT", tokenizer_bert)]:
    tokens = tok.tokenize(text)
    ids = tok.encode(text)
    print(f"{name}: {len(tokens)} 토큰")
    print(f"  토큰: {tokens}")
    print(f"  ID: {ids}")
    print()


# =============================================
# 2. tiktoken (OpenAI 모델용 - 매우 빠름)
# =============================================

# GPT-4용 토크나이저
enc = tiktoken.encoding_for_model("gpt-4")

# 또는 인코딩 직접 지정
enc_cl100k = tiktoken.get_encoding("cl100k_base")  # GPT-4, ChatGPT

# 토큰화
tokens = enc.encode(text_ko)
print(f"tiktoken (GPT-4): {len(tokens)} 토큰")
print(f"  토큰 ID: {tokens}")
print(f"  디코딩: {enc.decode(tokens)}")

# 개별 토큰 확인
print("  개별 토큰:")
for token_id in tokens:
    token_bytes = enc.decode_single_token_bytes(token_id)
    print(f"    {token_id} → {token_bytes}")


# =============================================
# 3. 커스텀 토크나이저 학습 (Hugging Face tokenizers)
# =============================================
from tokenizers import Tokenizer, models, trainers, pre_tokenizers

# BPE 토크나이저 생성
tokenizer = Tokenizer(models.BPE(unk_token="[UNK]"))
tokenizer.pre_tokenizer = pre_tokenizers.Whitespace()

# 학습 데이터 (실제로는 대용량 코퍼스 사용)
training_data = [
    "인공지능은 미래를 바꿀 것입니다.",
    "머신러닝과 딥러닝은 인공지능의 핵심 기술입니다.",
    "자연어 처리는 텍스트를 이해하는 기술입니다.",
]

# 임시 파일에 저장
with open("train_data.txt", "w", encoding="utf-8") as f:
    f.write("\n".join(training_data))

# 토크나이저 학습
trainer = trainers.BpeTrainer(
    vocab_size=1000,
    special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"]
)
tokenizer.train(["train_data.txt"], trainer)

# 학습된 토크나이저 테스트
output = tokenizer.encode("인공지능 기술")
print(f"커스텀 토크나이저: {output.tokens}")


# =============================================
# 4. 특수 토큰 처리
# =============================================
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")

# 특수 토큰 확인
print(f"[CLS] ID: {tokenizer.cls_token_id}")
print(f"[SEP] ID: {tokenizer.sep_token_id}")
print(f"[PAD] ID: {tokenizer.pad_token_id}")
print(f"[MASK] ID: {tokenizer.mask_token_id}")

# 문장 쌍 토큰화 (BERT 스타일)
encoded = tokenizer(
    "첫 번째 문장입니다.",
    "두 번째 문장입니다.",
    padding="max_length",
    max_length=32,
    truncation=True,
    return_tensors="pt"
)

print(f"input_ids: {encoded['input_ids']}")
print(f"attention_mask: {encoded['attention_mask']}")
print(f"token_type_ids: {encoded['token_type_ids']}")

🗣️ 실무에서 이렇게 말하세요

"이 모델은 센텐스피스 토크나이저 써서 한국어 효율이 좀 더 좋아요"

→ SentencePiece 기반 토크나이저가 다국어에 유리함을 설명

"토크나이저 vocab size가 32k라서 OOV 이슈는 거의 없을 거예요"

→ 어휘 크기가 충분히 커서 미등록 단어(OOV) 문제가 적음을 설명

"tiktoken 쓰면 토큰 카운트 속도가 엄청 빨라요"

→ Rust 기반 tiktoken 라이브러리의 성능 장점 언급

⚠️ 흔한 실수 & 주의사항

모델과 토크나이저 불일치

모델과 다른 토크나이저를 사용하면 결과가 엉망이 됩니다. 반드시 모델과 함께 학습된 토크나이저를 사용하세요.

패딩 방향 실수

GPT 계열은 왼쪽 패딩, BERT 계열은 오른쪽 패딩을 사용합니다. 잘못된 패딩 방향은 성능 저하를 유발합니다.

특수 토큰 누락

BERT는 [CLS], [SEP] 토큰이 필수입니다. 특수 토큰 없이 직접 encode()하면 모델 성능이 크게 떨어집니다.

긴 텍스트 잘림(Truncation)

max_length 초과 시 텍스트가 잘립니다. 중요한 정보가 뒷부분에 있으면 손실될 수 있으니 truncation 전략을 신중히 선택하세요.

🔗 관련 용어

📚 더 배우기