
LLM(Large Language Model)은 대량의 텍스트 데이터를 학습하여, 입력된 문맥을 바탕으로 다음에 올 토큰을 예측하는 방식으로 동작한다.
이 과정은 크게 Tokenizer → Token Embedding → Positional/Context Encoding → Transformer 연산 → Softmax → Sampling/Decoding 단계로 이해할 수 있다.
Tokenizer는 자연어 처리 시스템에서 입력 텍스트를 처리하는 첫 번째 단계이다.
사람이 읽는 문장은 그대로는 신경망이 처리할 수 없기 때문에, 먼저 텍스트를 토큰(Token) 이라는 단위로 분할한 뒤, 이를 숫자 ID로 바꾸어 모델에 전달한다.
토큰은 텍스트를 구성하는 최소 단위이다.
토큰의 기준은 모델마다 다를 수 있으며, 다음과 같은 형태가 될 수 있다.
하나의 단어
단어의 일부(서브워드)
문자 하나
공백, 구두점 같은 기호
예를 들어
"나는 밥을 먹었다"라는 문장이 있을 때, 토크나이저는 이를
["나는", "밥을", "먹었다"]처럼 나눌 수도 있고,
서브워드 기반이라면 더 잘게 나눌 수도 있다.
신경망은 문자열 자체를 이해하지 못하고 숫자만 처리할 수 있다.
따라서 입력 텍스트를 일정한 규칙에 따라 토큰으로 나누고, 각 토큰에 고유한 정수 ID를 부여해야 한다.
예:
"나는" → 1523
"밥을" → 8172
"먹었다" → 2941
즉, 문장은 최종적으로 [1523, 8172, 2941] 같은 숫자열로 변환된다.
LLM에서 많이 쓰이는 토크나이저 중 하나가 BPE(Byte Pair Encoding) 이다.
BPE는 텍스트를 서브워드(subword) 단위로 분리하는 방식이다.
BPE는 처음에는 문자를 기본 단위로 시작한 뒤, 텍스트에서 자주 함께 등장하는 문자 쌍을 반복적으로 병합하여 새로운 단위를 만든다.
예를 들어:
"l"과 "o"가 자주 같이 나타나면 "lo"로 병합
"lo"와 "w"가 자주 같이 나타나면 "low"로 병합
이 과정을 반복하면, 자주 쓰이는 단어는 통째로 토큰이 되고, 드문 단어는 여러 서브워드로 쪼개어 표현할 수 있다.
사전에 없는 단어라도 서브워드 단위로 분해하면 처리할 수 있다.
예:
"unbelievable"을 통째로 모른다고 해도
"un" + "believ" + "able"처럼 분해해 처리 가능
모든 단어를 사전에 넣지 않아도 되므로 vocabulary 크기를 적절히 유지할 수 있다.
새로운 단어나 드문 단어가 등장해도, 이미 학습한 서브워드 조합으로 대응할 수 있다.
쉽게 말하면, Tokenizer는 문장을 모델이 읽을 수 있는 작은 조각으로 나누는 도구이고, BPE는 그 조각을 단어보다 조금 더 유연한 서브워드 단위로 나누는 방법이다.

