디코더만 있는 트랜스포머의 대표적 예시: GPT 시리즈
-> 입력(프롬포트)만 보고 다음 단어를 예측하는 방식
1. 입력 토큰화
2. 위치 인코딩 추가
3. 멀티 헤드 셀프 어텐션 적용
4. 피드 포월드 네트워크 적용
5. 다음 단어 예측
1️⃣ 입력 토큰화 (Tokenization)
: 입력을 토큰으로 변환하는 과정

그런데, 실제로 트랜스포머는 문자를 숫자로 변환해서 학습해야 한다.
그래서 토큰들을 고유한 숫자로 변환(인덱싱) 한다.

이렇게 변환된 숫자들을 임베딩 벡터(Embedding Vector)로 변환한다.

2️⃣ 위치 인코딩(Positional Encoding) 추가
: 트랜스포머 모델이 순서를 고려하지 않는 특성(Self-Attention의 순서 무관성)을 보완하기 위해 추가된다.
예를 들어,
* "나는 학교에 간다"
* "간다 나는 학교에"
이 두 문장이 같은 의미로 처리될 수도 있는데, 그렇게 처리되면 안되기 때문에 추가되는 것이다.
트랜스포머에서는 단어의 위치 정보를 벡터로 표현하는데, 그 공식이 아래와 같다.

- : 단어의 위치 (예: 첫 번째 단어 → pos=0, 두 번째 단어 → pos=1, ...)
- dmodel : 트랜스포머의 임베딩 차원 크기 (예: 512차원)
- i : 차원의 인덱스
여기서 차원이란, 데이터를 표현하는 숫자의 개수를 의미한다.
예를 들어, 숫자 하나로 표현하면 1차원, 두 개면 2차원, 네 개면 4차원이다.
- 1차원 벡터 → [3]
- 2차원 벡터 → [3, 5]
- 4차원 벡터 → [3, 5, 7, 9]
- 512차원 벡터 → [3, 5, 7, ..., 512개 숫자]
트랜스포머 모델은 단어를 숫자 벡터(임베딩)로 변환해서 처리하는데,
여기서 벡터의 크기는 인베딩 차원(dmodel)이라고 부른다.
예를 들어, 만약 트랜스포머의 임베딩 차원이 4라면,
모든 단어는 4개의 숫자로 표현되는 벡터로 변환된다.
예제:
- "나는" → [0.2, 0.5, -0.3, 0.8]
- "학교에" → [0.1, -0.4, 0.6, 0.9]
- "간다" → [-0.5, 0.2, 0.7, -0.1]
하지만 트랜스포머에서 일반적으로 사용되는 임베딩 차원 크기는 512, 768, 1024 같은 큰 값이다.
위치 인코딩도 단어 임베딩과 더해질 수 있도록 같은 차원 크기를 가져야 한다.
즉, 위치 인코딩도 4차원 벡터여야 한다는 소리.
위치 인코딩 벡터는 아래처럼 사인(sin)과 코사인(cos) 값을 이용해 계산된다.
위치 인코딩 벡터의 차원(512차원)을 짝수 차원과 홀수 차원으로 나눈다.
- 짝수 차원 (0, 2, 4, ...) → 사인 함수(sin) 적용
- 홀수 차원 (1, 3, 5, ...) → 코사인 함수(cos) 적용
즉, 위치 인코딩 벡터는 아래와 같이 구성된다.

이렇게 하면 작은 숫자는 빠르게 변하고, 큰 숫자는 천천히 변해서 단어 간 거리 정보를 자연스럽게 학습할 수 있다.

라면,
위치 인코딩 벡터도 512개의 숫자로 된 벡터가 됩니다.
이 경우,

이렇게 각 차원마다 다른 값이 들어가면서,
멀리 떨어진 단어일수록 값이 천천히 변하고, 가까운 단어는 빠르게 변하는 효과를 얻을 수 있어요.
3️⃣ 멀티 헤드 셀프 어텐션(Self-Attention) 적용
(1) 마스크드 셀프 어텐션(Masked Self-Attention)
일반적인 트랜스포머의 Self-Attention은 모든 단어를 동시에 참고 가능하나,
디코더 온리 트랜스포머는 미래 단어를 보면 안되므로 마스크(Mask)를 적용해야 한다.
마스크를 씌운다는 의미는,
예를 들어, "나는 학교에 간다." 를 예측한다고 할 때,
- 첫 번째 단계에서는 "나는" 만 참고.
- 두 번째 단계에서는 "나는 학교에" 까지만 참고.
- 세 번째 단계에서는 "나는 학교에 간다" 까지만 참고.
즉, 아직 나오지 않은 단어는 가려놓고 예측해야 한다는 것이다.
(2) 멀티 헤드 어텐션(Multi-Head Attention)
하나의 어텐션만 보면 하나의 패턴만 찾을 가능성이 높다.
하지만 문장은 보통 여러 의미를 가지고 있기에, 다양한 관계를 한 번에 찾기 어렵다.
예를 들어,
"나는 학교에서 공부한다." 라는 문장이 있을 때,
- "나는" → "공부한다" 와 관계가 있음. (주어-동사 관계)
- "학교에서" → "공부한다" 와 관계가 있음. (장소-행동 관계)
하나의 어텐션만 사용하면 이 둘 중 하나의 관계만 잘 반영할 가능성이 크다.
그래서 여러 개의 어텐션(멀티 헤드 어텐션)을 사용하면 각 헤드가 서로 다른 관계를 학습할 수 있다.
멀티 헤드 어텐션은 기본적으로 여러 개의 어텐션을 병렬로 수행하는 방식이다.
단계별 과정은 아래와 같다.
(1단계) 입력을 Q, K, V로 변환
먼저, 입력 문장을 Query(Q), Key(K), Value(V) 벡터로 변환한다.
- Query (Q): 내가 어떤 정보를 찾고 싶은지 나타내는 벡터.
- Key (K): 각 단어가 어떤 의미를 가지는지 나타내는 벡터.
- Value (V): 최종적으로 참조할 실제 정보.
각각의 단어를 임베딩 벡터로 표현하면:

