한양과학기술고등학교

에듀테크 프로젝트 대시보드

BPE 토크나이저

BPE 토크나이저 (Byte Pair Encoding)

ChatGPT 같은 언어 모델은 글자도, 단어도 아닌 토큰(subword) 단위로 글을 읽는다 — 그 토큰을 만드는 대표 알고리즘

언어 모델에 strawberry 를 넣으면 모델은 이 단어를 통째로 보지 않고 straw + berry 같은 조각으로 나눠서 본다. 이 조각을 토큰이라고 부른다. 왜 이렇게 할까?

  • 글자 단위는 너무 잘게 쪼개져서 문장이 길어지고 의미 학습이 어렵다.
  • 단어 단위는 사전에 없는 신조어·오타·합성어(deepfake, 근데말이야)를 아예 표현할 수 없다.
  • BPE는 그 중간 — 자주 붙어 다니는 글자쌍을 계속 합쳐서, 흔한 단어는 토큰 1개로, 희귀한 단어는 몇 조각으로 표현한다.

1. 학습(training) — 자주 나오는 쌍을 계속 합치기

말뭉치(corpus)의 모든 단어를 글자 + 단어끝 기호 · 로 쪼갠 뒤, 가장 많이 인접해 등장한 심볼 쌍을 찾아 하나로 합친다. 이 과정을 원하는 횟수만큼 반복한다.

현재 단어 상태 — 심볼들이 어떻게 합쳐지는지 보세요

인접 쌍 빈도 (상위 8개) — 노란 막대가 이번에 합쳐질 쌍

병합 규칙 (merge 순서 = 적용 순서)

    어휘(vocab)

    2. 토큰화(encoding) — 배운 규칙을 새 문장에 적용

    새 단어도 글자로 쪼갠 뒤, 위에서 배운 병합 규칙을 배운 순서대로 가능한 만큼 적용한다. 학습에 없던 단어(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

    실제 GPT는 어떻게?

    항목내용
    바이트 단위 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글자, 한국어는 글자당 여러 토큰) 같은 뜻이라도 언어에 따라 비용이 다르다.

    왜 중요할까