토큰화가 끝나면, 각 토큰은 단순한 정수 ID 상태이다.
하지만 숫자 ID 자체는 의미를 담고 있지 않다. 예를 들어 1523과 8172는 그냥 번호일 뿐이다.
그래서 LLM은 각 토큰 ID를 고정 길이의 실수 벡터로 바꾸는데, 이것이 Token Embedding이다.
임베딩은 각 토큰을 의미 있는 수치 표현으로 바꾸는 과정이다.
즉, 토큰 하나를 다음과 같은 벡터로 변환한다.
"나는" → [0.12, -0.08, 0.31, ...]
"밥을" → [0.45, 0.02, -0.19, ...]
"먹었다" → [0.28, 0.61, -0.07, ...]
이 벡터들은 모델이 학습 과정에서 자동으로 조정한 값들이다.
텍스트는 문자이기 때문에 그대로는 수학 연산이 어렵다.
반면 벡터는 덧셈, 곱셈, 거리 계산 등을 수행할 수 있으므로, 모델이 단어 간 관계를 계산할 수 있다.
비슷한 의미의 단어는 벡터 공간에서도 가까운 위치에 놓이도록 학습된다.
예:
"왕"과 "여왕"
"고양이"와 "강아지"
벡터 형태로 변환되면 GPU/TPU를 통해 대규모 병렬 연산이 가능하다.
Transformer는 이 임베딩 벡터를 바탕으로 이후 문맥 처리를 진행한다.
초기 임베딩 자체는 보통 문맥을 완전히 반영하지 않는다.
즉, 같은 토큰은 문장에 상관없이 처음에는 같은 임베딩으로 시작하는 경우가 많다.
문맥은 이후 Transformer 층을 거치면서 반영된다.
토큰 임베딩만으로는 문장의 순서를 알 수 없다.
예를 들어 "고양이가 사람을 물었다"와 "사람이 고양이를 물었다"는 단어는 비슷하지만 의미는 전혀 다르다.
따라서 모델은 위치 정보와 문맥 정보를 함께 반영해야 한다.
여기서 Encoding은 넓게 보면, 토큰 임베딩에 위치 정보를 더하고, Transformer 블록을 지나며 각 토큰이 문맥을 반영한 표현으로 바뀌는 과정을 의미한다.
Transformer는 RNN과 달리 순서를 자동으로 기억하지 못하므로, 각 토큰이 문장 내 몇 번째 위치에 있는지 알려줘야 한다.
이를 위해 Positional Encoding 또는 Position Embedding을 사용한다.
즉,
토큰 의미 정보: Token Embedding
토큰 위치 정보: Position Embedding
이 둘을 결합하여 모델 입력으로 사용한다.
입력된 벡터들은 Transformer 내부에서 self-attention 연산을 거치며,
각 토큰이 다른 토큰들과의 관계를 참고해 문맥이 반영된 표현으로 업데이트된다.
예를 들어 "bank"라는 단어는
"river bank"에서는 강둑
"go to the bank"에서는 은행
을 의미한다.
초기 토큰 임베딩은 같을 수 있지만, 문맥을 본 뒤에는 서로 다른 표현으로 바뀐다.
Token Embedding: 단어 자체를 숫자 벡터로 바꾸는 단계
Encoding: 그 벡터에 위치와 주변 단어 관계를 반영해, 문장 안에서의 의미를 만드는 단계
이 둘은 자주 함께 언급되지만 역할이 다르다.
각 토큰을 벡터로 바꾸는 단계이다.
즉, "먹었다"라는 토큰 자체의 기본 표현을 만드는 과정이다.
그 벡터가 문장 전체 속에서 어떤 의미를 가지는지 반영하는 단계이다.
즉, "먹었다"가 누구와 무엇과 어떤 관계로 쓰였는지를 포함해 더 풍부한 표현으로 바꾸는 과정이다.
Token Embedding은 단어의 기본 의미
Encoding은 문장 속 문맥과 위치를 반영한 의미
라고 이해하면 된다.