이제 각 단어의 벡터를 사용해서 Q, K, V를 구한다.
Q, K, V는 각각 다른 행렬을 곱해서 계산되며, 차원은 dk로 조절된다.
(2단계) 여러 개의 어텐션 헤드를 만들기
이제 하나의 어텐션만 사용하지 않고 여러 개의 어텐션을 사용한다.
만약 헤드가 4개라고 하면:
- 첫 번째 헤드 → "나는" 과 "공부한다" 관계 학습 (주어-동사)
- 두 번째 헤드 → "학교에서" 와 "공부한다" 관계 학습 (장소-행동)
- 세 번째 헤드 → 문장 전체적인 흐름 학습
- 네 번째 헤드 → 다른 의미 학습
이렇게 각 헤드가 다른 패턴을 학습할 수 있도록 독립적으로 Q, K, V를 생성한다.
(3단계) 각 헤드에서 어텐션 수행
각 헤드는 독립적으로 어텐션을 수행한다.
즉, 각각의 Q, K, V를 가지고 어텐션 스코어(중요도 점수)를 계산하는 것이다.
어텐션 점수를 계산하는 공식:


각 헤드에서 위의 과정을 수행한 후,
각 헤드별로 다른 결과를 얻게 된다.
(4단계) 여러 개의 헤드 결과를 결합 (Concatenation)
이제 여러 개의 헤드에서 나온 어텐션 결과들을 하나로 합친다.
- 각 헤드에서 나온 벡터들을 이어붙여서 큰 벡터로 만듦.
- 그리고 다시 하나의 차원으로 줄이기 위해 선형 변환(Projection) 을 수행.
이 과정을 거치면 다양한 관계를 학습한 정보가 포함된 최종 벡터가 만들어진다.
4️⃣ Feed Forward Network (FFN) 적용
: 셀프 어텐션을 거친 벡터를 비선형 변환(MLP) 하기
셀프 어텐션(Self-Attention)은 문장 전체의 단어 관계를 파악하는 역할을 한다.
하지만, 각 단어를 개별적으로 비선형 변환해서 더 풍부한 표현을 만들 필요가 있고, 이때 FFN이 사용된다.
FFN은 두 개의 선형 변환(Linear Transformation)과 활성화 함수(ReLU)로 구성된다.
FFN 공식:


간단히 말하면,

FFN의 장점은
1. 각 단어별로 독립적인 비선형 변환을 수행 가능하다는 점
-> 문맥을 반영하면서도 개별 단어의 표현력 강화 가능
2. 어텐션이 부족한 부분을 보완할 수 있다는 점
-> 어텐션만으로는 학습하기 어려운 복잡한 관계를 FFN이 학습
3. 딥러닝 모델의 일반적인 구조와 유사하여 안정적인 학습이 가능하다는 점
-> MLP(다층 퍼셉트론)와 유사한 구조로 되어 있어서 학습이 효과적
즉, 단순한 선형 변환이 아니라 더 복잡한 패턴을 학습할 수 있도록 비선형 활성화 함수(ReLU 등)를 적용한다는 것이다.
이렇게 지피티 모델에서 사용되는 디코더 온리 트랜스포머 모델의 이론에 대해서 배워보았다.
다음 블로그에서 코딩을 직접 해보겠다.
안뇽~
'학부연구생' 카테고리의 다른 글
| HeartGPT / Heart_PT_generate.py 공부하기 (0) | 2025.02.18 |
|---|---|
| Decoder-Only Transformer - Positional Encoding Coding ver. (0) | 2025.02.14 |
| Positional Encoding에서 sin과 cos의 역할 (0) | 2025.02.14 |
| 트랜스포머 모델 개념(1) (0) | 2025.01.30 |