검색
← 모듈 로드맵

토큰과 토크나이저: 글자가 숫자가 되기까지

강의 · 입문자 · KAITABASE 정리

원제 · Tokenizers (Hugging Face LLM Course 참고)

글을 토큰 id로 바꾸는 세 방식과 BPE 병합을 손으로 학습해 보는 기초 수업

먼저 알아야 할 것

데이터를 숫자로 바꾸는 개념빈도 세기표 읽기

다루는 내용

언어 모델이 읽는 단위인 토큰과 토크나이저를 다룹니다. 단어 · 문자 · 서브워드 토큰화를 비교하고, 작은 말뭉치로 BPE 병합 규칙을 직접 학습 · 적용해 봅니다. 바이트 수준 BPE · WordPiece · Unigram, 특수 토큰, 토큰 수와 비용 · 문맥 길이의 관계까지 정리합니다.

해설

토큰과 토크나이저: 글자가 숫자가 되기까지

언어 모델은 글자를 직접 읽지 못하고 토큰(token) 이라는 조각의 번호만 읽습니다. 이 수업에서는 글을 토큰으로 자르는 세 가지 방식과, 오늘날 LLM이 쓰는 BPE(바이트 쌍 인코딩) 를 작은 말뭉치로 직접 손으로 학습해 봅니다.

항목내용
참고 출처Hugging Face LLM Course 2장 「Tokenizers」 · 6장 「Byte-Pair Encoding tokenization」 (chapter2/4, chapter6/5)
트랙 · 수준NLP·트랜스포머 · 기초
이 수업이 다루는 범위단어 · 문자 · 서브워드 토큰화, 어휘와 토큰 id, BPE 학습과 적용 손계산, WordPiece · Unigram 개요, 특수 토큰, 토큰 수와 비용 · 문맥 길이

들어가기 전에

  • 구글 머신러닝 단기 집중 과정 — "데이터를 숫자로 바꿔야 모델이 배운다"는 감각이 있으면 충분합니다. 이 수업은 그 '숫자로 바꾸기'의 글 버전입니다.
  • 수식은 거의 없습니다. 세기(빈도 세기)와 표 읽기만 할 줄 알면 됩니다.

한눈에 보기

  • 단어 단위 · 문자 단위 · 서브워드 단위 토큰화가 각각 무엇을 얻고 잃는지 비교할 수 있습니다.
  • 토크나이저가 하는 일 두 단계(자르기 → 번호 매기기)와 되돌리기(디코딩)를 설명할 수 있습니다.
  • BPE가 "가장 자주 붙어 나오는 쌍을 합친다"는 규칙 하나로 어휘를 만드는 과정을 손으로 따라 합니다.
  • [UNK] · [CLS] 같은 특수 토큰과, 바이트 수준 BPE가 왜 [UNK]를 없애는지 압니다.
  • 한국어 글의 토큰 수가 비용과 문맥 길이에 어떤 영향을 주는지 압니다.

1. 왜 토큰이 필요한가

직관(해설용 비유). 도서관 사서가 책을 '번호'로 관리하듯, 모델은 글 조각을 번호로 관리합니다. 모델 안의 계산은 전부 숫자 행렬 곱이라서, 글자 그대로는 넣을 수가 없습니다.

단계.

  1. 글을 정해진 규칙으로 조각(토큰)으로 자릅니다.
  2. 각 조각을 어휘(vocabulary) 표에서 찾아 정수 번호(토큰 id)로 바꿉니다.
  3. 모델은 이 번호를 받아 임베딩 벡터로 바꿔 계산합니다(→ 임베딩 수업).
  4. 모델이 내놓은 번호를 다시 글로 바꾸는 것이 디코딩(decoding)입니다.

Hugging Face 강좌는 이 과정을 토큰화(tokenize) 와 입력 id로 변환(convert_tokens_to_ids) 의 두 단계로 설명하고, 반대 방향은 decode() 로 합니다.

글→ 자르기 (t1,t2,…,tn)→ 어휘 조회 (id(t1),…,id(tn))\text{글} \xrightarrow{\ \text{자르기}\ } (t_1, t_2, \dots, t_n) \xrightarrow{\ \text{어휘 조회}\ } (\mathrm{id}(t_1), \dots, \mathrm{id}(t_n))
기호뜻
tit_iii번째 토큰(글 조각)
nn토큰 개수 — 모델이 실제로 처리하는 길이
id(⋅)\mathrm{id}(\cdot)어휘 표에서 토큰의 번호를 찾는 함수

