Skip to main content
Summary

흩어진 부품들이 하나의 기계가 되는 순간

지금까지 우리는 GPT를 이루는 부품들을 하나씩 살펴보았습니다. 토큰화, 어휘 사전, 임베딩, 컨텍스트 윈도우, Attention, Query·Key·Value, Multi-Head Attention, 위치 임베딩, Feed Forward Network, LayerNorm, Residual Connection까지 왔습니다. 처음에는 각각이 낯선 부품처럼 보였지만, 이제 이들을 한곳에 모으면 하나의 익숙한 모양이 나타납니다.

바로 GPT 계열 모델입니다.

GPT는 Transformer의 한 종류입니다. 더 정확히 말하면 decoder-only Transformer라고 부릅니다. 여기서 decoder-only라는 말은 Transformer 구조 중 디코더 쪽 구조를 중심으로 쌓아 올린 모델이라는 뜻입니다. 이름이 조금 거창하지만, 우리가 이해해야 할 핵심은 단순합니다. GPT는 왼쪽에서 오른쪽으로 토큰을 읽으며, 지금까지 본 토큰들을 바탕으로 다음 토큰을 예측하도록 만들어진 모델입니다.

이 장에서는 지금까지 배운 조각들을 하나의 흐름으로 연결해 보겠습니다. 문장이 들어오고, 토큰이 되고, 벡터가 되고, 여러 Transformer block을 지나, 마지막에 어휘 사전 전체에 대한 확률이 나오는 과정을 한눈에 보는 것이 목표입니다.

GPT 구조 한눈에 보기

GPT의 전체 파이프라인

GPT의 전체 흐름을 아주 크게 보면 다음과 같습니다.

입력 텍스트
  ↓
토큰화
  ↓
토큰 ID 시퀀스
  ↓
토큰 임베딩 + 위치 임베딩
  ↓
Transformer Block × N
  ↓
마지막 토큰별 은닉 벡터
  ↓
Linear Layer
  ↓
어휘 사전 전체에 대한 점수
  ↓
Softmax
  ↓
다음 토큰 확률

이 그림 하나에 지금까지 배운 내용이 거의 모두 들어 있습니다.

예를 들어 사용자가 다음과 같이 입력했다고 해 봅시다.

오늘 날씨가 참

모델은 이 문장을 그대로 읽지 않습니다. 먼저 토큰화 과정을 거쳐 텍스트를 작은 조각으로 나눕니다. 토큰화 방식에 따라 결과는 달라질 수 있지만, 개념적으로는 다음과 같은 흐름입니다.

오늘 / 날씨 / 가 / 참

각 토큰은 어휘 사전에 등록된 ID로 바뀝니다.

[1532, 8421, 17, 391]

하지만 이 ID는 의미를 담은 숫자가 아닙니다. 1532라는 숫자가 8421보다 더 크다고 해서 더 중요한 단어라는 뜻은 아닙니다. ID는 어디까지나 어휘 사전에서 해당 토큰을 찾기 위한 주소입니다. 실제 모델이 다루는 것은 이 ID를 바탕으로 꺼내 온 임베딩 벡터입니다.

토큰 임베딩과 위치 임베딩이 만나는 곳

GPT의 첫 번째 큰 단계는 토큰 ID를 벡터로 바꾸는 일입니다. 이때 사용되는 표가 토큰 임베딩 테이블입니다. 어휘 사전에 50,000개의 토큰이 있고, 각 토큰을 768차원 벡터로 표현한다면, 임베딩 테이블은 대략 다음과 같은 모양을 갖습니다.

어휘 사전 크기 × 임베딩 차원
50,000 × 768

토큰 ID 1532가 들어오면, 모델은 임베딩 테이블의 1532번째 줄에서 벡터를 꺼냅니다. 토큰 ID 8421이 들어오면 8421번째 줄의 벡터를 꺼냅니다. 이렇게 하면 입력 문장은 하나의 벡터 시퀀스가 됩니다.