LLM의 핵심은 Transformer 구조이다.
입력 토큰 벡터들은 여러 개의 Transformer 블록을 통과하면서 점점 더 정교한 표현으로 바뀐다.
Transformer 블록에서는 주로 다음이 일어난다.
각 토큰이 다른 토큰들을 얼마나 참고해야 하는지를 계산한다.
예를 들어, 문장 내에서 주어와 동사, 지시어와 대상어 같은 관계를 파악하는 데 중요하다.
Attention을 통해 섞인 정보를 각 토큰별로 더 복잡하게 변환한다.
학습 안정성과 정보 보존을 위해 사용된다.
결과적으로 각 토큰은 단순한 단어 벡터가 아니라, 문맥 전체를 반영한 고차원 표현이 된다.
이제 모델은 현재까지의 문맥을 바탕으로, 다음에 어떤 토큰이 올지를 예측해야 한다.
이때 마지막 층에서는 각 어휘(vocabulary)에 대해 하나의 점수를 출력하는데, 이 점수를 logit(로짓) 이라고 한다.
예를 들어 모델이 다음 토큰 후보에 대해 이런 값을 냈다고 하자.
"나는" : 1.2
"밥을" : 2.8
"학교에" : 0.5
이 값들은 아직 확률이 아니다. 단지 모델이 각 토큰을 얼마나 선호하는지를 나타내는 점수일 뿐이다.
이 점수들을 확률로 바꾸는 함수가 바로 Softmax 함수이다.
소프트맥스 함수는 여러 개의 점수를 받아, 각 값이 0과 1 사이에 있도록 변환하고 전체 합이 1이 되도록 정규화한다.
수식은 다음과 같다.
여기서
: 전체 클래스 또는 전체 어휘 수
: j번째 토큰의 logit
: j번째 토큰이 선택될 확률
즉, 각 점수에 지수함수를 씌운 뒤 전체 합으로 나누어 확률 분포를 만든다.
출력값을 0~1 사이의 값으로 바꾸고 합을 1로 만들어,
각 토큰이 나올 가능성을 확률처럼 해석할 수 있게 한다.
지수함수를 사용하므로 높은 점수는 더 두드러지고, 낮은 점수는 더 작아진다.
그래서 모델이 어떤 후보를 더 강하게 선호하는지가 분명해진다.
신경망은 역전파를 통해 학습하므로, Softmax는 수학적으로 다루기 쉽다.
앞에서 아이리스 데이터 예시로 설명했던 것처럼, 소프트맥스 함수는 다중 클래스 분류에서 출력층에 사용되는 대표적인 함수이다.
출력층에서 쓰이는 함수는 문제 종류에 따라 다르다.
항등 함수: 회귀 문제
시그모이드 함수: 이진 분류
소프트맥스 함수: 다중 클래스 분류
LLM에서는 엄밀히 말하면 “꽃 종류 3개 중 하나”를 맞히는 문제와 완전히 같지는 않지만, 원리는 비슷하다. LLM은 다음 토큰 후보들 전체를 클래스처럼 보고, 그중 하나를 선택한다.
아이리스 분류에서는 3개 클래스 중 하나를 고름
LLM에서는 수만 개 이상의 vocabulary 중 하나를 고름
둘 다 마지막에 소프트맥스로 확률 분포를 만든다는 점은 같다.
아이리스 데이터처럼 클래스가 3개라고 가정하자.
setosa
versicolor
virginica
모델이 출력한 점수 벡터가
이라면, Softmax를 통과한 결과는 예를 들어 아래처럼 될 수 있다.
이 의미는 아래와 같다.
첫 번째 클래스일 확률 66%
두 번째 클래스일 확률 24%
세 번째 클래스일 확률 10%
따라서 가장 높은 확률을 가진 첫 번째 클래스로 분류한다.
문장이 "나는 밥을"까지 주어졌다고 하자.
모델은 다음 토큰 후보들에 대해 점수를 낼 수 있다.
"먹었다" : 4.2
"좋아한다" : 2.1
"학교에" : 0.3
Softmax를 적용하면 예를 들어:
"먹었다" : 0.80
"좋아한다" : 0.17
"학교에" : 0.03
이 될 수 있다.
즉, 모델은 다음 토큰으로 "먹었다"를 가장 유력하게 본다.
모델은 단순히 확률만 출력하는 것이 아니라, 정답 토큰과 비교하여 오차를 계산하고 이를 줄이도록 학습한다.
이때 주로 사용하는 손실 함수가 Cross-Entropy이다.
모델의 예측 확률이 다음과 같다고 하자.
그리고 실제 정답이 두 번째 클래스라면 정답 벡터는 다음과 같다.
이 경우 모델은 정답인 두 번째 클래스에 0.70의 확률을 주었으므로 어느 정도 맞췄지만, 완벽하지는 않다.
Cross-Entropy는 정답 클래스의 확률이 높을수록 작아지고, 정답 클래스의 확률이 낮을수록 커진다.
따라서 모델은 정답 토큰에 더 높은 확률을 주는 방향으로 학습된다.
LLM도 같은 원리로, 실제 다음 토큰과 모델이 예측한 확률 분포를 비교하여 손실을 계산한다.
Softmax를 통해 확률 분포가 만들어졌다고 해서, 항상 가장 확률이 높은 토큰만 고르는 것은 아니다.
텍스트 생성에서는 샘플링(sampling) 전략이 중요하다.
가장 확률이 높은 토큰을 무조건 선택한다.
장점
단점
확률 분포에 따라 무작위로 선택한다.
장점
단점
확률이 높은 상위 k개 후보만 남기고 그 안에서 샘플링한다.
누적 확률이 p가 될 때까지의 후보 집합만 남기고 샘플링한다.
logit을 조절해 확률 분포의 날카로움을 바꾼다.
temperature가 낮으면 보수적
높으면 다양성 증가
모델은 최종적으로 토큰 ID의 시퀀스를 출력한다. 이 숫자열을 다시 사람이 읽을 수 있는 문장으로 바꾸는 과정이 Decoding이다.
예:
[1523, 8172, 2941]"나는 밥을 먹었다"Tokenizer는 텍스트를 토큰으로 나누고 숫자로 바꾸고
Decoder는 그 숫자를 다시 자연어 문자열로 복원한다
LLM의 동작 과정을 순서대로 정리하면 다음과 같다.
텍스트를 토큰 단위로 분할하고 각 토큰을 ID로 변환한다.
각 토큰 ID를 고차원 벡터로 변환한다.
각 토큰의 순서 정보를 반영한다.
Self-attention과 feed-forward layer를 거치며 문맥을 반영한 표현을 만든다.
다음 토큰 후보 전체에 대해 점수를 계산한다.
점수를 확률 분포로 바꾼다.
확률 분포를 바탕으로 다음 토큰을 선택한다.
선택된 토큰들을 다시 자연어 텍스트로 변환한다.
이 과정을 반복하면서 문장을 한 토큰씩 생성한다.
LLM은 입력 텍스트를 먼저 Tokenizer를 통해 토큰 단위로 분할하고, 각 토큰을 숫자 ID로 변환한다.
이후 Token Embedding을 통해 각 토큰을 벡터로 표현하며, 여기에 위치 정보를 추가한 뒤 Transformer 구조에서 문맥을 반영한 표현으로 변환한다.
마지막 출력층에서는 각 어휘에 대한 점수인 logit을 계산하고, 이를 Softmax 함수로 확률 분포로 변환한다.
그 다음 샘플링 기법을 통해 다음 토큰을 선택하고, 이를 반복하여 문장을 생성한다. 학습 과정에서는 실제 정답 토큰과 예측 확률 분포 사이의 차이를 Cross-Entropy 손실함수로 계산하고, 이 손실을 줄이는 방향으로 모델의 파라미터를 업데이트한다.