숫자로 해 보기(해설용, 가상의 어휘). 어휘가 {[UNK]:0, 나는:1, 커피:2, 를:3, 마신다:4} 라고 합시다. "나는 커피를 마신다"를 나는 / 커피 / 를 / 마신다 로 자르면 id는 [1, 2, 3, 4] 입니다. "나는 녹차를 마신다"는 녹차가 어휘에 없으므로 [1, 0, 3, 4] 가 되어, 모델은 "무언가를 마신다"는 정보밖에 받지 못합니다. 모르는 조각이 많을수록 정보가 사라집니다.

2. 세 가지 자르는 방식

방식예: "tokenization"장점단점
단어 단위(word-based)tokenization 한 덩어리조각 하나에 뜻이 많이 담김어휘가 매우 커지고, "dog" · "dogs"처럼 비슷한 형태를 남남으로 취급, 없는 단어는 [UNK]
문자 단위(character-based)t o k e n … 열두 조각어휘가 작고 [UNK]가 거의 없음조각 하나의 뜻이 적고 길이가 크게 늘어남
서브워드(subword)token + ization자주 쓰는 단어는 통째로, 드문 단어는 뜻 있는 조각으로자르는 규칙을 학습해야 함

강좌는 영어 단어만 해도 50만 개가 넘는다는 점을 들어 단어 단위의 어휘 폭발을 설명하고, 서브워드 예로 "tokenization" → "token" + "ization" 을 듭니다. 또 서브워드가 터키어처럼 조각을 이어 붙여 단어를 만드는 언어(교착어)에 잘 맞는다고 말합니다. 한국어도 '먹 + 었 + 습니다'처럼 붙여 쓰는 교착어라 같은 이유로 서브워드가 유리합니다.

왜 서브워드가 표준이 되었나. 단어 단위는 어휘가 너무 크고 모르는 단어에 약합니다. 문자 단위는 길이가 너무 깁니다. 어텐션 계산량은 길이의 제곱으로 늘기 때문에(→ 어텐션 직관) 길이는 곧 비용입니다. 서브워드는 이 둘 사이의 타협입니다.

3. BPE를 손으로 학습해 보기

직관(해설용 비유). 자주 같이 다니는 두 친구를 한 팀으로 묶어 이름표 하나를 주는 일을 계속 되풀이하는 것입니다. 자주 묶일수록 큰 팀(긴 토큰)이 됩니다.

단계(강좌가 설명하는 BPE 학습 절차).

  1. 말뭉치의 단어와 빈도를 셉니다(정규화 · 사전 토큰화 뒤).
  2. 단어에 쓰인 모든 문자를 기본 어휘로 둡니다.
  3. 모든 단어에서 붙어 있는 토큰 쌍의 빈도를 (단어 빈도로 가중해) 셉니다.
  4. 가장 많은 쌍을 하나의 새 토큰으로 병합(merge) 하고, 병합 규칙을 순서대로 기록합니다.
  5. 원하는 어휘 크기가 될 때까지 3~4를 되풀이합니다.
(a∗,b∗)=arg⁡max⁡(a,b)∑w∈말뭉치f(w)⋅cw(a,b)(a^*, b^*) = \arg\max_{(a,b)} \sum_{w \in \text{말뭉치}} f(w)\cdot c_w(a,b)
기호뜻
ww말뭉치의 단어 하나
f(w)f(w)그 단어가 나온 횟수
cw(a,b)c_w(a,b)단어 ww 안에서 토큰 aa 바로 뒤에 bb 가 붙어 나오는 횟수
(a∗,b∗)(a^*, b^*)이번에 합칠 쌍

숫자로 해 보기(해설용, 직접 만든 말뭉치). 단어 빈도가 cat 8, cats 3, hat 6, chat 2 라고 합시다. 기본 어휘는 {a, c, h, s, t} 입니다.

1회차. 쌍 빈도를 셉니다.

  • a t: cat 8 + cats 3 + hat 6 + chat 2 = 19
  • c a: cat 8 + cats 3 = 11
  • h a: hat 6 + chat 2 = 8
  • t s: 3, c h: 2

가장 많은 a t 를 합쳐 at 를 만듭니다. 단어는 c at, c at s, h at, c h at 이 됩니다.

2회차. c at: 8 + 3 = 11, h at: 6 + 2 = 8, at s: 3, c h: 2 → cat 을 만듭니다.

3회차. h at: 6 + 2 = 8, cat s: 3, c h: 2 → hat 을 만듭니다.

병합 규칙은 순서대로 ① a t → at ② c at → cat ③ h at → hat 입니다. 어휘는 {a, c, h, s, t, at, cat, hat} 여덟 개가 됩니다.