그런데 여기서 문제가 하나 있습니다. 토큰 임베딩만 보면 모델은 각 토큰이 몇 번째 위치에 있었는지 알기 어렵습니다. 앞 장에서 보았듯이 Attention은 토큰 사이의 관계를 잘 계산하지만, 순서 정보가 자동으로 생기는 것은 아닙니다. '고양이가 개를 쫓았다'와 '개가 고양이를 쫓았다'는 같은 단어들을 포함하지만 의미는 완전히 다릅니다. 순서가 바뀌었기 때문입니다.

그래서 GPT는 토큰 임베딩에 위치 임베딩을 더합니다.

각 위치의 입력 벡터 = 토큰 임베딩 + 위치 임베딩

이 덧셈은 단순해 보이지만 매우 중요합니다. 토큰 임베딩은 이 토큰이 무엇인지를 담고, 위치 임베딩은 이 토큰이 어디에 있는지를 담습니다. 두 정보가 합쳐져야 Transformer block이 문장 안의 의미와 순서를 함께 다룰 수 있습니다.

비유하자면 토큰 임베딩은 배우의 정체성이고, 위치 임베딩은 무대 위 자리입니다. 같은 배우라도 무대 중앙에 서 있는지, 문 옆에 서 있는지에 따라 장면의 의미가 달라집니다. GPT는 이 두 정보를 합친 뒤 본격적으로 문맥을 계산하기 시작합니다.

Transformer Block은 무엇을 반복하는가

임베딩을 통과한 입력은 여러 개의 Transformer block을 차례대로 지나갑니다. 여기서 block이라는 말은 여러 연산을 묶어 놓은 하나의 층을 뜻합니다. GPT는 이 block을 한두 개만 쓰지 않습니다. 작은 모델은 몇 개의 block을, 큰 모델은 수십 개 이상의 block을 쌓습니다.

하나의 GPT식 Transformer block을 단순화하면 다음과 같은 흐름입니다.

입력 벡터
  ↓
LayerNorm
  ↓
Causal Multi-Head Self-Attention
  ↓
Residual Connection
  ↓
LayerNorm
  ↓
Feed Forward Network
  ↓
Residual Connection
  ↓
출력 벡터

구현 방식에 따라 LayerNorm의 위치는 조금 달라질 수 있습니다. 하지만 큰 흐름은 비슷합니다. Attention으로 토큰 사이의 관계를 섞고, Feed Forward Network로 각 토큰의 표현을 더 풍부하게 바꾼 뒤, Residual Connection으로 원래 정보를 보존하고, LayerNorm으로 값의 흐름을 안정화합니다.

여기서 중요한 점은 Transformer block 하나를 지난다고 해서 입력이 완전히 다른 것으로 바뀌는 것이 아니라는 사실입니다. 각 토큰의 벡터가 조금 더 문맥을 반영한 표현으로 갱신됩니다.

처음의 '참'이라는 토큰 벡터는 그저 '참'이라는 토큰의 기본 의미에 가까울 수 있습니다. 하지만 여러 block을 지나면서 앞에 있는 '오늘', '날씨가'라는 토큰과 관계를 맺습니다. 그 결과 마지막 층의 '참' 위치 벡터는 단순히 '참'이라는 말이 아니라, '오늘 날씨가 참'이라는 문맥 속에서 다음에 어떤 말이 올지 예측하기 좋은 상태가 됩니다.

예를 들면 다음 후보들이 떠오를 수 있습니다.

  • 좋다

  • 덥다

  • 맑다

  • 이상하다

GPT는 이 후보들을 사람이 머릿속으로 떠올리는 방식 그대로 생성하지는 않습니다. 하지만 계산의 결과로 어휘 사전 전체에 점수를 매기고, 그 점수를 확률로 바꾸며, 그중 다음 토큰으로 적절한 후보를 선택합니다.

Causal Self-Attention: 미래를 보지 않는 Attention

GPT 구조에서 특히 중요한 것은 Causal Self-Attention입니다. Self-Attention은 같은 문장 안의 토큰들이 서로를 참고해 자신의 표현을 갱신하는 방식이었습니다. 그런데 GPT는 다음 토큰 예측 모델입니다. 학습할 때도, 생성할 때도 현재 위치에서 미래 토큰을 보면 안 됩니다.

