본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 08. 09:01

Byte Pair Encoding (BPE) 직접 구현하며 이해하기

요약

LLM의 핵심 전처리 단계인 토큰화 기술 중 하나인 Byte Pair Encoding(BPE)의 원리와 구현 방법을 다룹니다. 단어 단위와 문자 단위 토큰화의 한계를 분석하고, 서브워드 단위로 문제를 해결하는 BPE의 메커니즘을 설명합니다.

핵심 포인트

  • 단어 단위 토큰화의 OOV 문제와 문자 단위의 긴 시퀀스 문제 해결
  • 빈번한 인접 문자 쌍을 병합하여 서브워드 토큰을 생성하는 원리
  • BPE를 통한 효율적인 어휘 사전 구축 및 트레이드오프 최적화

Byte Pair Encoding (BPE) 직접 구현하며 이해하기

서론: 토큰화 (Tokenization)가 존재하는 이유

GPT, LLaMA, 또는 Mistral과 같은 대규모 언어 모델 (LLMs)을 다룰 때, 가장 먼저 마주하는 숨겨진 단계 중 하나는 **토큰화 (tokenization)**입니다.

LLMs는 가공되지 않은 텍스트 (raw text)를 그대로 읽지 않습니다. 대신, 텍스트는 모델이 처리할 수 있는 수치적 표현인 **토큰 (tokens)**으로 먼저 변환되어야 합니다.

현대 자연어 처리 (NLP) 시스템에서 사용되는 가장 중요한 토큰화 기술 중 하나가 바로 **Byte Pair Encoding (BPE)**입니다.

이 글에서는 직관적인 이해부터 구현에 이르기까지 단계별로 분석하고, Python을 사용하여 BPE를 처음부터 직접 어떻게 구축했는지 보여드리겠습니다.

다음 내용을 다룹니다:

  • 토큰화가 필요한 이유
  • 단어 단위 (word-level) 및 문자 단위 (character-level) 토큰화가 실패하는 이유
  • BPE가 이러한 트레이드오프 (trade-off)를 해결하는 방법
  • BPE의 단계별 구현 방식
  • 학습 (training) 대 추론 (inference) 동작
  • 장점과 한계점

단어 단위 토큰화 (Word-Level Tokenization)의 문제점

가장 단순한 접근 방식은 텍스트를 단어별로 나누는 것입니다:

I love machine learning

다음과 같이 변환됩니다:

["I", "love", "machine", "learning"]

이 방식은 합리적으로 보이지만, 한 가지 큰 문제점을 깨닫기 전까지만 그렇습니다.

모델이 다음과 같은 단어를 보게 되면 어떻게 될까요?

machinelearning

또는:

hyperlearning

만약 이 단어들이 학습 데이터 (training data)에 없었다면, 이들은 어휘 사전 외 (Out-Of-Vocabulary, OOV) 토큰이 됩니다.

이는 심각한 한계점입니다. 언어는 끊임없이 진화하며, 우리는 가능한 모든 단어를 저장할 수 없기 때문입니다.

문자 단위 토큰화 (Character-Level Tokenization)의 문제점

OOV 문제를 해결하기 위해 모든 것을 문자로 나눌 수도 있습니다:

learning

다음과 같이 변환됩니다:

["l", "e", "a", "r", "n", "i", "n", "g"]

이 방식은 OOV 문제를 완전히 제거합니다.

하지만 새로운 문제들을 야기합니다:

  • 시퀀스 (sequences)가 매우 길어짐
  • 학습 (training)이 비효율적으로 변함
  • 모델이 의미 있는 단어 구조를 잃어버림

따라서 우리는 다음과 같은 트레이드오프 (trade-off)를 마주하게 됩니다:

접근 방식문제점
단어 단위 (Word-level)OOV 문제
문자 단위 (Character-level)너무 긴 시퀀스

우리는 그 중간 단계의 무언가가 필요합니다.

Byte Pair Encoding (BPE)의 핵심 아이디어

BPE는 **텍스트 내의 공통 패턴 (common patterns in text)**을 학습함으로써 이 문제를 해결합니다.

단어(words)나 문자(characters)를 선택하는 대신, **서브워드 단위 (subword units)**를 구축합니다.

아이디어는 간단합니다:

  1. 문자로 시작합니다.
  2. 가장 빈번하게 나타나는 인접 쌍 (adjacent pair)을 찾습니다.
  3. 이를 새로운 토큰 (token)으로 병합 (merge)합니다.
  4. 반복합니다.

시간이 흐름에 따라 빈번한 패턴들은 하나의 토큰이 됩니다.

예시를 통한 직관적 이해

주어진 데이터:

l o w
l o w e r
l o w e s t

BPE는 빈도 패턴에 따라 다음과 같은 것들을 학습할 수 있습니다:

lo
low
lowe

1단계: 어휘 사전 (Vocabulary) 구축

단어 빈도수부터 시작합니다:

{
    "low": 1,
    "lower": 1,
...

그 다음 각 단어를 문자로 변환하고 단어 끝 표시자 (end-of-word marker)를 추가합니다:

{
    ('l', 'o', 'w', '</w>'): 1,
    ('l', 'o', 'w', 'e', 'r', '</w>'): 1,
...

</w> 표시자는 단어 경계 (word boundaries)를 구분하는 데 도움을 줍니다.

2단계: 인접 쌍 (Adjacent Pairs) 계산

모든 단어를 스캔하여 인접한 심볼 쌍 (symbol pairs)의 개수를 셉니다.

예를 들어:

l o w </w>

다음과 같은 결과를 생성합니다:

(l, o)
(o, w)
(w, </w>)

각 쌍은 단어 빈도수에 가중치를 두어 (weighted by word frequency) 계산됩니다.

이를 통해 코퍼스 (corpus) 내의 모든 쌍에 대한 전역 빈도 테이블 (global frequency table)을 얻을 수 있습니다.

3단계: 가장 빈번한 쌍 선택

가장 빈번하게 나타나는 인접 쌍을 선택합니다:

('l', 'o')

이것은 다음과 같은 병합 규칙 (merge rule)이 됩니다:

(l, o) → lo

4단계: 전체 어휘 사전에 걸쳐 병합 적용

다음의 모든 출현 사례를 교체합니다:

l o

다음으로:

lo

따라서:

('l','o','w','</w>')

다음이 됩니다:

('lo','w','</w>')

5단계: 프로세스 반복

쌍의 빈도를 다시 계산하고 병합을 계속합니다:

(l,o) → lo
(lo,w) → low
(low,e) → lowe

각 반복 (iteration)은 더 단순한 것들로부터 더 복잡한 토큰들을 구축합니다.

학습 (Training) vs 토큰화 (Tokenization) (핵심 개념)

이 부분이 많은 사람들이 혼란스러워하는 지점입니다.

학습 단계 (During Training)

BPE는:

  • 쌍의 빈도를 계산합니다.
  • 병합 규칙을 학습합니다.
  • 어휘 사전 (vocabulary)을 구축합니다.

예시:

(l,o) → lo
(lo,w) → low

토큰화 단계 (During Tokenization / Inference)

토크나이저 (tokenizer)는:

  • 아무것도 학습하지 않습니다.
  • 빈도를 계산하지 않습니다.
  • 오직 학습된 병합 규칙을 적용하기만 합니다.

예시:

입력:

lowly

시작:

l o w l y

병합 적용:

(l,o) → lo
(lo,w) → low

결과:

low l y

여기서는 학습이 일어나지 않으며, 오직 규칙 적용만 이루어집니다.

BPE가 매우 효과적인 이유

1. OOV (Out-of-Vocabulary) 문제 해결

보지 못한 단어라도 다음과 같이 표현할 수 있습니다:

playfulness → play + ful + ness

2. 더 작은 어휘 사전 (Vocabulary)

전체 단어를 저장하는 대신:

play
playing
player
...

우리는 다음을 재사용합니다:

play
ing
er

3. 더 나은 일반화 (Generalization)

공통된 어근을 가진 단어들은 토큰을 재사용합니다:

play
playing
player

이를 통해 모델은 연관된 단어들 사이에서 의미를 공유할 수 있습니다.

BPE의 한계

강력한 성능에도 불구하고, BPE에는 다음과 같은 한계가 있습니다:

  • 학습 코퍼스 (Training Corpus)에 민감함
  • 탐욕적 병합 전략 (Greedy Merging Strategy)
  • 다국어 균형 측면에서 취약함
  • 언어를 "이해"하는 것이 아니라, 오직 빈도 패턴만을 학습함

이러한 이유로 현대의 LLM (Large Language Models)은 주로 다음을 사용합니다:

  • Byte-level BPE (GPT 스타일의 토크나이저)
  • WordPiece (BERT)
  • SentencePiece Unigram (LLaMA, T5)

나의 Python 구현 (From Scratch)

아래는 간소화된 나의 BPE 구현체입니다:

import sys

def main(av: list[str]) -> int:
...

이 구현체는 다음을 수행합니다:

  • 어휘 사전 (Vocabulary) 구축
  • 쌍 빈도 (Pair Frequencies) 계산
  • 병합 규칙 (Merge Rules) 학습
  • 반복적인 토큰 업데이트

핵심 통찰 (Key Insight)

BPE는 놀라울 정도로 단순합니다:

그것은 언어를 이해하는 것이 아니라, 어떤 문자 쌍이 가장 빈번하게 함께 나타나는지를 학습할 뿐입니다.

그럼에도 불구하고 이 단순한 아이디어는 모든 현대 LLM에서 사용될 만큼 강력합니다.

결론

Byte Pair Encoding은 현대 NLP (Natural Language Processing) 시스템의 핵심에 자리 잡고 있습니다.

BPE는 다음 사이의 균형을 제공합니다:

  • 단어 단위 토큰화 (Word-level tokenization, 너무 경직됨)
  • 문자 단위 토큰화 (Character-level tokenization, 너무 김)

빈번한 서브워드 (Subword) 패턴을 학습함으로써, BPE는 모델이 흔히 쓰이는 단어와 보지 못한 단어 모두를 효율적으로 표현할 수 있게 해줍니다.

BPE를 이해하는 것은 LLM이 실제로 언어를 어떻게 처리하는지 이해하기 위한 가장 좋은 입문 경로 중 하나입니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0