새 단어에 적용하기. 새 글은 문자로 쪼갠 뒤 학습한 병합을 같은 순서로 적용합니다.

  • chats → c h a t s → ① c h at s → ② 해당 없음(c at 쌍이 없음) → ③ c hat s → 결과 [c, hat, s]
  • mat → m a t → ① m at → m 은 기본 어휘에 없으므로 [[UNK], at]

강좌의 예제도 같은 원리로, 기본 어휘에 없는 문자가 [UNK] 가 되는 모습을 보여 줍니다.

왜 이렇게 하나. 빈도만 세면 되므로 학습이 단순하고 빠릅니다. 자주 나오는 단어는 결국 한 토큰이 되고, 드문 단어는 아는 조각으로 쪼개져 완전히 모르는 단어가 거의 없어집니다. BPE의 원래 용도는 압축이었고, 이를 번역에 가져온 논문이 서브워드 단위로 드문 단어 번역하기 (BPE 토큰화) 입니다.

4. 바이트 수준 BPE, WordPiece, Unigram

  • 바이트 수준 BPE(byte-level BPE). 문자 대신 바이트(0~255)를 기본 어휘로 씁니다. 강좌에 따르면 GPT-2 · RoBERTa가 이 방식이며, 기본 어휘가 256개로 작아도 어떤 문자든 표현할 수 있어 [UNK] 가 생기지 않습니다. 예를 들어 한글 음절 하나는 UTF-8에서 3바이트이므로, 병합이 학습되지 않은 드문 글자도 바이트 3개로는 반드시 표현됩니다.
  • WordPiece. BERT가 씁니다. 단어 안에서 이어지는 조각 앞에 ## 를 붙입니다(예: ##er). 병합할 쌍을 고를 때 단순 빈도 대신 "두 조각이 각각 나오는 빈도에 비해 함께 나오는 빈도"를 봅니다.
  • Unigram · SentencePiece. 큰 후보 어휘에서 시작해, 빼도 전체 확률이 덜 나빠지는 조각부터 지워 나가는 방식입니다. 여러 다국어 모델이 씁니다. SentencePiece는 공백도 하나의 기호로 다뤄 띄어쓰기 규칙이 다른 언어에도 그대로 씁니다.
mermaid
flowchart LR
  A[원문 글] --> B[정규화<br/>소문자 · 유니코드 정리]
  B --> C[사전 토큰화<br/>공백 · 구두점 기준]
  C --> D[서브워드 모델<br/>BPE · WordPiece · Unigram]
  D --> E[특수 토큰 추가]
  E --> F[토큰 id 목록]
  F --> G[모델]
  G --> H[출력 id]
  H --> I[decode로 글 복원]

5. 특수 토큰과 부가 입력

  • [UNK] / <unk>: 어휘에 없는 조각. 자주 나오면 정보가 사라지고 있다는 신호입니다.
  • 문장 시작 · 끝 · 구분 표시: BERT 계열은 [CLS] · [SEP] 를 앞뒤에 붙입니다. 강좌의 BERT 예시 출력에서 맨 앞과 끝에 붙는 id가 이것입니다.
  • 패딩(padding) 토큰: 길이가 다른 문장을 한 묶음으로 처리하려고 짧은 쪽을 채우는 토큰입니다.
  • 토크나이저를 직접 부르면 input_ids 와 함께 attention_mask(패딩이 아닌 위치는 1) 등이 나옵니다. 모델은 마스크가 0인 자리를 보지 않습니다.

왜 중요한가. 모델은 학습 때 본 토크나이저 규칙과 특수 토큰을 그대로 기대합니다. 그래서 강좌는 모델과 같은 체크포인트 이름으로 토크나이저를 불러오라고(AutoTokenizer.from_pretrained) 안내합니다. 다른 토크나이저를 쓰면 번호의 뜻이 어긋나 결과가 엉망이 됩니다.

6. 토큰 수 = 비용 · 문맥 길이

LLM API 요금과 문맥 창(context window) 한도는 대부분 글자 수가 아니라 토큰 수로 정해집니다.

비용≈입력 토큰 수106×pin+출력 토큰 수106×pout\text{비용} \approx \frac{\text{입력 토큰 수}}{10^6}\times p_{\text{in}} + \frac{\text{출력 토큰 수}}{10^6}\times p_{\text{out}}
기호뜻
pin, poutp_{\text{in}},\ p_{\text{out}}100만 토큰당 입력 · 출력 단가(서비스마다 다름)

