2부 · 언어를 숫자로
← 1부 큰 그림 · 목차 · 다음: 3부 어텐션과 트랜스포머 →
1부에서 LLM이 "다음 한 조각을 고르는 일"을 반복한다고 했습니다. 그런데 컴퓨터는 글자를 직접 다루지 못합니다. 모든 것은 숫자여야 합니다. 그래서 모든 LLM의 맨 첫 단계는 텍스트를 숫자로 바꾸는 일입니다.
이 부의 한 줄 요약은 이것입니다.
모델은 글자를 보지 않는다. 글자를 잘게 쪼갠 '토큰'을, 그것도 '의미를 가진 좌표(숫자 묶음)'로만 본다.
flowchart LR
A["원본 텍스트<br/>'안녕하세요'"] --> B["토큰화<br/>['안녕', '하세요']"]
B --> C["토큰 ID<br/>[8174, 2293]"]
C --> D["임베딩<br/>각 ID를 수백 개<br/>숫자 묶음으로"]
D --> E["모델 내부로"]
classDef input fill:#fff3b0,stroke:#e0a800,color:#000
classDef proc fill:#a8e6e2,stroke:#2ba89e,color:#000
classDef inside fill:#d8b4f8,stroke:#8b5cf6,color:#000
class A input
class B,C proc
class D,E inside
2.1 토큰화 — 왜 '단어'가 아니라 '토큰'인가
가장 단순한 발상은 "단어마다 번호를 매기자"입니다. 하지만 이 방식은 의외로 잘 깨집니다. 언어에는 드문 단어, 새 이름, 오타, 전문 용어, 활용형 변화가 끝없이 등장합니다. 단어 단위 사전을 쓰면, 사전에 없는 단어가 나올 때마다 "모르는 단어"로 처리해 정보를 통째로 버리게 됩니다.
그래서 현대 LLM은 거의 다 부분 단어(subword) 토큰화를 씁니다. 단어보다 작고 글자보다 큰 조각으로 쪼개는 방식입니다. 가장 널리 쓰이는 방법이 BPE(Byte Pair Encoding, 바이트 쌍 부호화) 입니다.
BPE의 아이디어는 단순합니다. 처음엔 글자 단위로 시작해, 방대한 텍스트에서 가장 자주 붙어 다니는 짝을 반복해서 하나로 합칩니다. 이 과정을 정해진 어휘 크기(보통 5만~10만 개)에 도달할 때까지 반복합니다. 그 결과 자주 쓰는 단어는 통째로 한 토큰이 되고, 드문 단어는 여러 조각으로 쪼개집니다.
예를 들어 영어 "unbelievable"은 흔히 "un", "believ", "able" 같은 조각으로 나뉩니다. 모델이 처음 보는 단어라도 익숙한 조각들의 조합으로 표현할 수 있게 되는 것입니다.
비유 — 레고 블록 상자
토큰은 레고 블록입니다. 자주 쓰는 모양(흔한 단어)은 큰 조립 블록 하나로, 드문 모양은 작은 기본 블록 여러 개로 만듭니다. 어떤 새 모양이 와도 기본 블록 조합으로 거의 다 만들 수 있습니다.
이 비유가 깨지는 곳: 레고 블록은 사람이 의미를 보고 고르지만, BPE의 조각 경계는 의미가 아니라 빈도 통계로 정해집니다. 그래서 사람 눈엔 어색한 곳에서 단어가 잘리기도 합니다.
토큰화가 만들어내는 현상들
토큰이 단어와 일치하지 않는다는 사실은 실전에서 여러 눈에 띄는 결과를 낳습니다.
| 현상 | 왜 그런가 |
|---|---|
| "1 단어 = 1 토큰"이 아니다 | 영어 기준 대략 4글자당 1토큰, 즉 단어 하나가 1~3토큰이 될 수 있습니다. 공백·문장부호도 각자 토큰을 차지합니다. |
| 컨텍스트 길이가 "단어 수"가 아니다 | "12만 8천 토큰"은 정확히 12만 8천 단어가 아니라, 그보다 약간 적은 분량입니다. |
| 글자 세기·철자 뒤집기에 약하다 | 모델은 "strawberry" 안의 'r' 개수를 직접 세지 못합니다. 그 단어가 통째로 몇 개의 토큰 덩어리로만 들어오기 때문입니다(6부에서 자세히). |
| 언어마다 효율이 다르다 | 영어 위주로 만든 토크나이저는 한국어·일본어를 더 잘게 쪼개, 같은 내용도 토큰을 더 많이 먹습니다. |
흔한 오해 깨기
흔히들 "AI는 글자를 한 자 한 자 읽는다"고 생각하지만, 실제로는 글자가 아니라 토큰 덩어리 단위로 봅니다. 그래서 "딸기에 ㄹ이 몇 개?" 같은 글자 단위 질문에 의외로 약합니다.
🔬 더 깊이 — 바이트 단위 BPE
GPT 계열은 BPE를 바이트 단위로 구현합니다. 모든 텍스트를 256가지 바이트 값에서 출발시키므로, 이론상 어떤 문자(이모지·한자·특수기호 포함)도 "모르는 토큰" 없이 표현할 수 있습니다. "solid gold"는 의미가 살아 있는 두 토큰으로, 드문 합성어 "solidgold"는 코퍼스 통계에 따라 전혀 다르게 잘릴 수 있습니다 — 토큰 경계가 의미가 아닌 빈도로 정해진다는 증거입니다.
2.2 임베딩 — 의미를 좌표로
토큰을 번호(토큰 ID)로 바꾸는 것만으로는 부족합니다. 번호 8174와 2293은 그냥 서로 다른 번호일 뿐, "비슷한 의미인지" 같은 정보를 담지 못합니다.
그래서 다음 단계가 임베딩(embedding) 입니다. 각 토큰 ID를 수백 개의 숫자로 이루어진 묶음(벡터) 으로 바꿉니다. 이 숫자 묶음은 그 토큰의 "좌표"라고 생각하면 됩니다. 예컨대 GPT-2에서는 각 토큰이 768개의 숫자로 표현됐습니다. 요즘 큰 모델은 수천 개를 씁니다.
핵심은 이 좌표들이 학습으로 정해진다는 점입니다. 처음엔 무작위 숫자였다가, 다음 토큰 예측 훈련을 거치며 조금씩 조정됩니다. 그 결과 신기한 일이 일어납니다 — 비슷한 의미의 토큰들이 좌표 공간에서 서로 가까이 모이게 됩니다.
flowchart TB
subgraph SPACE["임베딩 공간 (개념도 — 실제는 수백 차원)"]
direction TB
K["왕"]
Q["여왕"]
M["남자"]
W["여자"]
D["강아지"]
C["고양이"]
AP["사과"]
end
K -.가까움.- Q
M -.가까움.- W
D -.가까움.- C
classDef people fill:#fff3b0,stroke:#e0a800,color:#000
classDef animal fill:#a8e6e2,stroke:#2ba89e,color:#000
classDef food fill:#b9f6ca,stroke:#2e9e5b,color:#000
class K,Q,M,W people
class D,C animal
class AP food
위 그림에서 "왕"과 "여왕"은 가깝고, "강아지"와 "고양이"가 가깝고, "사과"는 동물·사람들과 떨어져 있습니다. 모델은 누가 시키지 않아도, 단지 "다음 토큰을 잘 맞히려다 보니" 이런 배치를 스스로 만들어냅니다. 비슷한 맥락에서 등장하는 단어들은 비슷한 좌표를 갖게 되기 때문입니다.
비유 — 거대한 도서관의 책 배치
잘 정리된 도서관에서는 요리책끼리, 역사책끼리 가까운 책장에 모입니다. 제목을 몰라도 "이 근처는 다 요리책"이라고 짐작할 수 있습니다. 임베딩 공간도 의미가 비슷한 토큰을 가까운 "책장"에 둡니다.
이 비유가 깨지는 곳: 도서관은 한 권을 한 칸에 두지만, 임베딩의 "가까움"은 수백 개의 축을 동시에 따지는 거리라 한 줄로 그릴 수 없습니다. 아래 2.3에서 다룹니다.
"가깝다"의 의미
임베딩에서 "가깝다"는 건 단순히 한 줄 위에서 옆에 있다는 뜻이 아닙니다. 수백 개의 축(차원) 각각에서 값이 얼마나 비슷한지를 종합한 거리입니다. 각 축이 무엇을 뜻하는지 사람이 딱 떨어지게 이름 붙이긴 어렵지만, 어떤 방향은 대략 "동물성", 어떤 방향은 "긍정/부정", 어떤 방향은 "격식 정도"처럼 의미의 결을 담는 것으로 보입니다.
유명한 사례로, 초기 단어 임베딩에서는 "왕 − 남자 + 여자 ≈ 여왕" 같은 벡터 산수가 성립했습니다. 의미 관계가 좌표 공간의 일정한 "방향"으로 나타난 것입니다.
흔한 오해 깨기
흔히들 "왕−남자+여자=여왕 같은 깔끔한 산수가 요즘 LLM 내부에서도 그대로 성립한다"고 생각하지만, 실제로는 그 깔끔한 선형 관계는 word2vec 같은 옛 정적(static) 임베딩에서 두드러졌던 성질입니다. 현대 트랜스포머의 내부 표현에서는 이런 선형성이 상당히 흐려지고 더 복잡한 구조로 바뀐다는 것이 연구자들의 관찰입니다. 즉 "의미가 좌표가 된다"는 직관은 유효하되, "단순한 덧셈뺄셈이 항상 통한다"는 건 옛 모델의 이야기로 받아들이는 게 정확합니다.
🔬 더 깊이 — 정적 vs 문맥적 임베딩
word2vec류에서는 "배(과일)"와 "배(신체)"가 같은 하나의 좌표를 가졌습니다. 단어마다 좌표가 하나로 고정됐기 때문입니다(정적 임베딩). 반면 트랜스포머에서는 같은 토큰이라도 문장 속 맥락에 따라 내부 표현이 달라집니다(문맥적 표현). 이 "맥락에 따라 의미가 조정되는" 일이 바로 3부의 어텐션이 하는 일입니다. 2부의 임베딩은 출발점 좌표일 뿐, 모델 안에서 맥락을 거치며 계속 변형됩니다.
2.3 임베딩 공간의 직관 — 그림이 거짓말하는 지점
앞의 그림들은 모두 2차원 평면에 점을 찍었습니다. 하지만 실제 임베딩 공간은 수백~수천 개의 축을 가진 공간입니다. 사람은 3차원까지밖에 머릿속에 그릴 수 없으니, 다이어그램은 어쩔 수 없는 단순화입니다.
이게 왜 중요할까요? 고차원 공간에서는 우리 직관과 다른 일이 벌어집니다. 한 점이 동시에 아주 많은 다른 점들과 "여러 방향으로" 가까울 수 있습니다. 평면 위라면 "사과"는 "배"와 가까우면 "빨강"과는 멀어야 할 것 같지만, 고차원에서는 "과일이라는 방향"으로는 배와 가깝고 "색이라는 방향"으로는 빨강과 가까운 식으로, 여러 관계를 동시에 품을 수 있습니다.
비유는 여기서 한계에 부딪힙니다. 임베딩 공간은 Mermaid로도, 어떤 평면 그림으로도 정직하게 그릴 수 없습니다. "수백 개의 미세한 다이얼을 동시에 돌려 한 단어의 의미 위치를 잡는다"고 비유할 수 있지만, 이건 어디까지나 비유이고 사실이 아닙니다. 핵심만 가져가세요 — 의미가 숫자 묶음(좌표)이 되고, 의미의 비슷함이 좌표의 가까움이 된다.
2부 요약
- 컴퓨터는 글자를 다루지 못해, LLM의 첫 단계는 텍스트를 토큰으로 쪼개고 숫자로 바꾸는 일입니다.
- 단어 대신 부분 단어 토큰(주로 BPE) 을 쓰는 이유는, 드문 단어·새 단어·여러 언어를 버리지 않고 다루기 위해서입니다.
- 토큰이 단어와 다르다는 사실이 "1단어≠1토큰", "글자 세기에 약함", "언어별 효율 차이" 같은 현상을 만듭니다.
- 임베딩은 각 토큰을 수백 차원의 좌표로 바꾸며, 비슷한 의미가 가까운 좌표에 모입니다.
- "왕−남자+여자≈여왕" 같은 깔끔한 산수는 옛 정적 임베딩의 성질이고, 현대 LLM 내부는 더 복잡합니다.
- 임베딩 공간은 본질적으로 고차원이라, 모든 평면 그림은 단순화임을 기억해야 합니다.
이제 토큰들이 숫자 좌표가 되어 모델 안으로 들어갔습니다. 다음 부에서는 이 좌표들이 서로 맥락을 주고받는 방식, 즉 안내서의 심장인 어텐션과 트랜스포머를 다룹니다.
← 1부 큰 그림 · 목차 · 다음: 3부 어텐션과 트랜스포머 →