LLM 1: 토큰화 (Tokenization)
왜 필요할까?
LLM은 결국 거대한 수학 함수라서 숫자만 다룰 수 있다. 그래서 텍스트를 숫자로 바꾸는 단계가 먼저 필요하다.
"나는 학생이다" → [토큰들] → [번호들] → 모델에 들어감
텍스트를 어떤 단위로 자를까?
방법 A: 글자 단위
"학생" → ["학", "생"]
- 장점: 종류가 적다(사전이 작다).
- 단점: 문장이 너무 길어지고, 글자 하나에는 의미가 거의 없다.
방법 B: 단어 단위
"학생이다" → ["학생이다"]
- 장점: 의미 단위로 잘린다.
- 단점: 단어 종류가 무한하다. “학생이”, “학생을”, “학생에게”… 처음 보는 단어는 처리할 수 없다.
방법 C: 서브워드(subword) 단위 ← 실제 LLM이 쓰는 방식
"학생이다" → ["학생", "이다"]
"unbelievable" → ["un", "believ", "able"]
- 자주 나오는 덩어리는 하나의 토큰으로, 드문 단어는 작은 조각들로 나눈다.
- 처음 보는 단어도 조각을 조합해서 표현할 수 있다.
서브워드는 어떻게 만들까? → BPE (Byte Pair Encoding)
아이디어는 단순하다. “자주 붙어 다니는 쌍을 하나로 합친다”를 반복한다.
시작: l o w l o w e r l o w e s t
1회: "l o"가 제일 자주 나옴 → "lo"로 합침
lo w lo w e r lo w e s t
2회: "lo w"가 자주 나옴 → "low"로 합침
low low e r low e s t
... 원하는 사전 크기(예: 10만 개)가 될 때까지 반복
이렇게 만들어진 토큰 사전(vocabulary) 에서 각 토큰에 번호가 붙는다.
"low" → 1523, "er" → 287, "est" → 4410 ...
알아두면 좋은 사실들
- 토큰 ≠ 단어: 영어는 대략 단어 1개가 토큰 1.3개 정도다.
- 한국어는 토큰을 더 많이 쓴다: 학습 데이터에 영어가 많아서 영어 덩어리가 더 많이 합쳐졌기 때문이다. 같은 내용이라도 한국어가 토큰 수가 더 많아서, API 비용이 더 들고 컨텍스트도 더 빨리 찬다.
- LLM이 글자 세기를 못하는 이유: “strawberry에 r이 몇 개야?“를 자주 틀렸던 것도 토큰화 때문이다. 모델에게는
["str", "aw", "berry"]같은 덩어리로 보여서 글자 하나하나를 직접 보지 못한다.
핵심 요약
텍스트 → 서브워드 토큰으로 자르고 → 각 토큰을 번호(ID) 로 바꾼다. 모델이 실제로 보는 건 글자가 아니라 번호의 나열이다.
확인 질문
- 단어 단위로 자르지 않고 서브워드로 자르는 가장 큰 이유는 뭘까?
- “strawberry” 문제처럼, LLM이 토큰화 때문에 어려워할 만한 작업을 하나 더 떠올려보자. (힌트: 글자 단위로 다뤄야 하는 일)