예를 들어 다음 문장이 학습 데이터에 있다고 해 봅시다.

오늘 날씨가 참 좋다

모델이 '참' 다음에 올 토큰을 예측하는 순간, 정답인 '좋다'를 미리 보고 있다면 그것은 반칙입니다. 시험 문제를 풀기도 전에 답안지를 보는 셈입니다. 그러면 학습 점수는 좋아 보일 수 있지만, 실제 생성 상황에서는 아무 도움이 되지 않습니다. 실제 사용자가 '오늘 날씨가 참'까지만 입력했을 때, 미래의 '좋다'는 아직 존재하지 않기 때문입니다.

그래서 GPT는 causal mask를 사용합니다. mask는 Attention 계산에서 볼 수 없는 위치를 가리는 장치입니다. causal이라는 말은 인과적이라는 뜻인데, 여기서는 시간의 흐름을 거스르지 않는다는 의미로 이해하면 됩니다. 현재 토큰은 자기 자신과 과거 토큰만 볼 수 있고, 미래 토큰은 볼 수 없습니다.

입력: 오늘  날씨가  참  좋다

오늘   → 오늘만 볼 수 있음
날씨가 → 오늘, 날씨가를 볼 수 있음
참     → 오늘, 날씨가, 참을 볼 수 있음
좋다   → 오늘, 날씨가, 참, 좋다를 볼 수 있음

이 구조 덕분에 GPT는 문장을 왼쪽에서 오른쪽으로 자연스럽게 이어 갑니다. 첫 번째 토큰부터 마지막 토큰까지 각 위치에서 다음 토큰을 예측하는 훈련을 반복하면서, 문법과 표현, 사실 관계, 대화 패턴, 코드 작성 방식 같은 다양한 규칙성을 배웁니다.

여기서 한 가지 흥미로운 점이 있습니다. GPT는 학습할 때 하나의 문장에서 여러 문제를 동시에 풉니다. '오늘' 다음에는 무엇이 올까, '오늘 날씨가' 다음에는 무엇이 올까, '오늘 날씨가 참' 다음에는 무엇이 올까를 한 번의 계산 안에서 함께 학습할 수 있습니다. causal mask 덕분에 각 위치가 자기보다 오른쪽의 답을 훔쳐보지 않으면서도, 전체 문장을 효율적으로 처리할 수 있는 것입니다.

여러 층을 쌓는다는 것의 의미

Transformer block을 여러 층 쌓는다는 것은 단순히 같은 계산을 반복한다는 뜻만은 아닙니다. 각 층은 이전 층이 만든 표현을 바탕으로 더 복잡한 관계를 잡아낼 수 있습니다.

아주 거칠게 비유하자면 낮은 층은 가까운 단어 관계나 표면적인 패턴을 다루고, 높은 층은 더 넓은 문맥과 추상적인 의미를 다룰 가능성이 커집니다. 물론 실제 신경망 내부가 이렇게 깔끔하게 역할 분담을 한다고 단정할 수는 없습니다. 하지만 층이 깊어질수록 토큰 표현이 점진적으로 정교해진다는 감각은 GPT를 이해하는 데 도움이 됩니다.

문장 하나를 예로 들어 보겠습니다.

민수는 우산을 챙겼다. 하늘이 어두워졌기 때문이다.

처음 임베딩 단계에서 '우산'은 그저 우산이라는 토큰의 벡터에 가깝습니다. 낮은 층에서는 '챙겼다'와 연결되며 행동의 대상이라는 정보가 더해질 수 있습니다. 더 높은 층에서는 '하늘이 어두워졌다'와 연결되며 비가 올 것 같은 상황이라는 문맥이 더해질 수 있습니다. 마지막에는 이 문맥 전체가 다음 문장을 예측하는 데 쓰일 수 있습니다. 예를 들어 '곧 비가' 같은 이어지는 표현의 확률이 높아질 수 있습니다.

