현대의 LLM(Large Language Model)을 이해하는 첫걸음으로 가장 단순한 통계적 언어 모델인 N-gram을 살펴보겠습니다. 글자 출현 횟수만 세는 **Unigram(유니그램)**부터 직전 글자를 참고하여 다음 글자를 예측하는 **Bigram(바이그램)**까지 순차적으로 학습해 봅시다.
현대 AI를 이해하는 데 있어, LLM은 빼놓을 수 없는 핵심 기술이 되었습니다. 그리고 LLM의 작동 원리를 이해하기 위한 중요한 출발점은 바로 주어진 문맥을 바탕으로 다음에 올 토큰(token)을 예측한다는 사실입니다.
토큰이란 모델이 텍스트를 처리하는 단위로, 한 글자일 수도 있고 단어 전체나 단어의 일부일 수도 있습니다.
우선 토큰과 같은 개념은 잠시 접어두고, 하나의 글자와 그 뒤에 어떤 글자가 와야 할지 생각해 봅시다.
첫 번째 주제는 N-gram입니다.
N-gram이란 텍스트 내의 **연속된 N개의 요소(글자나 단어 등)**를 한 묶음으로 묶어 조사하는 방법입니다.
N-gram은 현대 LLM의 원리를 이해하는 데 적합한 고전적인 통계적 언어 모델입니다. 이는 확률적 텍스트 생성의 핵심 아이디어이므로, 이 N-gram을 근본부터 이해하는 것이 LLM을 이해하기 위한 첫걸음이 됩니다.
본론으로 들어가 봅시다. N-gram을 사용하여 MAMMAL이라는 단어를 글자 단위로 분석하면 다음과 같습니다.
| 이름 | N | 묶는 단위 |
MAMMAL의 예 |
|---|---|---|----
| Unigram(유니그램) | 1 | 한 글자 |
M , A , M , M , A , L
|---|---|----
| Bigram(바이그램) | 2 | 연속된 두 글자 |
MA , AM , MM , MA , AL
|---|---|----
| Trigram(트라이그램) | 3 | 연속된 세 글자 |
MAM , AMM , MMA , MAL
|
N-gram을 언어 모델로 활용하는 가장 기본적인 방법은 각 조합이 몇 번 출현했는지 수를 세고, 그 빈도를 확률로 변환하는 것입니다. 이러한 접근 방식을 *카운트 기반의 언어 모델(count-based language model)*이라고 부릅니다.
즉, 여기서 말하는 통계는 복잡한 계산보다 먼저 출현 횟수를 세는 것에서 시작합니다.
**Unigram(유니그램)**은 N-gram에서 N = 1인 경우입니다. 각 글자가 얼마나 자주 출현하는지만 학습하며, 앞뒤 글자와의 관계는 고려하지 않습니다.
예를 들어, 학습한 텍스트에서 알파벳 비율이 다음과 같다고 가정해 봅시다.
| 글자 | 출현 비율 | 생성 시 선택될 확률 |
|---|
a | 50% | 50% |
b | 30% | 30% |
c | 20% | 20% |
| 총합 | 100% | 100% |
이 분포에 따라 글자를 하나 생성할 경우, a가 선택될 확률은 50%, b는 30%, c는 20%입니다.
유니그램의 핵심은 간단합니다.
많이 출현한 글자일수록, 생성 시에도 높은 확률로 선택됩니다.
여기서 조금 다른 데이터가 있다고 가정해 봅시다.
글자를 선택하는 방법은 몇 가지가 있습니다.
방법① 탐욕적 디코딩(Greedy decoding)
매번 가장 확률이 높은 글자를 선택하는 방법입니다. 이 유니그램 모델에서는 d의 확률이 항상 40%로 가장 높기 때문에, 결과는 다음과 같습니다.
방법② 확률적 샘플링(Probabilistic sampling)
확률에 따라 무작위로 글자를 선택하는 방법입니다. d가 가장 자주 선택되지만, a, b, c도 출현할 가능성이 있습니다.
위 문자열은 생성될 수 있는 결과를 보여준 예시입니다. 그중에는 우연히 add라는 실제 영어 단어가 나타나 있습니다.
여기에는 중요한 차이가 있습니다.
- 탐욕적 디코딩(Greedy Decoding)은 이 유니그램 모델에서 가장 확률이 높은 단 하나의 문자만 반복합니다.
반면, 확률적 샘플링(Probabilistic Sampling)은 다양한 문자를 조합할 기회를 제공합니다.
하지만 샘플링을 했다고 해서 모델이 단어의 의미나 철자 규칙을 이해하고 있는 것은 아닙니다. add는 문자가 우연히 그 순서로 선택되었기 때문에 나타난 것일 뿐입니다.
또한, 탐욕적 디코딩 자체가 항상 나쁜 방법이라는 의미도 아닙니다. 유니그램에서는 직전 문자와 관계없이 동일한 확률 분포를 반복 사용하기 때문에 이러한 극단적인 반복이 일어나기 쉽다는 것입니다.
이번에는 다음 세 단어를 학습 데이터로 사용하겠습니다.
먼저, MAMMAL에 **한 문자 분량의 윈도우(window)**를 놓고 오른쪽으로 한 글자씩 이동시킵니다. 이 과정을 *슬라이딩 윈도우(sliding window)*라고 부릅니다.
Step 1 [M]AMMAL
Step 2 M[A]MMAL
Step 3 MA[M]MAL
...
나머지 두 단어에도 같은 처리를 적용하면 다음과 같습니다.
| 학습하는 단어 | 추출된 유니그램 |
|---|
MAMA | M , A , M , A |
MAMMAL | M , A , M , M , A , L |
MAMMOTH | M , A , M , M , O , T , H |
세 단어에서 추출한 총 17개의 문자의 빈도를 세어보겠습니다.
| 유니그램 | 출현 횟수 | 선택될 확률 |
|---|---|
M | 8 | 8/17 ≈ 47.1% |
A | 5 | 5/17 ≈ 29.4% |
L | 1 | 1/17 ≈ 5.9% |
O | 1 | 1/17 ≈ 5.9% |
T | 1 | 1/17 ≈ 5.9% |
H | 1 | 1/17 ≈ 5.9% |
합계 | 17 | 100% |
각 문자의 확률은 다음과 같이 계산합니다.
[P(문자) = \frac{해당 문자의 출현 횟수}{전체 문자 수}]
예를 들어, M이 생성될 확률은 8/17, 즉 약 **47.1%**입니다.
이 확률 분포에 따라 문자를 반복해서 선택하면 다음과 같은 문자열이 생성될 가능성이 있습니다.
확률이 높은 M과 A가 비교적 자주 출현하지만, 전체적으로는 자연스러운 영어 단어나 문장처럼 보이지 않습니다.
더 흥미로운 점은, 학습한 단어에는 없었던 문자 조합도 나타날 가능성이 있다는 것입니다. 예를 들어, 위의 결과에 포함된 LMM이라는 연속된 세 글자는 원래의 세 학습 단어에는 등장하지 않았습니다.
유니그램은 직전 문자가 무엇이었는지를 전혀 고려하지 않기 때문에 이러한 조합이 가능합니다. 반면, MMA나 MMO는 새롭게 나타난 조합처럼 보일 수 있지만, 실제로는 각각 MAMMAL, MAMMOTH 안에 이미 존재합니다.
그렇다면, 직전에 어떤 문자가 나왔는지까지 기억한다면 결과가 달라질까요?
**바이그램(Bigram)**은 N-gram에서 $N=2$인 경우입니다. 연속되는 두 문자를 하나의 조합으로 취급합니다.
유니그램이
| 학습하는 단어 | 추출된 바이그램 |
|---|
MAMA | MA , AM , MA |
MAMMAL | MA , AM , MM , MA , AL |
MAMMOTH | MA , AM , MM , MO , OT , TH |
중복되는 조합도 빠짐없이 세면, 다음과 같은 빈도표가 완성됩니다.
| 바이그램 | 출현 횟수 |
|---|
MA | 5 |
AM | 3 |
MM | 2 |
AL | 1 |
MO | 1 |
OT | 1 |
TH | 1 |
| 합계 | 14 |
유니그램은 총 17개였는데, 바이그램은 왜 14개일까요? 길이가 k인 단어를 두 글자씩 묶으면, k - 1개의 바이그램이 만들어지기 때문입니다. 단어는 세 개가 있으므로, 17 - 3 = 14개가 됩니다.
여기서 모델이 M을 출력한 상태라고 가정해 봅시다.
학습 데이터에서 M으로 시작하는 바이그램만 찾아보면 다음과 같습니다.
| 조합 | 출현 횟수 | M 다음 글자로 선택될 확률 |
|---|---|
MA | 5 | 5/8 = 62.5% |
MM | 2 | 2/8 = 25.0% |
MO | 1 | 1/8 = 12.5% |
합계 | 8 | 100% |
이것을 그림으로 나타내면 다음과 같습니다.
┌── A 62.5% (5회)
현재 글자 M ───┼── M 25.0% (2회)
└── O 12.5% (1회)
이 모델에서는, M 다음에 A가 올 확률이 가장 높습니다.
유니그램은 이전에 무엇을 생성했는지와 관계없이, 항상 동일한 전체 확률 분포에서 다음 글자를 선택합니다.
반면, 바이그램은 직전에 생성한 글자에 따라 확률 분포를 바꿉니다.
예를 들어, 학습 데이터에서는 다음과 같습니다.
M 다음에는 A, M, O가 올 가능성이 있습니다. -
A 다음에는 M이 3번, L이 1번 출현합니다. 따라서, A → M의 확률은 75%, A → L은 25%입니다. -
O 다음에는 T만 출현합니다. 따라서, 관측된 데이터만 보면, O → T의 확률은 100%입니다.
이렇게 모델은 단순히 자주 출현하는 글자가 아니라, 직전 글자에 맞는 다음 글자를 선택할 수 있게 됩니다.
다만, 바이그램도 어디까지나 직전의 한 글자만 참조합니다. 긴 단어의 구조나 문장 전체의 의미까지 이해하는 것은 아닙니다.
또한, 이 예시에서는 단어의 시작과 끝을 표시하지 않았지만, 실제 N-gram이나 LLM의 학습 텍스트에서는 <START>, <END>와 같은 경계 기호를 추가하고 하나의 토큰으로 취급함으로써, 어디서 시작하여 언제 멈출지까지 포함하여 학습합니다.
여기까지 확인한 것은 매우 간단하지만 중요한 원리입니다.
- 빈도 계산: 학습 데이터에서 어떤 패턴이 몇 번 출현했는지 세는 것입니다. -
- 확률 계산: 출현 횟수를 바탕으로 다음에 올 글자의 확률을 구하는 것입니다. -
- 샘플링: 이 확률 분포에서 글자를 선택하여 텍스트를 생성하는 것입니다. -
- 문맥 반영: 바이그램은 직전 글자에 따라 다음 글자의 확률이 달라집니다.
그렇다면, 직전의 한 글자가 아니라, 두 글자, 세 글자, 혹은 더 긴 문맥을 참조한다면 어떻게 될까요?