에듀테크 프로젝트 대시보드
BPE 토크나이저
언어 모델에 strawberry 를 넣으면 모델은 이 단어를 통째로 보지 않고
straw + berry 같은 조각으로 나눠서 본다.
이 조각을 토큰이라고 부른다. 왜 이렇게 할까?
deepfake, 근데말이야)를 아예 표현할 수 없다.
말뭉치(corpus)의 모든 단어를 글자 + 단어끝 기호 · 로 쪼갠 뒤,
가장 많이 인접해 등장한 심볼 쌍을 찾아 하나로 합친다. 이 과정을 원하는 횟수만큼 반복한다.
새 단어도 글자로 쪼갠 뒤, 위에서 배운 병합 규칙을 배운 순서대로 가능한 만큼 적용한다.
학습에 없던 단어(slowest)도 조각(s, low, est·)으로 표현된다.
# 1) 학습: 가장 잦은 인접 쌍을 num_merges 번 합친다 from collections import Counter def train_bpe(corpus, num_merges): # 단어 -> 빈도, 각 단어는 (글자..., '·') 튜플 words = Counter(tuple(w) + ('·',) for w in corpus.split()) merges = [] for _ in range(num_merges): pairs = Counter() for w, f in words.items(): for i in range(len(w) - 1): pairs[(w[i], w[i+1])] += f if not pairs: break best = max(pairs, key=pairs.get) # 최다 빈도 쌍 merges.append(best) words = Counter({_merge(w, best): f for w, f in words.items()}) return merges def _merge(word, pair): a, b, out, i = *pair, [], 0 while i < len(word): if i < len(word)-1 and (word[i], word[i+1]) == (a, b): out.append(a + b); i += 2 else: out.append(word[i]); i += 1 return tuple(out) # 2) 토큰화: 배운 순서대로 규칙을 적용 def encode(word, merges): sym = tuple(word) + ('·',) for pair in merges: sym = _merge(sym, pair) return sym
| 항목 | 내용 |
|---|---|
| 바이트 단위 BPE | 글자 대신 UTF-8 바이트(0~255)에서 시작 → 한글·이모지·어떤 문자든 "모르는 글자" 없이 표현 |
| 어휘 크기 | GPT-2 ≈ 50,257 · GPT-4 계열 ≈ 100,256개 토큰 |
| 공백 처리 | 단어 앞 공백을 토큰에 포함(" the") → 띄어쓰기 정보 보존 |
| 비슷한 방법 | WordPiece(BERT), Unigram/SentencePiece(T5, LLaMA) |
토큰이 글자 단위가 아니라서 생기는 유명한 한계: 모델은 strawberry 를
st·raw·berry 처럼 덩어리로 보기 때문에
"r이 몇 개야?" 같은 글자 세기를 자주 틀린다. 또 토큰 수로 요금을 매기므로
(영어 1토큰 ≈ 4글자, 한국어는 글자당 여러 토큰) 같은 뜻이라도 언어에 따라 비용이 다르다.
play + ing, un + happy 처럼 의미 단위에 가깝게 쪼개짐