GPT가 그럴듯한 문장을 만드는 힘은 바로 이 누적된 표현 갱신에서 나옵니다. 하나의 Attention이 모든 것을 해결하는 것이 아닙니다. 여러 head가 여러 관점으로 보고, 여러 block이 여러 단계로 다듬으면서, 각 토큰의 벡터가 점점 더 풍부한 문맥 표현으로 바뀝니다.

마지막 Linear Layer: 벡터를 단어 후보 점수로 바꾸기

여러 Transformer block을 지난 뒤에는 각 위치마다 하나의 벡터가 남습니다. 이 벡터를 보통 hidden state, 즉 은닉 상태라고 부릅니다. 은닉 상태라는 말은 모델 내부에서 다음 계산에 쓰이는 중간 표현이라는 뜻입니다.

하지만 이 벡터만으로는 아직 다음 토큰을 고를 수 없습니다. 우리는 어휘 사전 안의 각 토큰에 대해 '다음에 올 가능성이 얼마나 큰가'를 알아야 합니다. 그래서 마지막에 linear layer가 등장합니다. 언어 모델에서는 이 마지막 선형 층을 LM head라고 부르기도 합니다.

이 층의 역할은 간단합니다.

마지막 은닉 벡터 → 어휘 사전 크기만큼의 점수

어휘 사전에 50,000개의 토큰이 있다면, 마지막 linear layer는 각 위치의 벡터를 50,000개의 숫자로 바꿉니다. 이 숫자들은 아직 확률이 아닙니다. 어떤 값은 12.3일 수도 있고, 어떤 값은 -4.8일 수도 있습니다. 이런 원시 점수를 logit이라고 부릅니다.

그다음 softmax가 이 logit들을 확률로 바꿉니다. softmax는 여러 점수를 모두 더하면 1이 되는 확률 분포로 변환하는 함수입니다.

좋다: 0.42
덥다: 0.18
맑다: 0.11
이상하다: 0.04
...

이제 모델은 다음 토큰을 선택할 수 있습니다. 가장 확률이 높은 토큰을 고를 수도 있고, 일부 무작위성을 넣어 조금 더 다양한 답을 만들 수도 있습니다. temperature, top-k, top-p 같은 생성 옵션은 바로 이 선택 단계에 관여합니다. 같은 확률 분포를 보고도 얼마나 보수적으로 고를지, 얼마나 다양하게 고를지를 조절하는 장치입니다.

중요한 것은 GPT가 한 번에 완성된 긴 답변을 꺼내는 것이 아니라는 점입니다. GPT는 다음 토큰 하나를 예측합니다. 그 토큰을 입력 뒤에 붙입니다. 그리고 다시 다음 토큰을 예측합니다. 이 과정을 반복하면 문장, 문단, 긴 답변이 만들어집니다.

오늘 날씨가 참
→ 좋다

오늘 날씨가 참 좋다
→ .

오늘 날씨가 참 좋다.
→ 산책하기

오늘 날씨가 참 좋다. 산책하기
→ 좋은

길고 자연스러운 답변도 결국 이 작은 선택들이 이어진 결과입니다. 마법처럼 보이지만, 내부에서는 토큰 하나를 고르는 계산이 매우 빠르게 반복되고 있습니다.

GPT는 왜 decoder-only라고 부를까

Transformer라는 이름 아래에는 여러 계열의 모델이 있습니다. GPT, BERT, T5는 모두 Transformer와 관련이 있지만, 구조와 목적이 다릅니다. 이 차이를 이해하면 GPT가 어떤 문제에 특히 잘 맞는지도 선명해집니다.

BERT는 encoder-only 구조로 설명되는 경우가 많습니다. 인코더는 입력 전체를 양방향으로 보며 문장의 의미를 이해하는 데 강합니다. 예를 들어 문장 분류, 감정 분석, 빈칸 채우기, 검색 문서의 의미 표현 같은 작업에 잘 어울립니다. BERT는 문장의 왼쪽과 오른쪽 문맥을 모두 참고할 수 있기 때문에, 주어진 텍스트를 이해하고 표현하는 쪽에 강한 구조입니다.

