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개가 토큰 1.3개 정도다.
  2. 한국어는 토큰을 더 많이 쓴다: 학습 데이터에 영어가 많아서 영어 덩어리가 더 많이 합쳐졌기 때문이다. 같은 내용이라도 한국어가 토큰 수가 더 많아서, API 비용이 더 들고 컨텍스트도 더 빨리 찬다.
  3. LLM이 글자 세기를 못하는 이유: “strawberry에 r이 몇 개야?“를 자주 틀렸던 것도 토큰화 때문이다. 모델에게는 ["str", "aw", "berry"] 같은 덩어리로 보여서 글자 하나하나를 직접 보지 못한다.

핵심 요약

텍스트 → 서브워드 토큰으로 자르고 → 각 토큰을 번호(ID) 로 바꾼다. 모델이 실제로 보는 건 글자가 아니라 번호의 나열이다.

확인 질문

  1. 단어 단위로 자르지 않고 서브워드로 자르는 가장 큰 이유는 뭘까?
  2. “strawberry” 문제처럼, LLM이 토큰화 때문에 어려워할 만한 작업을 하나 더 떠올려보자. (힌트: 글자 단위로 다뤄야 하는 일)