본문 바로가기
Azure OpenAI Engineering/LLM

[Azure OpenAI #4] Transformer와 GPT 구조 : 왜 문맥을 이해할 수 있을까?

by yunalee-dev 2026. 6. 17.

글의 핵심 질문

이전 글에서는 LLM이 텍스트를 어떻게 처리하는지 정리했다.

  • 문자는 컴퓨터가 처리할 수 있는 숫자 형태로 바뀐다.
  • 문장은 토큰 단위로 나뉜다.
  • 각 토큰은 임베딩 벡터로 변환된다.
  • GPT는 이전 토큰들을 바탕으로 다음 토큰을 하나씩 예측한다.
  • 이 과정을 반복하면서 문장을 생성한다.

이번 글에서는 한 단계 더 들어가서, GPT가 문맥을 이해하고 다음 토큰을 예측하는 핵심 구조인 Transformer를 정리해보려고 한다.

Transformer 구조도를 처음 보면 다음 용어들이 한꺼번에 등장한다.

  • Encoder
  • Decoder
  • Self-Attention
  • Masked Self-Attention
  • Multi-Head Attention
  • Feed Forward Network
  • Add & Norm
  • Linear
  • Softmax

이 글에서는 이 용어들을 따로 외우는 방식이 아니라, 실제 데이터가 Transformer 안에서 흘러가는 순서대로 정리한다.

입력 문장
→ 토큰화
→ 임베딩
→ 위치 정보 추가
→ Attention
→ Add & Norm
→ Feed Forward
→ Add & Norm
→ Linear
→ Softmax
→ 다음 토큰 선택
→ 반복

1. Transformer가 등장한 이유

1-1. 자연어 처리에서 해결해야 하는 문제

문장은 단어 또는 토큰의 순서로 이루어져 있다.

나는 어제 친구와 카페에서 커피를 마셨다.

사람은 이 문장을 읽으면서 자연스럽게 다음 정보를 이해한다.

  • 누가? → 나는
  • 언제? → 어제
  • 누구와? → 친구와
  • 어디서? → 카페에서
  • 무엇을? → 커피를
  • 무엇을 했다? → 마셨다

하지만 컴퓨터 입장에서는 이 문장이 그냥 토큰들의 나열일 뿐이다.

모델이 해야 하는 일

  • 각 토큰이 문장 안에서 어떤 역할을 하는지 파악해야 한다.
  • 토큰들 사이의 관계를 계산해야 한다.
  • 문장 전체의 의미를 벡터 형태로 표현해야 한다.
  • 이전 문맥을 바탕으로 다음 토큰을 예측해야 한다.

1-2. 기존 방식: RNN과 LSTM

Transformer 이전에는 RNN, LSTM 같은 순차 처리 모델이 많이 사용되었다.

나는 → 어제 → 친구와 → 카페에서 → 커피를 → 마셨다

역할

  • 문장을 앞에서부터 하나씩 읽는다.
  • 앞에서 읽은 정보를 은닉 상태에 저장한다.
  • 저장된 정보를 다음 단어 처리에 넘겨준다.

장점

  • 문장을 순서대로 처리한다는 점에서 직관적이다.
  • 이전 단어의 정보를 다음 단어 처리에 반영할 수 있다.

한계

  • 문장이 길어질수록 앞쪽 정보가 흐려질 수 있다.
  • 앞 단어 처리가 끝나야 다음 단어를 처리 가능 -> 병렬 처리가 어렵움
  • 문장 전체의 관계를 한 번에 보기 어렵다.

1-3. Transformer의 핵심 아이디어

Transformer의 핵심 아이디어는 다음과 같다.

문장을 순서대로 하나씩만 보지 말고,
문장 안의 모든 토큰이 서로를 바라보게 하자.

역할

  • 문장 안의 토큰들이 서로 어떤 관련이 있는지 계산한다.
  • 현재 토큰을 이해하는 데 중요한 다른 토큰에 더 집중한다.
  • 문장 전체의 관계를 한 번에 계산한다.

이유

  • 긴 문장에서도 멀리 떨어진 단어 관계를 잘 파악하기 위해서다.
  • 병렬 처리를 통해 학습 속도를 높이기 위해서다.
  • 단어의 의미가 문맥에 따라 달라지는 문제를 해결하기 위해서다.

예시

나는 사과를 먹었다.
나는 친구에게 사과를 했다.

두 문장에서 사과는 같은 형태지만 의미가 다르다.

  • 사과먹었다 → 과일
  • 사과친구에게, 했다 → apology

[참고]

Attention은 모든 단어를 똑같이 보는 것이 아니다.

  • 관련성이 높은 토큰 → 더 많이 반영
  • 관련성이 낮은 토큰 → 덜 반영

2. Transformer 전체 구조

원래 Transformer는 크게 두 부분으로 나뉜다.

Encoder = 입력을 이해하는 부분
Decoder = 출력을 생성하는 부분

2-1. Encoder

역할

  • 입력 문장 전체를 이해한다.
  • 각 토큰의 문맥적 의미를 만든다.
  • 입력 토큰들을 문맥 벡터로 변환한다.

예시

입력: I am studying AI.

Encoder는 이 문장을 보고 다음 정보를 파악한다.

  • I → 주어
  • studying → 동작
  • AI → 공부 대상

2-2. Decoder

역할

  • 출력 문장을 생성한다.
  • 이전에 생성된 토큰을 보고 다음 토큰을 예측한다.
  • Encoder의 정보를 참고해 출력 토큰을 만든다.

예시

출력: 나는 AI를 공부하고 있다.

Decoder는 한 번에 전체 문장을 만드는 것이 아니라 다음처럼 토큰을 하나씩 만든다.

나는
→ AI를
→ 공부하고
→ 있다

2-3. GPT는 Decoder-only 구조다

GPT는 원래 Transformer 구조 중에서 Decoder 부분만 사용한다.

GPT = Decoder-only Transformer

역할

  • 이전 문맥을 보고 다음 토큰을 예측한다.
  • 생성된 토큰을 다시 문맥에 붙인다.
  • 이 과정을 반복해 문장을 만든다.

이유

GPT의 목적은 입력 문장을 따로 인코딩하는 것이 아니라, 지금까지의 문맥을 바탕으로 다음 토큰을 생성하는 것이기 때문이다.

[참고] Transformer 계열 모델 비교

구조 대표 모델 목적
Encoder-only BERT 문장 이해, 분류, 의미 분석
Encoder-Decoder 원래 Transformer, T5 번역, 요약, 변환
Decoder-only GPT 다음 토큰 생성

3. 입력 문장이 모델 안으로 들어가는 과정

전체 흐름은 다음과 같다.

입력 문장
→ Tokenization
→ Embedding
→ Positional Encoding

3-1. Tokenization

사용자가 다음 문장을 입력했다고 하자.

오늘 날씨가 정말

LLM은 이 문장을 그대로 처리하지 않고 토큰 단위로 나눈다.

오늘 / 날씨가 / 정말

역할

  • 문장을 모델이 처리할 수 있는 최소 단위로 나눈다.
  • 단어, 단어 일부, 문장부호 등을 토큰으로 분리한다.

이유

  • LLM은 글자나 문장 전체가 아니라 토큰 단위로 텍스트를 처리하기 때문이다.
  • 다음 토큰 예측도 토큰 단위로 이루어진다.

예시

오늘 날씨가 정말 좋다.

가능한 토큰화 예시는 다음과 같다.

오늘 / 날씨 / 가 / 정말 / 좋 / 다 / .

실제 토큰화 결과는 모델의 tokenizer에 따라 달라질 수 있다.

[참고] 한국어 토큰화

한국어는 영어보다 토큰화가 더 복잡할 수 있다.

  • 조사와 어미가 붙는다.
  • 하나의 어절이 여러 토큰으로 나뉠 수 있다.
  • 경우에 따라 영어보다 토큰 수가 많아질 수 있다.
  • 토큰 수가 많아지면 비용과 처리 시간이 증가할 수 있다.

3-2. Embedding

토큰은 그대로 계산할 수 없다. 모델은 숫자만 계산할 수 있기 때문에 각 토큰을 벡터로 바꾼다.

오늘   → [0.12, -0.03, 0.77, ...]
날씨가 → [0.45, 0.21, -0.18, ...]
정말   → [-0.33, 0.81, 0.09, ...]

역할

  • 토큰을 숫자 벡터로 변환한다.
  • 토큰의 의미를 수치적으로 표현한다.
  • 비슷한 의미의 토큰이 비슷한 벡터를 갖도록 만든다.

이유

  • 신경망은 텍스트 자체를 계산할 수 없다.
  • 텍스트를 숫자 벡터로 바꿔야 행렬 연산이 가능하다.
  • 의미가 담긴 벡터가 있어야 문맥 관계를 계산할 수 있다.

핵심 정리

Embedding = 토큰의 의미를 벡터로 표현하는 것

[참고] Embedding과 RAG

Embedding은 RAG나 벡터 검색에서도 중요하다.

  • 문서를 벡터로 바꾼다.
  • 질문도 벡터로 바꾼다.
  • 의미가 비슷한 문서를 검색한다.
  • 검색된 문서를 LLM 답변에 활용한다.

3-3. Positional Encoding

Transformer는 RNN처럼 토큰을 순서대로 하나씩 읽지 않는다. 여러 토큰을 한꺼번에 처리한다.

하지만 이렇게 하면 토큰의 순서 정보가 사라질 수 있다.

강아지가 고양이를 쫓았다.
고양이가 강아지를 쫓았다.

두 문장은 등장하는 단어가 거의 같지만 의미는 완전히 다르다.

역할

  • 각 토큰이 문장 안에서 몇 번째 위치에 있는지 알려준다.
  • 토큰 임베딩에 위치 정보를 더한다.

이유

  • Transformer는 병렬 처리를 하기 때문에 순서 정보를 따로 넣어야 한다.
  • 단어의 순서가 문장 의미에 큰 영향을 주기 때문이다.

핵심 정리

토큰 임베딩 + 위치 정보 = 위치가 반영된 토큰 표현
Embedding = 이 토큰이 무슨 뜻인지
Positional Encoding = 이 토큰이 몇 번째에 있는지

[참고]

Transformer가 순서를 모른다는 뜻은 아니다.

정확히는 다음과 같다.

  • RNN처럼 순서대로 읽지 않는다.
  • 그래서 위치 정보를 별도로 더한다.
  • 위치 정보가 더해진 뒤에는 순서를 반영할 수 있다.

좋아. 이 부분이 어려운 이유는 Encoder 안에서 실제로 문장이 “어떻게 이해되는지”가 눈에 안 보이기 때문이야. 그래서 일단 Encoder를 이렇게 생각하면 돼.

Encoder = 문장 속 각 단어를 ‘문맥이 반영된 단어’로 바꿔주는 장치

예를 들어 처음에는 그것이라는 토큰이 그냥 “대명사”일 뿐이야. 그런데 Encoder를 통과하고 나면 그것은 단순한 대명사가 아니라,

그것 = 앞에서 나온 책을 가리키는 말

처럼 문맥이 반영된 표현으로 바뀌어.


4. Encoder는 입력 문장을 어떻게 이해할까?

Encoder의 흐름

입력 토큰
→ Embedding
→ Positional Encoding
→ Self-Attention
→ Add & Norm
→ Feed Forward
→ Add & Norm
→ 문맥 벡터

이걸 한 줄로 쉽게 말하면

각 토큰을 벡터로 바꾼 뒤,
주변 토큰들과의 관계를 반영해서,
문맥이 담긴 벡터로 업데이트한다.

예시 문장 :

민수는 영희에게 책을 빌려주었고, 그녀는 그것을 다음 날 돌려주었다.

사람은 이 문장을 보면 바로 이렇게 이해한다.

그녀 = 영희
그것 = 책
돌려주었다 = 영희가 책을 민수에게 다시 줬다

그런데 모델은 처음부터 이걸 아는 게 아니다 Encoder 안에서 각 토큰이 서로를 참고하면서 이 관계를 계산하는 것이다.


4-1. Self-Attention이 하는 일

역할

Self-Attention은 각 토큰이 문장 안의 다른 토큰들을 보면서 이렇게 판단하는 과정

내 의미를 이해하려면 어떤 단어를 봐야 하지?

예를 들어 그것이라는 토큰을 보면

처음에 그것은 그냥 대명사

그것 = 어떤 물건을 가리키는 말

그런데 문장 안에는 후보가 여러 개 있다.

민수
영희
책
다음 날

이 중에서 그것이 가리킬 가능성이 높은 것은 이다.

그래서 Self-Attention은 대략 이런 관계를 계산한다.

그것 ↔ 민수      관련성 낮음
그것 ↔ 영희      관련성 낮음
그것 ↔ 책        관련성 높음
그것 ↔ 다음 날   관련성 낮음

결과적으로 그것의 벡터에는 의 정보가 많이 반영된다.

처음의 그것 벡터:
그냥 대명사 느낌

Self-Attention 이후의 그것 벡터:
책을 가리키는 대명사 느낌

핵심

Self-Attention은 단어 뜻을 사전적으로만 보는 게 아니라, 문장 안에서 그 단어가 어떤 다른 단어와 연결되는지 계산하는 과정이다.


4-2. Query, Key, Value가 왜 필요한가?

Query, Key, Value는 처음 보면 진짜 헷갈리는데, 검색 상황으로 비유하면 쉽다.

Query = 내가 찾고 싶은 것
Key = 각 정보의 이름표
Value = 실제 내용

예를 들어 그것이라는 토큰이 있다고 하면

그것은 지금 이런 질문을 하고 있다.

나는 무엇을 가리키는 말이지?

이 질문이 Query야.

문장 안의 다른 토큰들은 각각 이름표를 가지고 있다.

민수 = 사람, 남성, 주어 후보
영희 = 사람, 여성, 대상 후보
책 = 물건, 빌려준 대상
다음 날 = 시간 정보

이 이름표가 Key라고 보면 된다.

모델은 그것의 Query와 다른 토큰들의 Key를 비교한다.

그것의 Query: 내가 가리키는 대상은 무엇인가?

민수의 Key: 사람
영희의 Key: 사람
책의 Key: 물건, 빌려준 대상
다음 날의 Key: 시간

여기서 그것은 보통 물건을 가리키는 대명사니까 과 잘 맞다.

그래서 관련성 점수가 이렇게 나올 수 있다.

민수: 0.05
영희: 0.10
책: 0.75
다음 날: 0.10

이 점수를 Attention score라고 생각하면 된다.


4-3. Value는 실제로 섞이는 정보다

Query와 Key는 관련성 계산용. 실제로 최종 벡터에 들어오는 정보는 Value.

Query + Key = 누구를 얼마나 참고할지 결정
Value = 실제로 가져와서 섞는 정보

예를 들어 그것에 높은 attention을 준다고 해보면.

그러면 그것의 최종 벡터는 이런 식으로 만들어진다.

그것의 새 벡터
= 민수의 Value 조금
+ 영희의 Value 조금
+ 책의 Value 많이
+ 다음 날의 Value 조금

비유하면 이런 느낌이다.

그것이라는 빈 컵에
책의 의미를 많이 붓고,
영희와 민수의 정보는 조금만 섞는 것

그래서 최종적으로 그것은 그냥 대명사가 아니라,

그것 = 책을 가리키는 대명사

처럼 바뀌는 거다.

핵심 정리

Query = 내가 찾는 것
Key = 비교할 이름표
Value = 실제로 가져올 내용
Attention score = 얼마나 가져올지의 비율

4-4. Multi-Head Attention은 왜 필요할까?

Self-Attention을 한 번만 하면 한 가지 관점으로만 문장을 보게 된다.

그런데 문장 안에는 여러 관계가 동시에 있다.

다시 예시 문장을 보면

민수는 영희에게 책을 빌려주었고, 그녀는 그것을 다음 날 돌려주었다.

이 문장에서는 여러 관계를 봐야 한다.

그녀 = 영희
그것 = 책
책을 빌려준 사람 = 민수
책을 돌려준 사람 = 영희
다음 날 = 돌려준 시점

하나의 Attention만 있으면 이 모든 관계를 한 번에 잘 잡기 어려울 수 있다.

그래서 여러 개의 Attention head를 둔다.

Head 1: 그녀가 누구인지 찾음
Head 2: 그것이 무엇인지 찾음
Head 3: 누가 누구에게 무엇을 했는지 찾음
Head 4: 시간 정보가 어디에 붙는지 찾음

물론 실제 모델 내부에서 Head 1이 항상 대명사 담당, Head 2가 항상 목적어 담당처럼 딱 나뉘는 건 아니다. 하지만 이해할 때는 이렇게 보면 좋다.

Multi-Head Attention
= 여러 명의 독자가 같은 문장을 서로 다른 관점으로 읽는 것

비유

한 문장을 국어 선생님 여러 명이 동시에 분석한다고 생각해보면

A 선생님: 주어와 동사 관계를 봄
B 선생님: 대명사가 무엇을 가리키는지 봄
C 선생님: 시간 표현을 봄
D 선생님: 목적어와 동작 관계를 봄

그 결과를 합치면 문장을 더 풍부하게 이해할 수 있다.


4-5. Add & Norm은 왜 필요할까?

Self-Attention을 거치면 각 토큰 벡터가 새롭게 바뀐다.

예를 들어 그것 정보를 많이 반영해서 이런 벡터가 됐다고 해보면.

그것 → 책의 의미가 섞인 그것

그런데 여기서 문제가 생길 수 있다.

Attention 결과만 사용하면 원래 그것이 가지고 있던 정보가 너무 많이 사라질 수 있다.

그래서 Transformer는 원래 입력을 다시 더해준다.

원래 그것 벡터 + Attention 결과

이게 Add

Add의 역할

원래 정보를 잃지 않게 한다.
새로 계산한 문맥 정보를 추가한다.

즉, Add는 이런 느낌

원래 뜻은 유지하면서
문맥 정보를 덧붙이는 것

4-6. Add = Residual Connection

원래 입력을 버리지 않고 다시 더해준다.

예를 들어 이런 계산이 있다고 해보자.

x → Attention → Attention(x)

일반적인 방식이라면 Attention 결과만 다음으로 넘길 수 있다.

Attention(x)

그런데 Transformer는 이렇게 한다.

x + Attention(x)

왜 이렇게 할까?

깊은 신경망에서는 층을 많이 통과하면서 정보가 흐려질 수 있기 때문이다.

예를 들어 문장이 여러 층의 Encoder를 통과한다고 하면

1층 → 2층 → 3층 → 4층 → 5층 → ...

매번 벡터가 크게 바뀌면 처음 정보가 사라질 수 있어서 Add를 통해 원래 정보를 계속 보존한다.

원래 정보 + 새 정보

비유

필기할 때 원본 문장을 지우고 새 해석만 쓰는 게 아니라,

원본 문장 옆에 해석을 덧붙이는 것

이라고 보면 된다.


4-7. Norm = Layer Normalization

Norm은 계산 결과를 안정화하는 과정

신경망 안에서는 벡터 값들이 계속 계산되면서 너무 커지거나 너무 작아질 수 있다.

예를 들어 어떤 벡터 값이 이렇게 튄다고 해보자.

[0.2, 0.5, 100.7, -80.3, 0.1]

값이 너무 튀면 다음 층에서 계산이 불안정해질 수 있어,

Layer Normalization은 이런 값을 적절히 정리한다.

계산 결과가 너무 튀지 않도록 균형을 맞춘다.

Add & Norm 한 줄 정리

Add = 원래 정보를 살린다.
Norm = 계산 값을 안정화한다.

4-8. Feed Forward Network는 왜 필요할까?

Self-Attention은 토큰들 사이의 관계를 섞는 과정

예를 들어 그것이라는 벡터에 정보가 섞였다.

그것 + 책 정보

그런데 여기서 끝이 아니다.

모델은 이 섞인 정보를 한 번 더 가공해야 한다.

이제 이 정보를 어떻게 해석하지?
다음 계산에 쓰기 좋은 형태로 어떻게 바꾸지?

이걸 하는 게 Feed Forward Network

Self-Attention과 Feed Forward의 차이

Self-Attention = 다른 토큰 정보를 가져와서 섞는 과정
Feed Forward = 섞인 정보를 각 토큰 내부에서 가공하는 과정

비유

Self-Attention = 필요한 재료를 가져와서 섞기
Feed Forward = 섞은 재료를 실제 요리로 가공하기

예를 들어 그것이라는 재료에 이라는 정보를 섞었다.

그것 + 책

Feed Forward는 이걸 더 쓸모 있는 표현으로 바꿈.

그것 = 앞에서 언급된 책을 가리키는 목적어

이렇게 다음 층에서 쓰기 좋은 표현으로 만듦.


4-9. Feed Forward는 각 토큰에 독립적으로 적용된다

Self-Attention에서는 토큰들이 서로 정보를 주고받음.

그것 ↔ 책
그녀 ↔ 영희
돌려주었다 ↔ 그녀 / 그것

즉, 토큰들끼리 섞여.

그런데 Feed Forward는 토큰들끼리 섞지 않음. 각 토큰 벡터를 따로따로 가공.

민수 벡터 → Feed Forward → 더 정교한 민수 벡터
영희 벡터 → Feed Forward → 더 정교한 영희 벡터
책 벡터 → Feed Forward → 더 정교한 책 벡터
그것 벡터 → Feed Forward → 더 정교한 그것 벡터

핵심 차이

Self-Attention:
토큰들 사이의 관계를 섞는다.

Feed Forward:
각 토큰 벡터를 개별적으로 다듬는다.

비유

Self-Attention은 회의

각 단어가 서로 대화하면서 정보를 주고받음

Feed Forward는 개인 정리 시간

각 단어가 회의에서 얻은 정보를 자기 노트에 정리함

4-10. Feed Forward 뒤에도 Add & Norm이 있는 이유

Feed Forward도 벡터를 크게 바꾸는 연산

그래서 Attention 뒤와 마찬가지로 원래 정보를 보존하고 계산을 안정화해야 함.

Self-Attention
→ Add & Norm
→ Feed Forward
→ Add & Norm

첫 번째 Add & Norm

Self-Attention 결과를 안정화

즉,

원래 토큰 정보 + 문맥 관계 정보

를 안정적으로 만든다.

두 번째 Add & Norm

Feed Forward 결과를 안정화

즉,

Feed Forward 이전 정보 + Feed Forward가 가공한 정보

를 안정적으로 만든다.

핵심

각 큰 연산 뒤에는 항상 이런 처리를 한다고 보면 된다.

큰 변화가 일어남
→ 원래 정보도 다시 더함
→ 값이 너무 튀지 않게 정리함

4-11. Encoder 블록이 N번 반복되는 이유

Encoder 블록은 한 번만 실행되지 않음

Self-Attention
→ Add & Norm
→ Feed Forward
→ Add & Norm

이 묶음이 여러 번 반복돼.

그림에서 라고 적힌 게 이 뜻이야.

왜 여러 번 반복할까?

한 번의 Attention만으로는 문장을 깊게 이해하기 어렵기 때문.

첫 번째 층에서는 단순한 관계를 잡을 수 있음.

책 ↔ 빌려주었다
그녀 ↔ 영희
그것 ↔ 책

두 번째 층에서는 그 관계들을 조합할 수 있음.

영희가 책을 받았다
그녀는 영희다
그것은 책이다

세 번째 층에서는 더 큰 의미를 이해할 수 음.

영희가 민수에게 빌린 책을 다음 날 돌려주었다

즉, 층이 깊어질수록 단순한 단어 관계에서 문장 전체 의미로 발전.

비유

사람이 어려운 문장을 한 번 읽는 것보다 여러 번 읽으면 더 잘 이해하는 것과 같음.

1번 읽기: 단어 뜻 파악
2번 읽기: 누가 무엇을 했는지 파악
3번 읽기: 전체 사건 흐름 파악

Encoder 블록을 여러 번 쌓는 것도 비슷.

얕은 층 = 기본 관계 파악
중간 층 = 문장 구조 파악
깊은 층 = 전체 의미 파악

단, 실제 모델 내부가 항상 이렇게 명확하게 나뉘는 것은 아니다. 하지만 이해할 때는 이렇게 잡으면 좋다.


이 부분 전체를 한 장으로 요약하면

1. Self-Attention
   → 각 토큰이 다른 토큰을 참고해서 문맥 관계를 계산한다.

2. Query, Key, Value
   → Query와 Key로 관련성을 계산하고,
      Value를 실제 정보로 가져와 섞는다.

3. Multi-Head Attention
   → 여러 관점에서 문장 관계를 동시에 본다.

4. Add & Norm
   → 원래 정보를 보존하고 계산을 안정화한다.

5. Feed Forward Network
   → 문맥이 반영된 각 토큰 벡터를 더 정교하게 가공한다.

6. Encoder block N번 반복
   → 이 과정을 여러 번 반복하면서 문장 이해를 깊게 만든다.
Self-Attention = 다른 단어와의 관계를 섞기
Feed Forward = 섞인 정보를 각 단어 내부에서 해석하기
Add & Norm = 원래 정보 보존 + 계산 안정화
N번 반복 = 문장 이해를 점점 깊게 만들기

5. Decoder는 출력 문장을 어떻게 생성할까?

Encoder가 입력 문장을 이해하는 부분이라면, Decoder는 출력 문장을 생성하는 부분이다.

원래 Transformer에서는 Encoder가 입력 문장을 먼저 이해하고, Decoder가 그 정보를 참고해서 출력 문장을 만든다.

예를 들어 번역 작업을 생각해보자.

입력 문장: I love cats.
출력 문장: 나는 고양이를 좋아한다.

이때 Encoder는 I love cats.라는 입력 문장을 이해한다.

Decoder는 그 정보를 참고하면서 출력 문장을 하나씩 만든다.

나는
→ 나는 고양이를
→ 나는 고양이를 좋아한다
→ 나는 고양이를 좋아한다.

즉, Decoder는 문장을 한 번에 통째로 만드는 것이 아니라, 이전에 생성된 토큰들을 보고 다음 토큰을 예측하는 방식으로 작동한다.

Decoder의 전체 흐름은 다음과 같다.

이전 출력 토큰
→ Output Embedding
→ Positional Encoding
→ Masked Self-Attention
→ Add & Norm
→ Encoder-Decoder Attention
→ Add & Norm
→ Feed Forward
→ Add & Norm
→ Linear
→ Softmax
→ 다음 토큰 선택

GPT는 이 중에서 Encoder-Decoder Attention을 사용하지 않는다. 왜냐하면 GPT는 Encoder 없이 Decoder만 사용하는 Decoder-only Transformer이기 때문이다.


5-1. Output Embedding

Decoder에 들어가는 입력은 “지금까지 생성된 출력 토큰”이다.

예를 들어 모델이 지금까지 다음과 같이 생성했다고 하자.

오늘 날씨가 정말

이제 모델은 다음 토큰을 예측해야 한다.

오늘 날씨가 정말 → ?

그런데 Decoder도 Encoder와 마찬가지로 텍스트 자체를 바로 계산할 수 없다. 따라서 출력 토큰을 먼저 벡터로 바꿔야 한다.

오늘   → [0.21, -0.14, 0.55, ...]
날씨가 → [0.44, 0.09, -0.31, ...]
정말   → [-0.12, 0.72, 0.08, ...]

이 과정이 Output Embedding이다.


역할

  • 이전에 생성된 출력 토큰을 벡터로 바꾼다.
  • Decoder가 이전 출력 문맥을 계산할 수 있게 한다.
  • 다음 토큰 예측에 사용할 입력 표현을 만든다.

이유

Decoder는 다음 토큰을 예측해야 한다.

하지만 다음 토큰을 예측하려면 먼저 지금까지 만들어진 문맥을 이해해야 한다.

오늘 날씨가 정말

이 문맥을 보고 모델은 다음과 같은 후보를 생각할 수 있다.

좋다
맑다
춥다
더럽다
바나나
자동차
...

이 중에서 문맥상 자연스러운 토큰을 고르려면, 이전 출력 토큰들이 벡터 형태로 모델 안에 들어가야 한다.


예시

오늘 날씨가 정말

이 문장은 Decoder 안에서 다음처럼 처리된다.

출력 토큰
→ Output Embedding
→ Positional Encoding

즉, 오늘, 날씨가, 정말이 각각 벡터로 바뀌고, 각 토큰에 위치 정보가 더해진다.


[참고] Output Embedding과 Input Embedding의 차이

Encoder에서는 입력 문장을 임베딩한다.

입력 문장 → Input Embedding

Decoder에서는 출력 문장을 임베딩한다.

이전 출력 토큰 → Output Embedding

즉, 둘 다 토큰을 벡터로 바꾸는 과정이지만, 들어가는 대상이 다르다.

Encoder Embedding = 입력 문장 토큰을 벡터화
Decoder Embedding = 이전 출력 토큰을 벡터화

5-2. Positional Encoding

Output Embedding만으로는 토큰의 순서를 알 수 없다.

예를 들어 다음 두 문장을 보자.

나는 너를 좋아한다.
너는 나를 좋아한다.

등장하는 단어는 비슷하지만 의미는 완전히 다르다. 순서가 다르기 때문이다.

Decoder도 이전 출력 토큰의 순서를 알아야 한다.

오늘 / 날씨가 / 정말

여기서 오늘이 첫 번째이고, 정말이 세 번째라는 정보를 알아야 한다.


역할

  • 출력 토큰의 위치 정보를 더한다.
  • Decoder가 토큰의 순서를 반영할 수 있게 한다.
  • 다음 토큰 예측 시 “어떤 토큰이 앞에 나왔는지”를 알 수 있게 한다.

이유

Transformer는 RNN처럼 토큰을 하나씩 순서대로 읽지 않는다. 여러 토큰을 병렬로 처리한다.

따라서 위치 정보를 따로 추가해야 한다.

Output Embedding + Positional Encoding
= 위치가 반영된 출력 토큰 표현

5-3. Shifted Right

원래 Transformer 학습에서는 정답 문장을 한 칸 오른쪽으로 밀어서 Decoder에 넣는다. 이것을 Shifted Right라고 한다.

처음 보면 헷갈리지만, 핵심은 단순하다.

Decoder가 현재 위치에서 다음 토큰을 예측하도록 만들기 위한 장치다.

예시

정답 문장이 다음과 같다고 하자.

나는 고양이를 좋아한다.

모델은 이 문장을 한 번에 외우는 것이 아니라, 다음 토큰을 하나씩 맞히는 방식으로 학습한다.

입력: <시작>
정답: 나는

입력: <시작> 나는
정답: 고양이를

입력: <시작> 나는 고양이를
정답: 좋아한다

입력: <시작> 나는 고양이를 좋아한다
정답: .

즉, Decoder에는 정답 문장을 한 칸 오른쪽으로 민 형태가 들어간다.

Decoder 입력: <시작> 나는 고양이를 좋아한다
예측해야 할 정답: 나는 고양이를 좋아한다 .

역할

  • Decoder가 이전 토큰을 보고 다음 토큰을 예측하도록 만든다.
  • 학습 중에도 미래 정답을 미리 보지 못하게 한다.
  • 문장 생성 방식을 학습하게 한다.

5-4. Masked Self-Attention

Decoder에서 가장 중요한 부분은 Masked Self-Attention이다.

Encoder의 Self-Attention은 입력 문장 전체를 볼 수 있었다.

하지만 Decoder는 다르다. Decoder는 다음 토큰을 예측해야 하므로 미래 토큰을 보면 안 된다.


역할

  • 현재 위치 이전의 토큰들만 참고한다.
  • 미래 토큰을 보지 못하게 막는다.
  • 지금까지 생성된 문맥 안에서 다음 토큰을 예측한다.

이유

Decoder는 다음 토큰을 생성하는 구조다. 미래 토큰을 미리 보면 정답을 훔쳐보는 것이 된다.

예를 들어 다음 문장을 학습한다고 하자.

나는 오늘 커피를 마셨다.

모델이 나는 오늘 다음 토큰을 예측해야 한다면 정답은 커피를이다.

나는 오늘 → 커피를

그런데 이때 모델이 뒤에 있는 커피를, 마셨다를 미리 볼 수 있다면 학습이 의미가 없어진다.

그래서 미래 위치를 가린다. 이것이 mask다.


5-5. Decoder의 Q, K, V

Decoder의 Masked Self-Attention도 Query, Key, Value를 사용한다.

Encoder에서 Q, K, V는 이런 역할이었다.

Query = 내가 찾고 싶은 정보
Key = 각 토큰이 가진 이름표
Value = 실제로 가져올 정보

Decoder에서도 원리는 같다. 다만 차이가 있다.

Decoder에서는 미래 토큰의 Key와 Value를 볼 수 없다.

역할

  • 현재 토큰이 이전 토큰 중 어떤 정보를 참고할지 계산한다.
  • Query와 Key로 관련성을 계산한다.
  • 볼 수 있는 이전 토큰들의 Value만 섞는다.
  • 미래 토큰은 mask 처리해서 보지 못하게 한다.

과정

1. 현재 위치의 Query를 만든다.
2. 이전 토큰들의 Key와 비교한다.
3. 미래 토큰 위치는 mask 처리한다.
4. 볼 수 있는 토큰들에 대해서만 Attention score를 계산한다.
5. 관련성이 높은 이전 토큰의 Value를 많이 반영한다.
6. 관련성이 낮은 이전 토큰의 Value는 적게 반영한다.

예시

문장이 다음과 같다고 하자.

나는 오늘 커피를 마셨다.

현재 위치가 커피를이라고 하면, 볼 수 있는 토큰은 다음과 같다.

나는 / 오늘 / 커피를

볼 수 없는 토큰은 다음과 같다.

마셨다

이때 커피를의 Query는 이전 토큰들의 Key와 비교된다.

커피를 ↔ 나는
커피를 ↔ 오늘
커피를 ↔ 커피를

하지만 마셨다와는 비교하지 못한다.

커피를 ↔ 마셨다  X

왜냐하면 마셨다는 미래 토큰이기 때문이다.


핵심 정리

현재까지의 문맥 안에서만
어떤 이전 토큰을 더 참고할지 계산한다.

더 짧게 말하면 다음과 같다.

Decoder의 Q, K, V
= 미래를 제외한 상태에서 Attention을 계산하는 장치

5-6. Encoder-Decoder Attention

원래 Transformer의 Decoder에는 Encoder-Decoder Attention이 있다.

이 단계는 이름 그대로 Encoder와 Decoder를 연결한다.

Encoder가 입력 문장을 이해해 둔 결과를 Decoder가 참고하는 단계다.


역할

  • Decoder가 Encoder의 입력 문장 정보를 참고한다.
  • 현재 생성하려는 출력 토큰이 입력 문장의 어느 부분과 관련 있는지 계산한다.
  • 번역, 요약처럼 입력과 출력이 연결되어야 하는 작업에서 중요하다.

예시

번역 작업을 생각해보자.

입력: I love cats.
출력: 나는 고양이를 좋아한다.

Encoder는 입력 문장 I love cats.를 이해한다.

I → 나
love → 좋아하다
cats → 고양이

Decoder가 고양이를을 생성해야 하는 순간을 보자.

나는 → 고양이를

이때 Decoder는 Encoder의 입력 중 cats를 강하게 참고해야 한다.

고양이를 ↔ cats

이 연결을 담당하는 것이 Encoder-Decoder Attention이다.


Q, K, V 관점

Encoder-Decoder Attention에서는 Q, K, V의 출처가 다르다.

Query = Decoder 쪽에서 옴
Key = Encoder 쪽에서 옴
Value = Encoder 쪽에서 옴

즉, Decoder가 이렇게 묻는 것이다.

지금 내가 만들 출력 토큰은
입력 문장의 어느 부분을 참고해야 하지?

그리고 Encoder가 만들어 둔 입력 문장 정보에서 답을 찾는다.


과정

1. Decoder가 지금 필요한 정보를 Query로 만든다.
2. Encoder가 만든 입력 문장 정보의 Key와 비교한다.
3. 관련성이 높은 Encoder 쪽 Value를 많이 가져온다.
4. 그 정보를 바탕으로 다음 출력 토큰 표현을 만든다.

예시로 다시 보기

Decoder가 고양이를을 만들고 싶다.

Decoder Query: 지금 만들 단어는 어떤 입력 단어와 관련 있지?

Encoder 쪽 Key와 비교한다.

I
love
cats

그중 cats와 관련성이 가장 높게 나온다.

cats의 Value를 많이 가져옴

결과적으로 Decoder는 고양이를이라는 출력을 만들기 쉬워진다.


[참고] GPT와의 차이

GPT에는 일반적인 의미의 Encoder-Decoder Attention이 없다.

왜냐하면 GPT는 Encoder 없이 Decoder만 사용하기 때문이다.

GPT = Decoder-only Transformer

GPT는 입력 문장을 Encoder가 따로 이해하고, Decoder가 그 결과를 참고하는 구조가 아니다.

대신 사용자의 질문, 이전 대화, 지금까지 생성한 답변을 하나의 긴 문맥으로 보고 처리한다.

예를 들어 GPT에게 다음과 같이 입력했다고 하자.

사용자: 오늘 날씨가 정말

GPT는 이 전체 문맥을 Decoder 안에 넣고 다음 토큰을 예측한다.

오늘 날씨가 정말 → 좋다

즉, GPT에서는 다음 구조가 핵심이다.

이전 문맥
→ Masked Self-Attention
→ 다음 토큰 예측

5-7. Decoder에서도 Add & Norm을 반복한다

Decoder에서도 각 큰 연산 뒤에는 Add & Norm이 붙는다.

Masked Self-Attention
→ Add & Norm
→ Encoder-Decoder Attention
→ Add & Norm
→ Feed Forward
→ Add & Norm

Encoder와 마찬가지로 Decoder에서도 Add & Norm은 매우 중요하다.


역할

  • 원래 정보를 보존한다.
  • 새로 계산한 정보를 추가한다.
  • 계산 결과를 안정화한다.
  • 깊은 Decoder 층을 안정적으로 통과하게 한다.

이유

Decoder에서도 벡터는 계속 바뀐다.

Output Embedding
→ Masked Self-Attention
→ Encoder-Decoder Attention
→ Feed Forward

각 단계를 거치면서 정보가 크게 변할 수 있다. 그래서 원래 정보를 계속 보존하고, 값이 너무 튀지 않도록 안정화해야 한다.


쉽게 말하면

Add = 원래 내용을 잃지 않게 하는 장치
Norm = 계산 결과가 너무 흔들리지 않게 하는 장치

예시

Decoder가 고양이를이라는 토큰 표현을 만들고 있다고 하자.

Masked Self-Attention을 지나면 나는이라는 이전 출력 문맥이 반영된다.

고양이를 + 나는

Encoder-Decoder Attention을 지나면 입력 문장의 cats 정보가 반영된다.

고양이를 + 나는 + cats

Feed Forward를 지나면 이 정보가 다음 토큰 예측에 적합하게 가공된다.

다음 토큰 예측에 적합한 고양이를 표현

이 과정마다 Add & Norm이 붙어서 원래 정보가 사라지지 않게 하고, 계산을 안정화한다.


[참고] GPT에서는?

GPT에는 Encoder-Decoder Attention이 없다.

그래서 일반적인 GPT 블록은 다음 구조를 중심으로 반복된다.

Masked Self-Attention
→ Add & Norm
→ Feed Forward
→ Add & Norm

즉, GPT는 입력 문장과 출력 문장을 분리해서 처리하지 않고, 전체 문맥 안에서 다음 토큰을 예측한다.


5-8. Decoder의 Feed Forward Network

Attention을 거친 뒤에는 Decoder에서도 Feed Forward Network가 나온다.

Attention 결과
→ Feed Forward
→ 다음 토큰 예측에 쓸 최종 표현

역할

  • Attention을 거친 출력 토큰 표현을 더 정교하게 가공한다.
  • 다음 토큰 예측에 쓸 최종 표현을 만든다.
  • 각 토큰 위치의 벡터를 개별적으로 변환한다.

이유

Attention은 이전 출력 문맥과 Encoder 정보를 섞어준다.

하지만 그 정보가 섞인 벡터를 그대로 Linear와 Softmax로 넘기기에는 부족하다. 다음 토큰 예측에 더 적합한 형태로 한 번 더 가공해야 한다.

이때 Feed Forward Network가 사용된다.


Encoder의 Feed Forward와 공통점

  • 각 토큰 위치에 독립적으로 적용된다.
  • 토큰 벡터를 더 표현력 있게 바꾼다.
  • Attention으로 섞인 정보를 한 번 더 가공한다.

Encoder의 Feed Forward와 차이점

구분 Encoder Feed Forward Decoder Feed Forward
목적 입력 문장 이해 다음 토큰 생성
입력 Self-Attention 결과 Masked Self-Attention + Encoder-Decoder Attention 결과
결과 문맥이 반영된 입력 표현 다음 토큰 예측용 출력 표현

예시

번역 문장을 다시 보자.

입력: I love cats.
출력: 나는 고양이를 좋아한다.

Decoder가 고양이를까지 만든 상태라고 하자.

나는 고양이를

이제 다음 토큰은 좋아한다가 되어야 한다.

Decoder는 다음 정보를 이미 어느 정도 가지고 있다.

이전 출력 문맥: 나는 고양이를
입력 문장 정보: I love cats

Attention을 통해 다음 관계가 반영된다.

고양이를 ↔ cats
나는 ↔ I
좋아한다 ↔ love

Feed Forward는 이 정보를 다음 토큰 예측에 더 적합한 형태로 가공한다.

다음에는 love에 해당하는 표현이 나와야 함
→ 좋아한다 가능성이 높아짐

5-9. Decoder 블록도 N번 반복된다

그림에서 Decoder 쪽에도 가 있다. 이 말은 Decoder 블록도 여러 번 반복된다는 뜻이다.

Masked Self-Attention
→ Add & Norm
→ Encoder-Decoder Attention
→ Add & Norm
→ Feed Forward
→ Add & Norm

역할

  • 출력 문맥을 점점 더 정교하게 만든다.
  • 입력 문장과 출력 문장의 관계를 여러 층에 걸쳐 반영한다.
  • 다음 토큰 예측을 더 정확하게 만든다.

이유

한 번의 Attention과 Feed Forward만으로는 복잡한 생성 작업을 충분히 처리하기 어렵기 때문이다.


예시

번역 문장을 다시 보자.

입력: I love cats.
출력: 나는 고양이를 좋아한다.

얕은 Decoder 층에서는 단순한 관계를 볼 수 있다.

I ↔ 나는
cats ↔ 고양이를
love ↔ 좋아한다

더 깊은 층에서는 문장 구조를 반영할 수 있다.

한국어에서는 목적어가 동사 앞에 온다.
나는 / 고양이를 / 좋아한다

더 깊은 층에서는 자연스러운 출력 문장을 만들 수 있다.

나는 고양이를 좋아한다.

GPT에서는?

GPT도 Decoder 블록을 여러 번 쌓는다.

다만 GPT에는 Encoder-Decoder Attention이 없기 때문에, 반복되는 핵심 블록은 다음과 같다.

Masked Self-Attention
→ Add & Norm
→ Feed Forward
→ Add & Norm

이 블록이 여러 번 반복되면서 이전 문맥을 점점 더 깊게 반영한다.


Decoder 부분을 한 장으로 요약하면

1. Output Embedding
   → 이전 출력 토큰을 벡터로 바꾼다.

2. Positional Encoding
   → 출력 토큰의 순서 정보를 더한다.

3. Masked Self-Attention
   → 미래 토큰을 가리고, 이전 토큰까지만 참고한다.

4. Decoder의 Q, K, V
   → 현재 문맥 안에서 어떤 이전 토큰을 참고할지 계산한다.

5. Encoder-Decoder Attention
   → 원래 Transformer에서는 Encoder의 입력 문장 정보를 참고한다.

6. Add & Norm
   → 원래 정보를 보존하고 계산을 안정화한다.

7. Feed Forward
   → Attention 결과를 다음 토큰 예측에 적합하게 가공한다.

8. Decoder block N번 반복
   → 이 과정을 여러 층 반복해 출력 문맥을 정교하게 만든다.

진짜 핵심만 남기면 이거다.

Masked Self-Attention
= 미래를 보지 않고 이전 문맥만 본다.

Encoder-Decoder Attention
= 입력 문장과 출력 문장을 연결한다.

Feed Forward
= Attention 결과를 다음 토큰 예측용으로 가공한다.

Add & Norm
= 원래 정보 보존 + 계산 안정화

GPT
= Encoder-Decoder Attention 없이 Decoder 블록만 반복한다.

6. Linear와 Softmax는 다음 토큰 확률을 어떻게 만들까?

Decoder의 마지막 단계에서는 다음 토큰 후보들의 확률을 만든다.

최종 hidden vector
→ Linear
→ logit
→ Softmax
→ 다음 토큰 확률

입력 문장: I love cats. 현재까지 생성한 출력: 나는 고양이를 예측해야 할 다음 토큰: 좋아한다

Decoder는 Attention과 Feed Forward를 거치면서 다음과 같은 표현을 만든다.

지금 문맥상 다음에는 좋아한다에 가까운 의미가 와야 함

하지만 이 표현은 아직 실제 단어가 아니다. 모델이 다음 토큰을 선택하려면 전체 vocabulary에 있는 후보 토큰들을 비교해야 한다.

좋아한다 키운다 본다 먹었다 자동차 바나나 ...

이때 Linear와 Softmax가 사용된다.


6-1. Linear Layer

Linear Layer는 Decoder가 만든 최종 벡터를 후보 토큰별 점수로 바꾼다.

역할

  • Transformer가 만든 최종 벡터를 vocabulary 크기의 점수 벡터로 바꾼다.
  • 가능한 모든 다음 토큰 후보에 점수를 매긴다.

이유

최종 hidden vector 자체는 단어가 아니다. 이 벡터를 모델의 전체 토큰 사전 크기에 맞는 점수로 바꿔야 한다.

예시

문맥이 다음과 같다고 하자.

오늘 날씨가 정말

가능한 다음 토큰 후보는 많다.

좋다
춥다
맑다
덥다
이상하다
아름답다
...

Linear Layer는 각 후보에 점수를 매긴다.

좋다: 8.2
맑다: 7.5
춥다: 5.1
자동차: -2.3
바나나: -3.1
...

이 점수를 logit이라고 한다.


6-2. Logit

logit = 후보 토큰별 가능성 점수 = Softmax 전 단계의 점

역할

  • Softmax 이전의 원시 점수다.
  • 각 후보 토큰이 다음에 올 가능성을 점수로 표현한다.

특징

  • 아직 확률이 아니다.
  • 음수일 수도 있다.
  • 모든 점수의 합이 1이 아니다.
예시 : 좋아한다: 8.2 키운다: 6.4 본다: 4.9 자동차: -2.3

핵심 정리

Logit = Softmax를 거치기 전의 후보 토큰 점수

6-3. Softmax

역할

  • logit 점수를 확률 분포로 바꾼다.
  • 모든 후보 토큰의 확률 합이 1이 되도록 만든다.

예시

Linear 결과가 다음과 같다고 하자.

좋다: 8.2
맑다: 7.5
춥다: 5.1
자동차: -2.3

Softmax를 거치면 다음처럼 바뀐다.

좋다: 0.58
맑다: 0.29
춥다: 0.12
자동차: 0.01

핵심 정리

Linear = 점수 만들기
Softmax = 점수를 확률로 바꾸기

6-4. 다음 토큰 선택

역할

  • Softmax로 만들어진 확률 분포에서 다음 토큰을 선택한다.

가장 단순한 방식

확률이 가장 높은 토큰을 고른다.

좋다: 0.58 ← 선택
맑다: 0.29
춥다: 0.12
자동차: 0.01

그러면 문장은 다음처럼 이어진다.

오늘 날씨가 정말 좋다

이후 같은 과정을 다시 반복한다.

오늘 날씨가 정말 좋다
→ 다음 토큰 후보 계산
→ "." 선택
→ 오늘 날씨가 정말 좋다.

6-5. Temperature와 Softmax의 연결

Temperature는 다음 글에서 자세히 다룰 예정이지만, 여기서는 Softmax와의 연결만 짧게 정리한다.

역할

  • Softmax로 만들어지는 확률 분포의 모양을 조절한다.
  • 다음 토큰 선택의 다양성과 무작위성에 영향을 준다.

Temperature가 낮을 때

확률이 높은 토큰에 더 강하게 몰린다.

좋다: 0.85
맑다: 0.10
춥다: 0.04
기타: 0.01
결과
  • 더 안정적인 답변
  • 더 일관적인 답변
  • 반복 가능성이 높은 답변

Temperature가 높을 때

확률 분포가 더 완만해진다.

좋다: 0.35
맑다: 0.27
춥다: 0.20
기타: 0.18
결과
  • 더 다양한 답변
  • 더 창의적인 답변
  • 무작위성이 큰 답변

핵심 정리

Temperature 낮음 = 안정적, 결정적
Temperature 높음 = 다양함, 창의적

7. GPT는 이 과정을 어떻게 반복할까?

GPT의 생성은 한 번으로 끝나지 않는다.

오늘 날씨가 정말
→ 좋다

토큰 하나를 생성하면, 그 토큰을 다시 문맥 뒤에 붙인다.

오늘 날씨가 정말 좋다

그리고 다시 다음 토큰을 예측한다.

오늘 날씨가 정말 좋다
→ .

7-1. GPT 생성 과정

1. 사용자가 문장을 입력한다.
2. 문장이 토큰으로 나뉜다.
3. 각 토큰이 임베딩 벡터로 바뀐다.
4. 각 토큰에 위치 정보가 더해진다.
5. Masked Self-Attention이 이전 토큰들과의 관계를 계산한다.
6. Add & Norm으로 원래 정보와 새 정보를 안정적으로 합친다.
7. Feed Forward Network가 벡터 표현을 더 정교하게 변환한다.
8. 다시 Add & Norm을 거쳐 계산을 안정화한다.
9. Linear Layer가 다음 토큰 후보들의 logit 점수를 만든다.
10. Softmax가 logit을 확률로 바꾼다.
11. 확률에 따라 다음 토큰이 선택된다.
12. 선택된 토큰이 문맥 뒤에 붙는다.
13. 다시 다음 토큰을 예측한다.
14. 종료 토큰이 나오거나 최대 길이에 도달하면 생성이 끝난다.

7-2. GPT 흐름 한 줄 정리

토큰화
→ 임베딩
→ 위치 정보 추가
→ Masked Self-Attention
→ Add & Norm
→ Feed Forward
→ Add & Norm
→ Linear
→ Softmax
→ 다음 토큰 선택
→ 반복

8. Encoder, Decoder, GPT 비교

구분 Encoder Decoder GPT
주된 역할 입력 이해 출력 생성 다음 토큰 생성
볼 수 있는 정보 입력 전체 이전 출력 토큰 + Encoder 정보 이전 문맥 토큰
Attention 방식 Self-Attention Masked Self-Attention + Encoder-Decoder Attention Masked Self-Attention
미래 토큰 참조 가능 불가능 불가능
Add & Norm Attention/Feed Forward 뒤에 사용 각 Attention/Feed Forward 뒤에 사용 Masked Self-Attention/Feed Forward 뒤에 사용
Feed Forward 각 토큰 표현 가공 생성 중인 토큰 표현 가공 다음 토큰 예측용 표현 가공
최종 출력 문맥 벡터 출력 토큰 확률 다음 토큰 확률
대표 활용 문장 분류, 의미 분석 번역, 요약, 변환 챗봇, 글쓰기, 코드 생성
대표 모델 BERT Transformer Decoder GPT 계열

9. 핵심 개념 한 번에 정리

단계 개념 역할
1 Tokenization 문장을 토큰 단위로 나눈다
2 Embedding 토큰을 벡터로 바꾼다
3 Positional Encoding 토큰 순서 정보를 더한다
4 Self-Attention 문장 안의 토큰 관계를 계산한다
5 Query, Key, Value 관련성을 계산하고 실제 정보를 섞는다
6 Multi-Head Attention 여러 관점에서 Attention을 수행한다
7 Masked Self-Attention 미래 토큰을 보지 못하게 막고 이전 문맥만 본다
8 Add & Norm 원래 정보를 보존하고 계산을 안정화한다
9 Feed Forward Network 각 토큰 벡터를 더 표현력 있게 바꾼다
10 Linear 최종 벡터를 vocabulary 크기의 logit으로 바꾼다
11 Softmax logit을 확률 분포로 바꾼다
12 Token Selection 확률을 바탕으로 다음 토큰을 선택한다
13 Temperature 다음 토큰 선택의 다양성에 영향을 준다

10. 마무리

이번 글에서는 Transformer와 GPT 구조를 절차 중심으로 정리했다.

Transformer의 핵심

  • Transformer의 핵심은 Attention이다.
  • Attention은 문장 안의 각 토큰이 다른 토큰들과 어떤 관계를 갖는지 계산한다.
  • 원래 Transformer는 Encoder와 Decoder로 이루어져 있다.
Encoder = 입력 이해
Decoder = 출력 생성

GPT의 핵심

  • GPT는 Decoder-only 구조를 사용한다.
  • GPT는 지금까지의 문맥을 보고 다음 토큰을 예측한다.
  • 생성한 토큰을 다시 문맥에 붙인다.
  • 이 과정을 반복하면서 문장을 만든다.

최종 흐름

이전 토큰들을 본다
→ 문맥 관계를 계산한다
→ 다음 토큰 후보들의 확률을 만든다
→ 하나의 토큰을 선택한다
→ 다시 반복한다

조금 더 구조적으로 표현하면 다음과 같다.

Tokenization
→ Embedding
→ Positional Encoding
→ Masked Self-Attention
→ Add & Norm
→ Feed Forward
→ Add & Norm
→ Linear
→ Softmax
→ Next Token

즉, GPT는 거대한 문장 생성기가 아니라 다음 과정을 매우 정교하게 반복하는 모델이다.

이전 문맥 → 다음 토큰 예측

다음 글에서는 이 마지막 단계에서 등장하는 Temperature, Top-P, Max Tokens 같은 매개변수들이 실제 응답 결과를 어떻게 바꾸는지 정리해보겠다.