GPT는 decoder-only 구조입니다. 왼쪽에서 오른쪽으로 토큰을 생성하는 데 초점이 있습니다. 미래 토큰을 가리는 causal mask를 사용하고, 지금까지의 문맥을 바탕으로 다음 토큰을 예측합니다. 그래서 글쓰기, 대화, 코드 생성, 요약 초안 작성처럼 텍스트를 이어서 만들어 내는 작업에 자연스럽게 맞습니다.

T5는 encoder-decoder 구조로 설명할 수 있습니다. 입력을 인코더가 읽고, 디코더가 그 입력을 바탕으로 출력을 생성합니다. 번역처럼 입력 문장과 출력 문장이 구분되는 작업에 잘 어울립니다. 예를 들어 영어 문장을 한국어로 번역할 때, 인코더는 영어 문장을 읽고 디코더는 한국어 문장을 생성합니다.

세 구조를 간단히 비교하면 다음과 같습니다.

모델 계열구조주된 방향잘 어울리는 작업
BERTEncoder-only입력 전체 이해분류, 검색, 문장 표현
GPTDecoder-only다음 토큰 생성대화, 글쓰기, 코드 생성
T5Encoder-Decoder입력을 읽고 출력 생성번역, 변환, 요약

물론 현대 LLM 생태계에서는 경계가 예전보다 유연해졌습니다. GPT 계열 모델도 분류나 요약을 잘할 수 있고, encoder-decoder 모델도 다양한 생성 작업을 할 수 있습니다. 하지만 기본 구조의 차이를 이해하면 각 모델이 어떤 철학으로 출발했는지 알 수 있습니다.

이 책에서 앞으로 직접 만들 Mini GPT는 GPT 계열의 핵심 원리를 이해하기 위한 작은 decoder-only Transformer입니다. ChatGPT급 모델을 만드는 것이 아니라, ChatGPT의 핵심 원리를 손으로 만져 보기 위한 작은 실험실을 만드는 것입니다.

GPT의 forward 흐름을 코드 관점으로 보기

이제 구현 관점에서 GPT의 forward 흐름을 아주 간단한 의사 코드로 살펴보겠습니다. 여기서 forward란 입력이 모델 안을 통과해 출력으로 바뀌는 순전파 과정을 뜻합니다.

입력: token_ids

x = token_embedding(token_ids)
pos = position_embedding(positions)
x = x + pos

for block in transformer_blocks:
    x = block(x)

logits = linear(x)
probabilities = softmax(logits)

출력: 다음 토큰 확률

이 짧은 흐름 안에 GPT의 핵심이 모두 들어 있습니다. token_embedding은 토큰의 의미적 출발점을 만들고, position_embedding은 순서를 알려 줍니다. transformer_blocks는 문맥을 반영해 표현을 계속 갱신합니다. 마지막 linear는 벡터를 어휘 사전 전체에 대한 점수로 바꾸고, softmax는 그 점수를 확률로 바꿉니다.

실제 구현에서는 배치 크기, 시퀀스 길이, 임베딩 차원 같은 텐서 모양을 신경 써야 합니다. 예를 들어 한 번에 32개의 문장을 처리하고, 각 문장이 128개의 토큰으로 잘렸으며, 임베딩 차원이 384라면 중간 텐서는 대략 다음과 같은 모양을 가집니다.

batch_size × sequence_length × embedding_dim
32 × 128 × 384

마지막 logits의 모양은 어휘 사전 크기에 따라 바뀝니다. 어휘 사전 크기가 10,000이라면 다음과 같습니다.

batch_size × sequence_length × vocab_size
32 × 128 × 10,000

이 말은 각 문장의 각 위치마다 어휘 사전 전체에 대한 다음 토큰 점수가 나온다는 뜻입니다. GPT는 입력 시퀀스의 마지막 위치만 예측하는 것이 아니라, 학습 중에는 모든 위치에서 다음 토큰 예측 문제를 동시에 풉니다. 그래서 매우 많은 예측 신호를 효율적으로 얻을 수 있습니다.