숫자로 해 보기(해설용, 가상의 단가). 입력 단가가 100만 토큰당 3달러, 출력 단가가 15달러라고 합시다. 입력 2,000토큰 · 출력 500토큰 요청 한 번은 0.002×3+0.0005×15=0.006+0.0075=0.01350.002\times3 + 0.0005\times15 = 0.006 + 0.0075 = 0.0135 달러입니다. 하루 1만 번이면 135달러입니다.

한국어에서 주의할 점. 토크나이저의 어휘는 학습 말뭉치에 많이 나온 조각 위주로 만들어집니다. 학습 데이터에 한국어가 적은 토크나이저일수록 한국어 단어가 짧은 조각이나 바이트로 잘게 쪼개져, 같은 뜻의 영어 문장보다 토큰이 많이 나올 수 있습니다. 정확한 비율은 모델마다 다르므로, 실제로 쓸 모델의 토크나이저로 직접 세어 보는 것이 가장 정확합니다.

연습 문제

  1. 단어 빈도 low 5, lowest 2, newer 6, wider 3 의 기본 어휘(문자 집합)는 무엇인가요?
    • 풀이: 쓰인 문자를 모으면 {d, e, i, l, n, o, r, s, t, w} 열 개입니다.
  2. 본문의 cat/cats/hat/chat 말뭉치에서 4회차 병합은 무엇인가요?
    • 풀이: 3회차 뒤 단어는 cat, cat s, hat, c hat 입니다. 쌍 빈도는 cat s 3, c hat 2 이므로 cat s → cats 가 합쳐집니다.
  3. 병합 규칙 ① a t → at ② c at → cat ③ h at → hat 으로 that 을 토큰화하세요.
    • 풀이: t h a t → ① t h at → ② 해당 없음 → ③ t hat → [t, hat] 입니다.
  4. 문맥 창이 8,000토큰인 모델에 시스템 지시 1,200토큰과 답변 여유 1,000토큰을 남기면, 참고 문서에는 몇 토큰을 쓸 수 있나요?
    • 풀이: 8000−1200−1000=58008000 - 1200 - 1000 = 5800 토큰입니다.

스스로 점검

  1. 문자 단위 토큰화는 [UNK] 가 거의 없는데 왜 LLM의 표준이 되지 못했나요?
    • 답: 토큰 하나에 담긴 뜻이 적고 길이가 크게 늘어납니다. 길이가 늘면 계산량과 비용이 함께 늘어납니다.
  2. BPE로 새 단어를 자를 때 병합 규칙의 순서가 왜 중요한가요?
    • 답: 학습 때 만든 순서대로 합쳐야 학습 때와 같은 조각이 나옵니다. 순서를 바꾸면 다른 조각이 나와 모델이 본 적 없는 id 열이 됩니다.
  3. 바이트 수준 BPE가 [UNK] 를 만들지 않는 이유는?
    • 답: 모든 글은 바이트(0~255)의 열로 표현되고, 256개 바이트가 전부 기본 어휘에 있기 때문입니다.

용어 정리

용어쉬운 뜻
토큰(token)모델이 읽는 글 조각 한 개
토크나이저(tokenizer)글을 토큰으로 자르고 번호로 바꾸는 도구
어휘(vocabulary)토크나이저가 아는 토큰과 번호의 표
토큰 id어휘 표에서 토큰의 번호
서브워드(subword)단어보다 작고 문자보다 큰 조각
BPE(Byte-Pair Encoding)가장 자주 붙어 나오는 쌍을 계속 합쳐 어휘를 만드는 방법
병합 규칙(merge)"이 두 조각을 합친다"는 학습된 규칙, 순서가 있음
[UNK]어휘에 없는 조각을 뜻하는 특수 토큰
디코딩(decoding)토큰 id를 다시 글로 바꾸는 일
문맥 창(context window)모델이 한 번에 볼 수 있는 최대 토큰 수

더 깊이 보려면

다음에 볼 것

라이선스

본문은 KAITABASE 자체 해설입니다. 참고 자료인 Hugging Face LLM Course는 Apache 2.0 라이선스로 공개되어 있습니다. BPE 손계산 말뭉치(cat/cats/hat/chat)와 단가 예시는 이 수업을 위해 만든 해설용 예입니다.

출처

AI 원리부터 이해하기 · NLP·트랜스포머 모듈

NLP·트랜스포머 모듈 학습

이 글은 NLP·트랜스포머 모듈의 학습 자료입니다. 전체 23개 자료 중 1번째입니다.

AI 기초 과정은 현재 진도 저장을 지원하지 않습니다.

출처·원문

원문 보기

요약만

본문 자체 작성 · 참고 자료 Hugging Face LLM Course(Apache 2.0)