학습과 생성은 같은 구조를 다르게 사용한다

GPT는 학습할 때와 생성할 때 같은 구조를 사용하지만, 사용 방식은 조금 다릅니다.

학습할 때는 정답 텍스트가 이미 있습니다. 모델은 각 위치에서 다음 토큰을 예측하고, 실제 다음 토큰과 비교합니다. 예측이 틀리면 손실이 커지고, 모델의 파라미터가 조금 수정됩니다. 이 과정을 엄청나게 많은 텍스트에 대해 반복하면, 모델은 어떤 문맥 뒤에 어떤 토큰이 자주 오고 자연스러운지 점점 더 잘 맞히게 됩니다.

생성할 때는 정답이 없습니다. 사용자의 입력이 주어지면 모델은 다음 토큰 확률을 계산하고, 그중 하나를 선택합니다. 선택된 토큰은 다시 입력 뒤에 붙습니다. 그러면 문맥이 길어지고, 모델은 다시 다음 토큰을 예측합니다. 이 반복이 우리가 보는 답변이 됩니다.

학습: 예측한 다음 토큰과 실제 다음 토큰을 비교한다.
생성: 예측한 다음 토큰을 골라 문맥 뒤에 붙인다.

그래서 GPT를 이해할 때 가장 중요한 문장은 여전히 이것입니다. GPT는 다음 토큰을 예측하는 모델입니다. 다만 그 예측을 위해 토큰 임베딩, 위치 임베딩, Causal Self-Attention, Multi-Head Attention, Feed Forward Network, LayerNorm, Residual Connection, Linear Layer, Softmax가 정교하게 연결되어 있을 뿐입니다.

한 장으로 정리하는 GPT 구조

마지막으로 전체 구조를 한 번 더 압축해 보겠습니다.

텍스트
  ↓ 토큰화
토큰 ID
  ↓ 임베딩 조회
토큰 벡터
  + 위치 벡터
  ↓
문맥이 없는 초기 표현
  ↓ Transformer Block 1
조금 문맥화된 표현
  ↓ Transformer Block 2
더 문맥화된 표현
  ↓ ...
깊게 문맥화된 표현
  ↓ Linear Layer
어휘 사전 전체 점수
  ↓ Softmax
다음 토큰 확률

이제 GPT의 큰 그림이 보입니다. GPT는 텍스트를 숫자로 바꾸고, 숫자를 벡터로 바꾸고, 벡터들이 서로를 참고하게 만들고, 그 결과를 다시 어휘 사전의 확률로 바꿉니다. 그리고 그 확률을 이용해 다음 토큰을 고릅니다.

이 구조를 이해하면 LLM은 더 이상 완전히 닫힌 상자가 아닙니다. 물론 실제 대형 모델은 훨씬 크고 복잡합니다. 수많은 파라미터, 거대한 데이터셋, 분산 학습, 최적화 기법, 안전성 조정이 더해집니다. 하지만 중심 원리는 지금 본 그림에서 크게 벗어나지 않습니다.

다음 부터는 이 그림을 코드로 옮겨 볼 차례입니다. 거대한 모델을 만들지는 않습니다. 대신 작은 텍스트 데이터셋으로 문자 단위 언어 모델부터 시작해, Bigram 모델, 작은 신경망 언어 모델, Self-Attention, Transformer block을 차근차근 구현해 볼 것입니다. 그리고 마침내 우리 손으로 Mini GPT를 학습시켜 볼 것입니다.

그때 오늘 본 전체 구조가 길잡이가 됩니다. 코드를 쓰다가 길을 잃으면 이 그림으로 돌아오면 됩니다. 입력 텍스트는 토큰이 되고, 토큰은 벡터가 되고, 벡터는 Transformer block을 지나고, 마지막에는 다음 토큰 확률이 됩니다. GPT라는 긴 여행은 언제나 이 단순한 길에서 출발합니다.

책 목록

처음 만나는 LLM: 원리부터 Mini GPT 구현, RAG 서비스 개발까지

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기